webentwicklung-frage-antwort-db.com.de

Maximale Videoauflösung mit getUserMedia

Ich versuche, die höchstmögliche Videoauflösung durch JS navigator.getUserMedia zu erhalten. Ich kenne mich mit Einschränkungen aus, weiß aber nicht, wie ich mich in meinem Fall richtig entscheiden soll.

Das Problem ist, dass es keine Möglichkeit gibt zu sagen "Ich möchte ein Video mit maximaler Auflösung". Stattdessen versuche ich zu sagen: "Ich möchte, dass das Video eine nicht sehr große Auflösung hat".

Wenn ich minWidth: 1600 versuche, liefert Chrome ein 1280 × 720-Video (höchstes Niveau für meine Kamera, denke ich). Was aber, wenn der Benutzer eine Kamera mit höherer Auflösung hat? Ich frage nach minWidth: 2048 Video und Chrome gibt nur 640 × 480 zurück.

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

Dies ist ein Online-Beispiel: http://jsbin.com/kibeza/1/watch?js,output

Und es gibt ein tatsächliches Problem: Chrome kennt keine Mathematik. Ich denke, was 1600 ist, ist größer als 2048. Ich kann nicht nach einem Video "nicht weniger als 100500" fragen, da ich in diesem Fall eine niedrige Standardauflösung bekomme. Ich kann nicht fragen, Video "nicht weniger als eine angemessene kleine Auflösung", weil es Benutzer mit höherer Auflösung geben kann und ich eine höhere Auflösung erhalten möchte.

24
homm

Ich weiß immer noch nicht die richtige Antwort, aber ich mache Folgendes:

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

Während ein einzelner minWidth: 2560-Ausdruck die Auflösung auf die Standardeinstellung zurücksetzt, nimmt der Browser mit einer Reihe von minWidth-Ausdrücken auf der getesteten Hardware immer die maximale Auflösung.

13
homm

Benutzen:

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

Dadurch verwendet der Browser die maximal verfügbare Auflösung von bis zu 4K. Funktioniert in Chrome 63, Edge 41 und Firefox 58.

Zitieren von MDN bezüglich der Verwendung von ideal:

Wenn ein idealer Wert verwendet wird, hat er die Schwerkraft, was bedeutet, dass der Browser wird versuchen, die Einstellung zu finden (und die Kamera, falls Sie mehr als eine haben), mit dem kleinsten Fitnessabstand von den angegebenen Idealwerten.

8
Honza Kalfus

Ich hatte unterschiedliche Erfolge bei der Definition von ideal-Abmessungen und beim Versuch, die Rückkamera zu erzwingen.

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

Ich habe immer noch keine gute API gefunden, um mit getUserMedia eine maximale Videoauflösung zu erzielen.

Aber hier teile ich meine Idee, um eine maximale unterstützte Videoauflösung zu erhalten des angeschlossenen Geräts mit Binary Search-Algorithmus und es funktioniert super.

Hier sind die Schritte, um diese Arbeit zu erledigen,

  • Speichern Sie einige Standardauflösungen in einem Array in aufrechter Reihenfolge
  • Setze leftIndex = 0 und rightIndex = Größe des Auflösungsfeldes.
  • Prüfen Sie die midIndex = (links + rechts)/2-Auflösung, oder nicht. Und Ändern Sie links und rechts basierend auf dem Ergebnis.

Hier teile ich meine Implementierung: 

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

Rufen Sie einfachfunction FindMaximum_WidthHeight_ForCamera ()auf. Wenn der Vorgang abgeschlossen ist, wird die maximale Videoauflösung in selectedWidth und selectedHeight variables gespeichert. Hier füge ich auch die Konsolenausgabe für mein Gerät an:

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

Ich habe diese Implementierung mit Chrome Version 57.0.2987.110 (64-Bit) und Logitech, Inc. Webcam C270 getestet. Ich denke jedoch, dass diese Lösung in jedem Szenario funktionieren sollte. Danke dir. 

5
RajibTheKing

Ich stimme mit homm überein, sein Ansatz funktioniert gut: 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 meinem Fall bieten Opera und Chrome eine maximale Auflösung von 1280 × 720.

Firefox gibt standardmäßig 640 × 480 an, aber Sie können seine Auflösung auch auf bis zu 1280 × 720 verbessern. Bitte schön:

enter image description here

3
evpozdniakov

Sie können dieses Dienstprogramm überprüfen, um die verfügbaren Auflösungen Ihrer Geräte zu überprüfen:

https://webrtchacks.github.io/WebRTC-Camera-Resolution/

Dies ist hilfreich für die Fehlerbehebung.

Hoffe du findest es interessant!

0
Andrés