2014-12-11 22 views
21

Próbuję uzyskać najwyższą rozdzielczość wideo przez JS navigator.getUserMedia. Wiem o ograniczeniach, ale nie wiem, jak wybrać właściwy w moim przypadku.Uzyskaj maksymalną rozdzielczość wideo za pomocą getUserMedia

Problem wygląda na to, że nie można powiedzieć "Chcę wideo o maksymalnej rozdzielczości". Zamiast tego próbuję powiedzieć "Chcę wideo nie mniej niż bardzo dużą rozdzielczość".

Kiedy próbuję minWidth: 1600, Chrome zwraca mi 1280 × 720 wideo (najwyższy możliwy dla mojej kamery, myślę). Ale co, jeśli użytkownik ma kamerę o wyższej rozdzielczości? Pytam więc o film wideo minWidth: 2048, a Chrome zwraca tylko 640 × 480.

var constraints = { 
    video: { 
    optional: [ 
    {minWidth: 2048} 
    ] 
    } 
}; 

Jest to przykład na stronie: http://jsbin.com/kibeza/1/watch?js,output

I jest rzeczywisty problem: Chrome nie zna matematyki. Uważam, że 1600 jest większe niż 2048. Nie mogę poprosić o wideo "nie mniej niż 100500", ponieważ w tym przypadku otrzymam standardową niską rozdzielczość. Nie mogę pytać wideo "nie mniej niż rozsądna mała rozdzielczość", ponieważ mogą istnieć użytkownicy o wyższej rozdzielczości i chcę uzyskać wyższą rozdzielczość.

+0

Czy widziałeś [ten błąd?] (Https://code.google.com/p/chromium/issues/detail?id=312928) – Martin

+0

to zabawne, gdy zażądam rezolucji, która jest zbyt duża, dostaję "ConstraintNotSatisfiedError" i żaden film nie jest zwracany – Michael

Odpowiedz

10

ja nadal nie wiem poprawną odpowiedź, ale należy wykonać następujące czynności:

video: { 
    optional: [ 
    {minWidth: 320}, 
    {minWidth: 640}, 
    {minWidth: 1024}, 
    {minWidth: 1280}, 
    {minWidth: 1920}, 
    {minWidth: 2560}, 
    ] 
} 

Chociaż pojedynczy rozdzielczości resetuje minWidth: 2560 wyrażenie domyślne, seria minWidth ekspresji make przeglądarce zawsze ma maksymalną rozdzielczość na testowanego sprzętu.

+0

Nadal nie ma żadnych wiadomości? – Jiloc

+1

To odpowiednia odpowiedź dla Chrome, na razie. Ograniczenia minimalna/maksymalna tworzą zakresy wartości prawnych, które przeglądarka ma nadal swobodę wyboru dowolnej wartości w obrębie, więc jedynym sposobem wpływania na kierunek jest coraz węższy lub szerszy zakres. Działa to, ponieważ przeglądarka próbuje skumulować tak wiele zakresów, jak to tylko możliwe, zaczynając od pierwszego i pomijając te, które nadmiernie ograniczają. Chrome ma nadzieję, że wkrótce przejdzie na [standard] (http://stackoverflow.com/questions/28282385/webrtc-firefox-constraints/28911694#28911694), który obsługuje to bardziej intuicyjnie. – jib

+0

nie jest to wspaniałe, jeśli natywna szerokość jest większa niż 2560 lub nie ma na powyższej liście. – Michael

3

zgadzam się z HoMM, jego podejście działa prawidłowo: 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 = ''; 
    } 
} 

W moim przypadku, Opera i Chrome oferują Maksymalna rozdzielczość 1280 × 720.

Firefox domyślnie daje rozdzielczość 640 × 480, ale można poprawić jego rozdzielczość do 1280 × 720. Proszę bardzo:

enter image description here

+0

W rzeczywistości Firefox wyprzedza Chrome i obsługuje specyfikację, więc jest to bułka z masłem: '{wideo: {szerokość: 9999, wysokość: 9999 }} 'daje najwyższą możliwą rozdzielczość. Zobacz [to powiązana odpowiedź] (http://stackoverflow.com/questions/28282385/webrtc-firefox-constraints/28911694#28911694) – jib

3

Miałem urozmaicone sukces definiowania ideal wymiary i próbuje wymusić „wstecz” aparatu.

$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); 
}); 
4

Jeszcze nie znalazłem żadnych dobrych API, aby uzyskać maksymalną rozdzielczość wideo z getUserMedia.

Ale tu dzielę mój pomysł, aby uzyskać maksymalną obsługiwana rozdzielczość video podłączonego urządzenia za pomocą Binary Search algorytm i wszystko działa świetnie.

Oto kroki do wykonania tej pracy,

  • Przechowuj kilka standardowych uchwał w tablicy, zachowując rosnąco zamówienia.
  • Zestaw leftIndex = 0 i rightIndex = tablica rozmiarów rozdzielczości.
  • Sprawdź midIndex = (lewy + prawy)/2 rozdzielczości obsługiwane lub nie, i modyfikować w lewo i prawo w oparciu o wynik.

Tutaj dzielę się moją realizacji:

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(); 
} 

Wystarczy zadzwonić funkcja FindMaximum_WidthHeight_ForCamera(). Po zakończeniu operacji maksymalna rozdzielczość wideo zostanie zapisana w zmiennych wybranychWidth i selectedHeight. Ja tu również dołączenie wyjścia konsoli do mojego urządzenia:

//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 

Ja testowałem tej implementacji korzystając Chrome w wersji 57.0.2987.110 (64-bit) i Logitech Webcam C270, Inc.. Ale myślę, że to rozwiązanie powinno działać w każdym scenariuszu. Dziękuję Ci.

+0

To wydaje się całkiem dobrym rozwiązaniem, ale otrzymuję 1280x900 dla Motorola G2 i Motorola G3 , a ich maksymalna rozdzielczość wideo to 1280x720 – deweydb

+0

Naprawdę dostajesz wideo po wybraniu rozdzielczości przez ten algorytm. Istnieją dwa scenariusze dla twojego problemu .... i) dostajesz wideo ii) Nie dostajesz wideo, po wybraniu rozdzielczości – RajibTheKing

1

Zastosowanie:

var constraints = { 
    video: { 
     width: { ideal: 4096 }, 
     height: { ideal: 2160 } 
    } 
}; 

To spowoduje, że przeglądarka używa maksymalnej rozdzielczości nie jest dostępna, aż do 4K. Pracuje w Chrome 63, Firefox krawędzi 41 i 58.

Powołując MDN dotyczących stosowania idealnego:

Idealnym wartość, jeśli jest stosowany, ma grawitacji, co oznacza, że ​​przeglądarka spróbuje znajdź ustawienie (i kamerę, jeśli masz więcej niż jedną), o najmniejszej odległości od idealnych podanych wartości.

Powiązane problemy