【问题标题】:getUserMedia() video size in Firefox & Chrome differsFirefox 和 Chrome 中的 getUserMedia() 视频大小不同
【发布时间】: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 answerstackoverflow.com/questions/17502205/webrtc-resolution-limit 似乎是firefox缺乏功能

标签: javascript google-chrome firefox html5-video getusermedia


【解决方案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 中所述,已制作了 PRadapter.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。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
  • 2011-09-29
  • 1970-01-01
  • 1970-01-01
  • 2020-12-30
  • 2016-03-19
相关资源
最近更新 更多