getUserMedia() video size in Firefox & Chrome differs
Edit April 15
As noted by @jib in his awesome answer,
Firefox [38+] does support a subset of constraints with getUserMedia(), but not the outdated syntax that Chrome and Opera are using. The mandatory / optional syntax was deprecated a year ago, and minWidth and minHeight the year before that.
So the new syntax, approved by specs is :
var constraints = { audio: false, video: { width: { min: 1024, ideal: 1280, max: 1920 }, height: { min: 576, ideal: 720, max: 1080 }, }};
However this syntax throws an error in Chrome. As noted in comments, a PR to adapter.js
has been made, including a polyfill for older FF and chrome.
Here is my attempt, for chrome only (but newer version of FF seem to accept the magical and hidden require:['width', 'height']
.
First Answer
So I started to write you this before you answered your own question.
As noted in the comments, I'm drawing each frame of the video to fit a resized canvas.
var video, canvas, streaming = false, constrainedWidth = 320, constrainedHeight = 180;function streamCam() { navigator.getMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia); //**Deprecated Now, see the update** var video_constraints = { "mandatory": { "minWidth": constrainedWidth, "minHeight": constrainedHeight, "minFrameRate": "30" }, "optional": [] } navigator.getMedia({ video: video_constraints, audio: false }, function(stream) { if (navigator.mozGetUserMedia) { video.mozSrcObject = stream; } else { var vendorURL = window.URL || window.webkitURL; video.src = vendorURL.createObjectURL(stream); } video.play(); }, function(err) { console.log("An error occured! " + err); streamCam(); } );}function FFResize() { canvas.width = constrainedWidth; canvas.height = constrainedHeight; canvas.getContext('2d').drawImage(video, 0, 0, constrainedWidth, constrainedHeight); setTimeout(function() { requestAnimationFrame(FFResize) }, 10);}window.onload = function() { video = document.querySelector('#video'), canvas = document.querySelector('#canvas'); streamCam(); video.addEventListener('playing', function(ev) { if (!streaming) { if (video.videoHeight === 0) { window.setTimeout(function() { video.pause(); video.play(); }, 100); } else { video.setAttribute('width', video.videoWidth); video.setAttribute('height', video.videoHeight); canvas.setAttribute('width', constrainedWidth); canvas.setAttribute('height', constrainedHeight); streaming = true; requestAnimationFrame(FFResize); } } }, false);};
#canvas { position: fixed; top: 0;}
<video id="video"></video><canvas id="canvas"></canvas>
This does its job but as you noted constraints are still in dev and the only way to have them to work with Firefox is to manually set every browser's media.navigator.video.default_
in about:config
.
Ok. Long time coming.
I found that the following code:
var vid_constraints = { mandatory: { maxHeight: 180, maxWidth: 320 }}
Is actually useless. What works better, is to simply use
navigator.getUserMedia({audio: true, video: true}, function(stream){..},function(e){...});
And you just set the size of the video through CSS or inline html. For my application this worked fine, as I just had to copy the video content to a canvas. Worked great in the end.
So in conclusion, the problem seemed to be the constraint options. Stay away form them if your trying to make it work in multiple browsers.
This may not work for you if you require better control over your camera resolution. If you need finite control over the res, perhaps try conditional (ie. if(navigator.mozGetUserMedia){... //compatible resolutions etc ...}
).
Praying there will be a standard getUserMedia
function handled by all browsers soon! :)
Just a reference. I forked some fiddleJS code and modified it to test in Chrome and Mozilla:http://jsfiddle.net/sidewaiise/Laq5txvq/