admin管理员组

文章数量:1297127

In a small web project I am trying to get a video element that displays a video track "cropped" in portrait mode. In my HTML I have something like:

<video id="video" style="width:300px; height:600px"></video>

where the dimensions I have written are just to show I want to render the element with a "portrait" aspect ratio.

Following what specified here:

in a script, I have something like this:

const constraints = {
  audio: false,
  video: { 
    width: 300, 
    height: 600 
  },
};

navigator.mediaDevices
  .getUserMedia(constraints)
    .then((mediaStream) => {
      const video = document.querySelector("video");
      video.srcObject = mediaStream;
      video.onloadedmetadata = () => {
        video.play();
      };
   })
   .catch((err) => {
     // always check for errors at the end.
     console.error(`${err.name}: ${err.message}`);
   });

When I open the webpage on a mobile device in portrait mode, I get that:

  • the video element has the requested size;
  • the video track displayed inside the video element spans at the required width, but its height is much less than that required and, in particular is exactly equal to the required width times the aspect ratio obtained by the required constraints. So in the case of the example I have provided the height of the video track is 300 * 0.5 = 150(px).

Instead, if I open the webpage on a desktop computer or on a mobile device kept in landscape mode, I can get a video track with those exact width and height, and in turn that fits its video element.

I have tried also to set width and height ranges, and ideal values, as well exact aspect ratio value through the following constraints definition:

constraints : {
                audio: false,
                video : {            
                          width: {
                                   min: 200,
                                   max: 700,
                                   ideal: 300
                                 },
                          height: {
                                    min: 400,
                                    max: 1400,
                                    ideal: 600
                                  },                    
                          aspectRatio : {exact:0.5},
                          resizeMode: "crop-and-scale",
                        }
               }

but I get always the same result as that described above. This behaviour seems to be due to the mobile device that, when in portrait mode, doesn't "crop and resize" the video track in order to fill the video element. It looks like the mobile device doesn't expand the width of the video track over the available width of the video element but forces it to have a maximum width equal to that of the video element.

I could only get an ephemeral result by using the following constraints:

constraints = {
                audio: false,
                video: { 
                         width: 300, 
                         aspectRatio: 0.5 
                },
              };

i.e. by requesting the width of the video track equal to that of the video element, leaving the height unconstrained at all and requesting the specific aspect ratio. With this setup, the video track, at page loading (or when the first frame from the mediastream object is served), is cropped and resized as I request (the image fills the video element) but immediately after the video track is set again with its height equal to its width times the aspect ratio (300*0.5 = 150).

Is there a known way to keep the video track cropped and resized?

本文标签: