javascript Firefox 和 Chrome 中的 getUserMedia() 视频大小不同
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26415778/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
getUserMedia() video size in Firefox & Chrome differs
提问by sidewaiise
I'm using getUserMedia()
, and when implementing constraints (see below) they only work in Chrome and not Mozilla. The size in mozilla always appears stretched and ends up bigger than the one in chome.
我正在使用getUserMedia()
, 并且在实施约束(见下文)时,它们仅适用于 Chrome 而不是 Mozilla。mozilla 中的大小总是显得拉长,最终比 chome 中的大。
var vid_constraints = {
mandatory: {
maxHeight: 180,
maxWidth: 320
}
}
var constraints = { audio: false, video: vid_constraints };
navigator.getUserMedia(constraints, successCallback, errorCallback);
After reading some, it appears that MozGetUserMedia()
doesn't support resolution constraints. Is there a way to display the video that ensures it has the same size/res in both Firefox and Chrome?
看了一些,好像MozGetUserMedia()
不支持分辨率限制。有没有办法显示视频以确保它在 Firefox 和 Chrome 中具有相同的大小/分辨率?
Thanks
谢谢
EditI've modified the script to take snapshots. I've saved snapshots in Moz and in Chrome - the result is what follows:
编辑我修改了脚本以拍摄快照。我已经在 Moz 和 Chrome 中保存了快照 - 结果如下:
(left = Chrome, right = Mozilla)
(左 = Chrome,右 = Mozilla)
Thought this may clarify the problem. It looks like aspect ratio.
认为这可以澄清问题。它看起来像纵横比。
Edit (take 2)
编辑(采取 2)
Yes - the aspect ratio for the chrome one is 16:9, whereas for Moz its 4:3. How can I modify this?
是的 - chrome 的纵横比是 16:9,而 Moz 的纵横比是 4:3。我该如何修改?
回答by Kaiido
Edit April 15
4月15日编辑
As noted by @jibin 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.
Firefox [38+] 确实支持 getUserMedia() 的约束子集,但不支持 Chrome 和 Opera 使用的过时语法。强制/可选语法在一年前被弃用,而 minWidth 和 minHeight 则是在那之前的一年。
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 PRto adapter.js
has been made, including a polyfillfor older FF and chrome.
但是,此语法会在 Chrome 中引发错误。正如在评论中指出,一个PR来adapter.js
已取得包括填充工具为老年人FF和铬。
Here is my attempt, for chrome only (but newer version of FF seem to accept the magical and hidden require:['width', 'height']
.
这是我的尝试,仅适用于 chrome(但较新版本的 FF 似乎接受了神奇和隐藏的require:['width', 'height']
.
var video_constraints = {
width: { min: 320, max: 480 },
height: { min: 240, max: 360 },
require: ["width", "height"] // needed pre-Firefox 38 (non-spec)
};
function getMedia(){
if(navigator.webkitGetUserMedia){
var wkConstraints={mandatory: {} };
var c = video_constraints;
for(var i in c){
switch(i){
case 'width': for(j in c[i]){
switch(j){
case 'max': wkConstraints.mandatory.maxWidth = c[i][j]; break;
case 'min': wkConstraints.mandatory.minWidth = c[i][j]; break;
case 'exact': wkConstraints.mandatory.minWidth = wkConstraints.mandatory.maxWidth = c[i][j]; break;
}
}; break;
case 'height': for(var j in c[i]){
switch(j){
case 'max': wkConstraints.mandatory.maxHeight = c[i][j]; break;
case 'min': wkConstraints.mandatory.minHeight = c[i][j]; break;
case 'exact': wkConstraints.mandatory.minHeight = wkConstraints.mandatory.maxHeight = c[i][j]; break;
}
}; break;
default: break;
}
}
video_constraints = wkConstraints;
}
navigator.getUserMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia);
if(!navigator.getUserMedia){
alert("your browser doesn't support getUserMedia")
}
navigator.getUserMedia(
{
video: video_constraints,
audio: false,
},
function(stream) {
if (navigator.mozGetUserMedia) {
video.mozSrcObject = stream;
}
else {
var URL = window.URL || window.webkitURL;
video.src = URL.createObjectURL(stream);
}
video.play();
},
function(err) {
console.log(err);
}
);
}
var video= document.querySelector('video');
video.addEventListener('playing', loopStart, false);
function loopStart(){
this.removeEventListener('playing', loopStart);
if(this.videoHeight === 0){
window.setTimeout(function() {
this.pause();
this.play();
loopStart();
}, 100);
}
else {
this.setAttribute('width', this.videoWidth);
this.setAttribute('height', this.videoHeight);
}
}
getMedia();
<video/>
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
.
这样做的工作,但正如你指出的限制仍然在开发中,并将它们必须与火狐工作的唯一方法是手动设置每个浏览器media.navigator.video.default_
中about:config
。
回答by sidewaiise
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.
您只需通过 CSS 或内联 html 设置视频的大小。对于我的应用程序,这很好用,因为我只需要将视频内容复制到画布上。最后效果很好。
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 ...}
).
如果您需要更好地控制相机分辨率,这可能对您不起作用。如果您需要对 res 进行有限控制,请尝试使用条件(即if(navigator.mozGetUserMedia){... //compatible resolutions etc ...}
)。
Praying there will be a standard getUserMedia
function handled by all browsers soon! :)
祈祷getUserMedia
所有浏览器都能尽快处理标准功能!:)
Just a reference. I forked some fiddleJS code and modified it to test in Chrome and Mozilla:http://jsfiddle.net/sidewaiise/Laq5txvq/
仅供参考。我分叉了一些 fiddleJS 代码并对其进行了修改以在 Chrome 和 Mozilla 中进行测试:http: //jsfiddle.net/sidewaiise/Laq5txvq/