JS navigator.getUserMedia
を使用して、可能な限り最高のビデオ解像度を取得しようとしています。制約については知っていますが、私の場合、正しい選択方法はわかりません。
問題は、「最大解像度のビデオが欲しい」と言う方法がないように見えます。その代わりに、「非常に大きな解像度以上のビデオが欲しい」と言っています。
minWidth: 1600
を試しているとき、Chromeは1280×720のビデオを返します(私のカメラで可能な限り最高だと思います)。 'minWidth: 2048
ビデオを要求し、Chromeは640×480のみを返します。
var constraints = {
video: {
optional: [
{minWidth: 2048}
]
}
};
これはオンラインの例です: http://jsbin.com/kibeza/1/watch?js,output
そして実際の問題があります:Chromeは数学を知りません。1600が2048よりも大きいと思います。この場合、私は「100500以上」のビデオを要求できません。標準の低解像度を取得します。ユーザーに高解像度のユーザーがいる可能性があり、より高い解像度を取得したいので、「妥当な小さな解像度以上」のビデオを要求することはできません。
正しい答えはまだわかりませんが、次のことを行います。
video: {
optional: [
{minWidth: 320},
{minWidth: 640},
{minWidth: 1024},
{minWidth: 1280},
{minWidth: 1920},
{minWidth: 2560},
]
}
シングルminWidth: 2560
式は解像度をデフォルトにリセットし、一連のminWidth
式はテストされたハードウェアで常に最大解像度を取得します。
使用する:
var constraints = {
video: {
width: { ideal: 4096 },
height: { ideal: 2160 }
}
};
これにより、ブラウザは使用可能な最大解像度(最大4K)を使用します。 Chrome 63、Edge 41、Firefox 58で動作します。
引用 [〜#〜] mdn [〜#〜]idealの使用に関して:
理想値を使用すると重力が発生します。つまり、ブラウザは設定値(および複数のカメラがある場合はカメラ)を見つけようとし、与えられた理想値からの最小の適合距離を持ちます。
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);
});
それでも、getUserMediaで最大のビデオ解像度を取得するための適切なAPIは見つかりませんでした。
しかし、ここで私はサポートされている最大のビデオ解像度を得るためのアイデアバイナリ検索アルゴリズムを使用して接続されたデバイスを共有しており、うまく機能しています。
このジョブを実行する手順は次のとおりです。
ここで、実装を共有しています。
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();
}
function 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
Chromeバージョン57.0.2987.110(64ビット)およびLogitech、Inc. Webcam C27を使用して、この実装をテストしました。しかし、このソリューションは各シナリオで機能するはずです。ありがとうございました。
私は同意します、彼のアプローチはうまくいきます: 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 = '';
}
}
私の場合、Opera and Chromeは最大解像度1280×720を提供します。
Firefoxはデフォルトで640×480を提供しますが、解像度を1280×720まで改善できます。どうぞ:
このユーティリティをチェックして、使用可能なデバイスの解像度を確認できます。
https://webrtchacks.github.io/WebRTC-Camera-Resolution/
トラブルシューティングの目的に役立ちます。
面白いと思います!