How to keep 1:1 aspect ratio video all the time in WebRTC

12,542

Solution 1

You're asking about getUserMedia here, which is effectively about camera resolutions.

What resolutions your camera captures video in depends on your hardware. My camera for instance, can capture in a number of modes, they're all 4:3 modes up to about 640x480, and above that they're all 16:9. It has no 1:1 modes (I checked).

You haven't said why you care about aspect, but I suspect you still want a ball to appear round and not oval, so if your site wants video from my camera to fit in a square, it'll need to either crop out the left and right parts of my video or suffer black bars above and below. No way around it.

If it's just about layout, leave the capture aspect alone and crop the playback element (which scales the video for you btw) with CSS instead. This gives you full control (use https fiddle in Chrome):

navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => video.srcObject = stream)
  .then(() => new Promise(resolve => video.onloadedmetadata = resolve))
  .then(() => log(video.srcObject.getVideoTracks()[0].label +
                  " ("+ video.videoWidth +"x"+ video.videoHeight +")"))
  .catch(log);

var log = msg => div.innerHTML += msg + "<br>";
.crop{
  overflow:hidden;
  display:block;
  width: 120px;
}
#video{
  margin-left: -15px;
}
<div class="crop"><video id="video" width="160" height="120" autoplay></video></div>
<br><div id="div"></div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

Also, please be aware of browser differences here, some browsers (Chrome) will mutate (crop) the camera capture for you, while others (Firefox) will always give you native modes.

Solution 2

You can set the aspect ratio by using an aspectRatio property.

video: {
 width: {max: 1024},
 height: {max: 1024},
 aspectRatio: {ideal: 1}
}

In this case, if a user's camera supports an aspect ratio of 1:1 the website will use it. In case when it is not supported it will use a different one.

Also if your camera resolution is maximally 720p but it does support the 1:1 ratio it will start a video with 720x720 resolution.

Share:
12,542

Related videos on Youtube

Hongbo Miao
Author by

Hongbo Miao

https://www.hongbomiao.com

Updated on September 15, 2022

Comments

  • Hongbo Miao
    Hongbo Miao over 1 year

    When I use this setting, the video aspect ratio is 1:1.

    constraints = {
      audio: false,
      video: { width: 240, height: 240 }
    };
    

    However, I want WebRTC choose better resolution if exists. When I changed it to this

    constraints = {
      audio: false,
      video: {
        width: { min: 240, ideal: 720, max: 1080 },
        height: { min: 240, ideal: 720, max: 1080 }
      }
    };
    

    The demo jsfiddle

    In my case, sometimes, it becomes 4:3, which is 640*480. I think it is because both the number 640 and 480 are between 240 and 1080.

    How can I keep it 1:1 all the time? Thanks

  • Hongbo Miao
    Hongbo Miao almost 8 years
    thank you so much for detailed answer! I will reply more soon!
  • Hongbo Miao
    Hongbo Miao almost 8 years
    I just got time to test, I think it is a good way to go. Thank you so much!
  • Noitidart
    Noitidart almost 8 years
    I am recording straight to file, is it possible to set the crop x, y, x2, and y2? Because otherwise I'll have to figure out how to get each frame to a canvas then crop each frame then save it back to webm.
  • jib
    jib almost 8 years
    @Noitidart If you need the cropping in the actual output file, then I don't know of a better way, sorry. In Firefox I would draw to canvas as you suggest, and use canvas.captureStream().
  • Noitidart
    Noitidart almost 8 years
    Ooo that's a cool idea! I'll try that! I'll keep you updated :)
  • Noitidart
    Noitidart almost 8 years
    Hi there jib, this captureStream looks great but I have recorded audio with it. Is there possible to overlap the recorded audio over the captureStream?
  • jib
    jib almost 8 years
    @Noitidart I think so, but please post a new question as there's not enough room here.
  • Noitidart
    Noitidart almost 8 years
    Thanks jib! I actually didn't look at the docs on it yet, I was still working on other parts. If I stumble I'll definitely post up a q and ping you.
  • Ali Bahrami
    Ali Bahrami almost 5 years
    so for fix we should go over first answer. Thanks for description.