Firefox 和 Chrome 中的 getUserMedia() 视频大小不同
Posted
技术标签:
【中文标题】Firefox 和 Chrome 中的 getUserMedia() 视频大小不同【英文标题】:getUserMedia() video size in Firefox & Chrome differs 【发布时间】:2014-12-12 11:47:56 【问题描述】:我正在使用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);
读了一些之后,MozGetUserMedia()
似乎不支持分辨率限制。有没有办法显示视频以确保它在 Firefox 和 Chrome 中具有相同的大小/分辨率?
谢谢
编辑 我已修改脚本以拍摄快照。我在 Moz 和 Chrome 中保存了快照 - 结果如下:
(左 = Chrome,右 = Mozilla)
认为这可以澄清问题。它看起来像宽高比。
编辑(拍摄 2 次)
是的 - chrome one 的纵横比是 16:9,而 Moz 的纵横比是 4:3。我该如何修改?
【问题讨论】:
Firefox 的哪个版本? @aldanux Firefox 33.0 on Mac OS X 10.9.5 你试过设置视频元素的高宽吗 是的。它只是改变了视频元素的总面积。它自己的视频只是简单地缩放以适应内部。 (不改变比例) 看看那个问题中的this answer:***.com/questions/17502205/webrtc-resolution-limit 似乎是firefox缺乏功能 【参考方案1】:4 月 15 日编辑
正如@jib 在他的awesome answer 中所指出的,
Firefox [38+] 确实支持约束的子集 getUserMedia(),但不是 Chrome 和 Opera 的过时语法 使用。强制/可选语法在一年前被弃用,并且 前一年的 minWidth 和 minHeight。
所以规范批准的新语法是:
var constraints =
audio: false,
video:
width: min: 1024, ideal: 1280, max: 1920 ,
height: min: 576, ideal: 720, max: 1080 ,
;
但是,这种语法会在 Chrome 中引发错误。如 cmets 中所述,已制作了 PR 到 adapter.js
,包括用于旧 FF 和 chrome 的 polyfill。
这是我的尝试,仅适用于 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/>
第一个答案
所以在你回答你自己的问题之前,我开始给你写这篇文章。
如 cmets 中所述,我正在绘制视频的每一帧以适应调整大小的画布。
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>
这完成了它的工作,但正如您所指出的,限制仍在开发中,让它们与 Firefox 一起工作的唯一方法是在about:config
中手动设置每个浏览器的media.navigator.video.default_
。
【讨论】:
很好的答案,感谢您的完整解释。你的运行代码 sn-p 非常好:) 只是为了澄清这个误解:如果您使用标准语法而不是过时的 Chrome 语法,约束在 Firefox 中工作得很好。它应该是width: min: 640
而不是minWidth: 640
。也跳过mandatory
。见this answer。
@jib 是的,我看到了这个答案,(看看我对已接受答案的评论)我会更新答案,但我不确定你跳过 Chrome 语法的想法是个好主意,因为Chrome 使用 w3 的语法抛出一个错误,并且不会显示任何内容。但是,我会在几分钟后将我写的 polyfill 放入编辑中。因此,我不确定require: ["width", "height"]
何时集成到 FF 中。我将不得不尝试使用旧版本,所以我现在让我的答案。
@Kaiido 这个答案已经***年了。去年我在 FF32 中添加了 require
语法,不幸的是,在新语法正在制定中(我使用 jesup)在规范中绕道而行。 - 我同意 Chome 抛出错误是不幸的,但我建议向他们提出问题,因为我们必须集中在标准上,而不是在其他东西上。我正在尝试在跨浏览器垫片 adapter.js 中解决此问题,并且我有一个 PR 用于等待约束的 polyfill,它使规范约束适用于 Chrome 和旧版本的火狐。
更新: adapter.js 现在允许您在 Chrome 和 Firefox 中使用规范约束!【参考方案2】:
好的。好久不见。
我发现如下代码:
var vid_constraints =
mandatory:
maxHeight: 180,
maxWidth: 320
其实没用。更好的方法是简单地使用
navigator.getUserMedia(audio: true, video: true, function(stream)..,function(e)...);
您只需通过 CSS 或内联 html 设置视频的大小。对于我的应用程序,这很好用,因为我只需要将视频内容复制到画布上。最后效果很好。
因此,总而言之,问题似乎出在约束选项上。如果您试图使其在多个浏览器中工作,请远离它们。
如果您需要更好地控制相机分辨率,这可能不适合您。如果您需要对 res 进行有限控制,不妨试试有条件的(即if(navigator.mozGetUserMedia)... //compatible resolutions etc ...
)。
祈祷很快就会有一个标准的getUserMedia
函数被所有浏览器处理! :)
仅供参考。我分叉了一些 fiddleJS 代码并对其进行了修改以在 Chrome 和 Mozilla 中进行测试:http://jsfiddle.net/sidewaiise/Laq5txvq/
【讨论】:
似乎不再起作用了……我也遇到了同样的问题。当 chrome 客户端和 firefox 客户端聊天时,无论我尝试过哪个版本,来自 firefox 的视频始终是 4:3。我现在在firefox 35上,你的小提琴也不起作用...... 如果您的问题只是调整页面上播放的视频大小,那么调整视频播放元素的大小是正确的答案。约束访问不同的相机模式,并且由于人们拥有具有不同能力的不同相机,因此应注意不要过度限制硬件能力,以免无意中排除人的风险。但是,通过 peerConnection 发送视频是另一回事。尽管 peerConnection 会动态调整比特率,但在不需要时避免使用高分辨率和帧速率也会有所帮助。小提琴为我工作 FWIW。以上是关于Firefox 和 Chrome 中的 getUserMedia() 视频大小不同的主要内容,如果未能解决你的问题,请参考以下文章