Javascript 使用 getUserMedia 获得最大视频分辨率
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27420581/
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
Get maximum video resolution with getUserMedia
提问by homm
I'm trying to get highest video resolution as possible through JS navigator.getUserMedia. I know about constraints, but don't know how to choose right in my case.
我正在尝试通过 JS 获得尽可能高的视频分辨率navigator.getUserMedia。我知道约束,但不知道如何在我的情况下选择正确的。
The problem is looks like there is no way to say "I want a video at maximum resolution". So instead I'm trying to say "I want video not less than very big resolution".
问题是看起来没有办法说“我想要最大分辨率的视频”。所以相反,我试图说“我想要视频的分辨率不低于非常大”。
When I'm trying minWidth: 1600, Chrome returns me 1280×720 video (highest possible for my camera, I think). But what if user has camera with higher resolution? So I'm asking for minWidth: 2048video, and Chrome returns only 640×480.
当我尝试时minWidth: 1600,Chrome 会返回 1280×720 的视频(我认为我的相机可能是最高的)。但是如果用户有更高分辨率的相机呢?所以我要minWidth: 2048视频,Chrome 只返回 640×480。
var constraints = {
video: {
optional: [
{minWidth: 2048}
]
}
};
This is online example: http://jsbin.com/kibeza/1/watch?js,output
这是在线示例:http: //jsbin.com/kibeza/1/watch?js,output
And there is actual problem: Chrome doesn't know math. It think what 1600 is greater than 2048. I can't ask for video "not less than 100500", because in this case I'll get standard low resolution. I cant ask video "not less than some reasonable small resolution", because there can be users with higher resolution and I want to get higher resolution.
还有一个实际问题:Chrome 不懂数学。它认为1600大于2048。我不能要求视频“不低于100500”,因为在这种情况下我会得到标准的低分辨率。我不能要求视频“不低于一些合理的小分辨率”,因为可以有更高分辨率的用户,我想获得更高的分辨率。
回答by Honza Kalfus
Use:
用:
var constraints = {
video: {
width: { ideal: 4096 },
height: { ideal: 2160 }
}
};
This will make the browser use the maximum resolution available, up to 4K. Works in Chrome 63, Edge 41 and Firefox 58.
这将使浏览器使用可用的最大分辨率,最高可达 4K。适用于 Chrome 63、Edge 41 和 Firefox 58。
Citing MDNregarding the use of ideal:
引用MDN关于理想的使用:
An ideal value, when used, has gravity, which means that the browser will try to find the setting (and camera, if you have more than one), with the smallest fitness distance from the ideal values given.
理想值在使用时具有重力,这意味着浏览器将尝试找到与给定理想值的最小适应距离的设置(和相机,如果您有多个)。
回答by homm
I still don't know correct answer, but I do the following:
我仍然不知道正确答案,但我执行以下操作:
video: {
optional: [
{minWidth: 320},
{minWidth: 640},
{minWidth: 1024},
{minWidth: 1280},
{minWidth: 1920},
{minWidth: 2560},
]
}
While single minWidth: 2560expression resets resolution to default, series of minWidthexpression make browser always takes maximum resolution on tested hardware.
当单个minWidth: 2560表达式将分辨率重置为默认值时,一系列minWidth表达式使浏览器在测试的硬件上始终采用最大分辨率。
回答by sidonaldson
I had varied success with defining idealdimensions and trying to force the 'back' camera.
我在定义ideal尺寸和尝试强制“后置”相机方面取得了不同的成功。
$video = document.getElementById('video')
//declare ideal values
var constraints = {
audio: false,
video: {
width: { ideal: 1280 },
height: { ideal: 1024 },
facingMode: "environment"
}
};
// enumerate devices and select the first camera (mostly the back one)
navigator.mediaDevices.enumerateDevices().then(function(devices) {
for (var i = 0; i !== devices.length; ++i) {
if (devices[i].kind === 'videoinput') {
console.log('Camera found: ', devices[i].label || 'label not found', devices[i].deviceId || 'id no found');
videoConstraints.deviceId = { exact: devices[i].deviceId }
}
}
});
//first up the stream
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
$video.srcObject = stream;
// log the real size
console.log($video.videoWidth, $video.videoHeight);
}).catch(function(err) {
console.log(err.name + ': ' + err.message);
});
回答by RajibTheKing
Still I haven't found any good API to get maximum video resolution with getUserMedia.
我仍然没有找到任何好的 API 来使用getUserMedia获得最大视频分辨率。
But here I am sharing my idea to get maximum supported video resolutionof the connected device using Binary Search algorithmand it's working great.
但在这里我分享了我的想法,即使用二进制搜索算法获得所连接设备的最大支持视频分辨率,并且效果很好。
Here are the steps to do this job,
以下是完成这项工作的步骤,
- Store some standard resolutions in an Array, maintaining ascending order .
- Set leftIndex= 0 and rightIndex= size of resolution array.
- Check midIndex= (left+right)/2 resolution supported or not, and modify left and right based on the result.
- 在 Array 中存储一些标准分辨率,保持升序。
- 设置leftIndex= 0 和rightIndex= 分辨率数组的大小。
- 检查midIndex= (left+right)/2分辨率是否支持,根据结果修改左右。
Here I am sharing my implementation:
在这里我分享我的实现:
var ResolutionsToCheck = [
{width: 160, height:120},
{width: 320, height:180},
{width: 320, height:240},
{width: 640, height:360},
{width: 640, height:480},
{width: 768, height:576},
{width: 1024, height:576},
{width: 1280, height:720},
{width: 1280, height:768},
{width: 1280, height:800},
{width: 1280, height:900},
{width: 1280, height:1000},
{width: 1920, height:1080},
{width: 1920, height:1200},
{width: 2560, height:1440},
{width: 3840, height:2160},
{width: 4096, height:2160}
];
var left = 0;
var right = ResolutionsToCheck.length;
var selectedWidth;
var selectedHeight;
var mid;
function FindMaximum_WidthHeight_ForCamera()
{
console.log("left:right = ", left, ":", right);
if(left > right)
{
console.log("Selected Height:Width = ", selectedWidth, ":", selectedHeight);
return;
}
mid = Math.floor((left + right) / 2);
var temporaryConstraints = {
"audio": true,
"video": {
"mandatory": {
"minWidth": ResolutionsToCheck[mid].width,
"minHeight": ResolutionsToCheck[mid].height,
"maxWidth": ResolutionsToCheck[mid].width,
"maxHeight": ResolutionsToCheck[mid].height
},
"optional": []
}
}
navigator.mediaDevices.getUserMedia(temporaryConstraints).then(checkSuccess).catch(checkError);
}
function checkSuccess(stream)
{
console.log("Success for --> " , mid , " ", ResolutionsToCheck[mid]);
selectedWidth = ResolutionsToCheck[mid].width;
selectedHeight = ResolutionsToCheck[mid].height;
left = mid+1;
for (let track of stream.getTracks())
{
track.stop()
}
FindMaximum_WidthHeight_ForCamera();
}
function checkError(error)
{
console.log("Failed for --> " + mid , " ", ResolutionsToCheck[mid], " ", error);
right = mid-1;
FindMaximum_WidthHeight_ForCamera();
}
Just call function FindMaximum_WidthHeight_ForCamera(). When operation will be completed then maximum video resolution will be stored in selectedWidthand selectedHeightvariables. Here I am also attaching console output for my device:
只需调用函数 FindMaximum_WidthHeight_ForCamera()。操作完成后,最大视频分辨率将存储在selectedWidth和selectedHeight变量中。在这里,我还为我的设备附加了控制台输出:
//Console Output
left:right = 0 : 17
Success for --> 8 Objectheight: 768width: 1280__proto__: Object
left:right = 9 : 17
Failed for --> 13 Objectheight: 1200width: 1920__proto__: Object NavigatorUserMediaError
left:right = 9 : 12
Success for --> 10 Objectheight: 900width: 1280__proto__: Object
left:right = 11 : 12
Failed for --> 11 Objectheight: 1000width: 1280__proto__: Object NavigatorUserMediaError
left:right = 11 : 10
Selected Height:Width = 1280 : 900
I have tested this implementation using Chrome Version 57.0.2987.110 (64-bit)and Logitech, Inc. Webcam C270. But I think this solution should work in each scenario. Thank You.
我已经使用Chrome 版本 57.0.2987.110(64 位)和Logitech, Inc. Webcam C270测试了这个实现。但我认为这个解决方案应该适用于每种情况。谢谢你。
回答by evpozdniakov
I agree with homm, his approach works fine: https://jsfiddle.net/evpozdniakov/c84ksucw/
我同意 homm,他的方法效果很好:https://jsfiddle.net/evpozdniakov/c84ksucw/
var getUserMediaPrefixed,
videoStream,
videoTag;
setGumPrefix();
if (!getUserMediaPrefixed) {
logMessage('Sorry, your browser doesn\'t support getUserMedia interface');
}
else {
runCamera();
}
function dealWithStream(stream) {
videoStream = stream;
if (!videoTag) {
videoTag = document.createElement('video');
videoTag.addEventListener('resize', videoEventListener);
}
videoTag.src = window.URL.createObjectURL(stream);
videoTag.play();
}
function handleError(e) {
if (e.name == 'PermissionDeniedError') {
logMessage('It looks like you\'ve denied access to the camera.');
}
else if (e.name == 'SourceUnavailableError') {
logMessage('It looks like your camera is <b>used</b> by another application.');
}
else {
logMessage('The camera is unavailable. The error message is: ' +e.message);
}
}
function logMessage(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.getElementById('output').appendChild(p);
}
function runCamera() {
var constraints = {
audio: false,
video: {
optional: [
{minWidth: 320},
{minWidth: 640},
{minWidth: 800},
{minWidth: 900},
{minWidth: 1024},
{minWidth: 1280},
{minWidth: 1920},
{minWidth: 2560}
]
}
};
navigator[getUserMediaPrefixed](constraints, dealWithStream, handleError);
}
function setGumPrefix() {
if (navigator.getUserMedia) {
getUserMediaPrefixed = 'getUserMedia';
}
else if (navigator.webkitGetUserMedia) {
getUserMediaPrefixed = 'webkitGetUserMedia';
}
else if (navigator.mozGetUserMedia) {
getUserMediaPrefixed = 'mozGetUserMedia';
}
else if (navigator.msGetUserMedia) {
getUserMediaPrefixed = 'msGetUserMedia';
}
}
function videoEventListener() {
if (videoTag.videoWidth) {
logMessage('Best captured video quality in your browser is ' +videoTag.videoWidth+ '×' +videoTag.videoHeight);
// stop stream
videoStream.stop();
videoTag.src = '';
}
}
In my case, Opera and Chrome offer max resolution 1280×720.
就我而言,Opera 和 Chrome 提供的最大分辨率为 1280×720。
Firefox gives 640×480 by default, but you can improve his resolution as well up to 1280×720. Here you go:
Firefox 默认提供 640×480,但您也可以将其分辨率提高到 1280×720。干得好:


回答by Andrés
You can check this utility to check the available resolutions of your devices:
您可以检查此实用程序以检查设备的可用分辨率:
https://webrtchacks.github.io/WebRTC-Camera-Resolution/
https://webrtchacks.github.io/WebRTC-Camera-Resolution/
It is useful for troubleshooting purposes.
它可用于故障排除目的。
Hope you find it interesting!
希望你觉得它很有趣!

