Federico Tomasi
Federico Tomasi

Reputation: 121

navigator.mediaDevices.getUserMedia() portrait mode in mobile device - video track is not cropped and resized

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:

https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

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:

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?

Upvotes: 0

Views: 31

Answers (0)

Related Questions