videojs / video.js

Video.js - open source HTML5 video player
https://videojs.com
Other
38.13k stars 7.46k forks source link

Automatic Resize to Fit Container Height (instead of width) #7620

Open GreggShimokura opened 2 years ago

GreggShimokura commented 2 years ago

Description

I am trying to play a phone video (portrait aspect ratio) inside a iframe. For landscape videos it wall works fine, however for portrait layout, the player extends off screen because the player fits to the width of the container.

Can video.js be configured so that the player automatically resizes to fit in the height of the container/iframe instead of the width?

Results

Expected

Player letterboxed on left/right sides so that the full height of the video can be seen without scrolling (also remove scroll bars).

Actual

Video is fit to full width, extending off the bottom of the screen.

Additional Information

I am using video.js version 7.12.3 but could use any version.

mister-ben commented 2 years ago

You can fill mode to fill a containing element, vjs-fill or fill: true.

GreggShimokura commented 2 years ago

Hi. Thanks for the reply. I have tried this but it fills width as a priority and the container extends in height off the screen.. I would like to fill the height first as a priority and keep the height fixed and remain visible on the screen. Gregg

mister-ben commented 2 years ago

Fill should do that, it sets width and height to 100%: https://codepen.io/mister-ben/pen/yLPgrYj?editors=1000 Could you be using fluid instead?

GreggShimokura commented 2 years ago

I am trying to debug as my install is not matching the behaviour you have provided (which is what I want).

I see you are using 7.17.0, should it work with the 7.12.3 that I am using?

Gregg

gkatsev commented 2 years ago

fill is available as of 7.3. https://github.com/videojs/video.js/pull/5478

GreggShimokura commented 2 years ago

Thanks for the confirmation.

I am not sure but I think my problem is related to the fact that my video.js player page is referenced inside an 'iFrame' from another page because I pass the path/source details of my video+poster to my player page.

In other words, I am trying to fit the video player inside an iframe of variable dimensions instead of a container of fixed/known dimensions.

Should the fill options work in this scenario?

As expected, updating the video.js version did not improve (or worsen) the problem.

gkatsev commented 2 years ago

A live minimal test example is probably needed to help out more.

GreggShimokura commented 2 years ago

Understood.. I will endeavour to create one.

GreggShimokura commented 2 years ago

Hi, I have created a live test case at: https://shimokura.space/public/ There are portrait and landscape example videos. The video.js player is activated inside an iframe when clicking on the images.

It seems that the player size is fixed to a certain size and does not adapt to the container size. If the browser is resized the video size does not seem to change.

To help in debug I have made the border of the iframe red. The dimension of the videos are as follows: Landscape : 1280 x 720 Portrait : 1300 x 1950

I'd like the videos to be centered as well but that is secondary at this point.

Thanks for any suggestions you can provide,

Gregg

gkatsev commented 2 years ago

Looks like neither of these players are fluid or fill. You probably want to set fluid on them but also provide a maximum width or height. For the landscape one you can call player.fluid(true) or add vjs-fluid to your player and then add the following css to the page:

body {
  margin: 0;
}
.video-js {
  max-width: 100vw;
}

The above removes the margin from the body so that we don't need to worry about it and have the player be able to go edge-to-edge in the iframe. Then we constrain the player to be at most as wide as the viewport.

For the portrait one, the above works too, but depending on the shape of the page, the player might end up being too long. For that, you can use the following css:

body {
  margin: 0;
}
.video-js {
  max-height: 100vh;
  height: auto;
  aspect-ratio: 2/3;
}
GreggShimokura commented 2 years ago

Thanks for the suggestions. I did indeed forget to enable fill or fluid. I have update my setup with fluid: true; and

body {
  margin: 0;
}

.video-js {
  max-width: 100vw;
  max-height: 100vh;
  height: auto;
}

I would like to have one videoplayer.html that handles any size video as I am trying for a general solution. So I omitted the aspect-ratio styling.

Now as you can see the player defaults to filing the width for the portrait video.

When I use fill: true the Landscape video is not displaye as it seems to be off screen somewhere.

If you can take a look that would be appreciated,

Gregg

GreggShimokura commented 2 years ago

Hi. Just checking if I need to do something to confirm? Thanks

misteroneill commented 2 years ago

Hi @GreggShimokura, nope! That label was just for our own tracking purposes, but I think it was an inaccurate one. We are pretty limited on capacity at the moment, so I'm not sure when someone will have the bandwidth to dig further into this question.

gkatsev commented 2 years ago

Yeah, unfortunately, I don't have more time to look into this beyond https://github.com/videojs/video.js/issues/7620#issuecomment-1034113424. Loading the player inside an iframe makes things a lot harder since you don't have direct access to the player, and sizing iframes is a bit of a pain. Definitely easier if you didn't have an iframe, but should still be do-able. Making the player with fill: true and then sizing the iframe as you expect it to be is probably the best, and then you won't need to have specific handling on the player side.

aproni34f commented 1 year ago

I am trying to use fill mode. This is what I get : https://jsfiddle.net/cbL30h85/1/ (you might need to resize preview area)

Is this expected behavior?

What I would like is not having black left and right of video, because controls also span 100% but ideally they would be the same as video video. Cant video metadata be detected and they resizing work on that?

I want to fill available area but not make video bigger than its natural size, and I dont want vertical scroll if video is bigger than it fits (so I dont use fluid option).

asheroto commented 7 months ago

I was never able to get vjs-fluid to do what I want. The video continuously was too tall for the window and the user would have to scroll to see the controls. Gave up on using it.

Instead, I used CSS to accomplish the task. This will size the video to the viewport height and width. Works on portrait, landscape, computer, seemingly everywhere. 😊

Here's how I fixed it:

CSS

body {
    margin: 0;
}

.video-container {
    width: 100%;
    height: 100vh;
    position: relative;
}

.video-js {
    width: 100% !important;
    height: 100% !important;
}

HTML

<div class="video-container">
    <video id="my-video" class="video-js" controls preload="auto" data-setup='{}' controlsList="nodownload">
        <source src="video.webm" type="video/webm" />
        <source src="video.mp4" type="video/mp4" />
    </video>
</div>