I need to use getUserMedia
while the video is set to record in 16:9 resolution.
My code works on most desktops and on Android 7 and above:
navigator.getUserMedia( {
audio: true,
video: {
mandatory: {
minWidth: 380,
minHeight: 214,
maxWidth: 380,
maxHeight: 214
}
}
})
But on Android 6 and below, and on some desktops too (can't figure out exactly which), getUserMedia
breaks, and no image is available from the camera.
This works on all devices and desktop, but with a default resolution ratio of 4:3, while I need 16:9:
navigator.getUserMedia( {
audio: true,
video: true
})
I tried omitting the mandatory
, no luck.
To add to my confusion, iOS devices (11 beta) and Android require passing the facingMode
argument:
video: { facingMode: 'user' }
So, it seems that passing the width
and height
arguments breaks getUserMedia
on some desktops and devices like Android 5 and 6.
Is there a way to force a 16:9 ratio on all devices? What is the correct and conventional method of capturing a video with specific dimensions?
You're assuming all cameras support 16:9, or that all browsers will crop the video for you. Not so. You're also using an outdated API. Try the latest API (fiddle, samples):
var constraints = {video: {width: 320, height: 180, facingMode: "user"}};
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => video.srcObject = stream)
.then(() => new Promise(resolve => video.onloadedmetadata = resolve))
.then(() => log(video.videoWidth +"x"+ video.videoHeight))
.catch(e => console.log(e));
getUserMedia
at its heart is a camera/mic discovery API: All the min
, max
, exact
, ideal
keywords exist to describe your constraints, i.e. your tolerance for not getting what you want.
I would suggest the aspectRatio
constraint, except nobody implements that yet, and it's just another constraint to decrease your tolerance.
At the moment I believe only Chrome will downscale and crop camera output to the exact size you want. Turns out this is what most people want, but discovers little about the user's camera. Other browsers may follow, since there hasn't been much demand for much else, but they don't currently downscale.
Note though that even Chrome won't upscale, so if you're using Chrome on Android, there's a chance you asked for a higher resolution than your Android 6 device can output. Check for OverconstrainedError
in this case, and try again with lower values.
In short, you're not always going to get the exact size you want, as it ultimately depends on the user's camera and their browser.
But HTMLVideoElement downscales on playback anyway, and you can use CSS to crop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With