2016-04-06 3 views
1

Ich habe eine Frage über die Reihenfolge von JavaScript. Lassen Sie mich zuerst Sie meinen Code zeigen:Weisen Sie den Wert von MediaDevices.enumerateDevices() in globale Variable in JavaScript

Hier ist mein HTML:

<video id="video" width="320" height="320" autoplay></video><br> 
<button id="snap">Snap Photo</button><br> 
<canvas id="canvas" width="320" height="320"></canvas> 
<p id="pngHolder"></p> 

Und hier ist mein JavaScript:

<script> 
var Id; 
//List cameras and microphones. 
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) { 
    console.log("enumerateDevices() not supported."); 
} 
navigator.mediaDevices.enumerateDevices() 
.then(function (devices) { 
    devices.forEach(function (device) { 
     if (device.kind == "videoinput" && device.label.indexOf('back') >= 0) { 
      Id = device.deviceId; 
      alert("ID 1 : " + Id); 
     } 
    }); 
}) 
.catch(function (err) { 
    console.log(err.name + ": " + err.message); 
}); 

// Put event listeners into place 
window.addEventListener("DOMContentLoaded", function() { 
    // Grab elements, create settings, etc. 
    alert("ID 2 : "+ Id); 
    var canvas = document.getElementById("canvas"), 
     videoObj = { 
      video: { 
       optional: [{ deviceId: Id }] 
      } 
     }, 
     context = canvas.getContext("2d"), 
     video = document.getElementById("video"), 
     errBack = function (error) { 
      console.log("Video capture error: ", error.code); 
     }; 

    // Trigger photo take 
    document.getElementById("snap").addEventListener("click", function() { 
     context.drawImage(video, 0, 0, 640, 480); 
     // Get the image 
     var image = convertCanvasToImage(canvas); 
     // Actions 
     document.getElementById("pngHolder").appendChild(image); 
     // Converts canvas to an image 
     function convertCanvasToImage(canvas) { 
      var image = new Image(); 
      image.src = canvas.toDataURL("image/png"); 
      return image; 
     } 
    }); 

    //alert("ID 2 : " + Id); 
    // Put video listeners into place 
    if (navigator.getUserMedia) { // Standard 
     navigator.getUserMedia(videoObj, function (stream) { 
      video.src = stream; 
      video.play(); 
     }, errBack); 
    } else if (navigator.webkitGetUserMedia) { // WebKit-prefixed 
     navigator.webkitGetUserMedia(videoObj, function (stream) { 
      video.src = window.webkitURL.createObjectURL(stream); 
      video.play(); 
     }, errBack); 
    } else if (navigator.mozGetUserMedia) { // Firefox-prefixed 
     navigator.mozGetUserMedia(videoObj, function (stream) { 
      video.src = window.URL.createObjectURL(stream); 
      video.play(); 
     }, errBack); 
    } 
}, false); 

ich den Wert von device.deviceId in variable Id eingefügt werden soll, dass Ich definiere auf der ersten meiner JavaScript-Zeile. Es ist immer noch ein Erfolg (es wird durch die alert("ID 1 : " + Id); gezeigt). Aber wenn ich versuche, es in optional: [{ deviceId: Id }] zu setzen, hat der Id keinen Wert.

Und auch, wenn ich versuche, es mit dem Browser zu starten, habe ich festgestellt, dass alert("ID 2 : " + Id); zuerst anstelle von alert("ID 1 : " + Id); angezeigt wird. In der Tat habe ich bereits die alert("ID 1 : " + Id); zuerst gesetzt. Ich denke, deshalb ist die Variable noch leer.

Meine Frage ist, wie kann ich den device.deviceId Wert auf optional: [{ deviceId: Id }] einfügen?

Antwort

1

navigator.mediaDevices.enumerateDevices() ist asynchron. Es gibt ein Versprechen (denke Rückruf, aber Züchter).

Sie sollten von dort den Aufruf von getUserMedia auslösen oder auf DOMContentLoaded und enumerateDevices warten und dann getUserMedia ausführen.

5

navigator.mediaDevices.enumerateDevices und DOMContentLoaded sind Rennen, und letzteres gewinnt, also verwenden Sie Id, bevor es eingestellt ist.

auf dieser Anwendung ein temporäres haveId Versprechen lösen:

var haveId = navigator.mediaDevices.enumerateDevices() 
    .then(devices => devices.find(d => d.kind == "videoinput" && 
           d.label.indexOf("back") >= 0)); 

// Put event listeners into place 
window.addEventListener("DOMContentLoaded", function() { 
    haveId.then(id => { 
    // Grab elements, create settings, etc. 
    alert("ID 2 : "+ id); 
    var canvas = document.getElementById("canvas"), 
    videoObj = { video: { deviceId: id } }, // <-- adapter.js constraints 

Versprechen Ketten schaffen Abhängigkeiten, und auf diese Weise des getUserMedia Code wird nicht gehen, bis beiden Dinge geschehen.

Das zweite Problem ist, Sie mischen neue und outdated Chrome-specific constraints. Verwenden Sie entweder adapter.js, bis Chrome aufholt, oder verwenden Sie im Notfall die Nur-Chrome-Version sourceId (die aber in keinem anderen Browser funktioniert).

+0

Es tut mir leid, ich verstehe immer noch nicht mit Ihrem Beispiel. Ich habe versucht, es zu implementieren, aber es zeigt Fehler bei "=>" und "haveId.then (id => {". Möchten Sie mehr darüber erfahren? –

+0

@YusrilMaulidanRaji oh, das sind [Pfeil Funktionen] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions), nur um hier kurz zu bleiben. Ersetzen Sie jedes 'x => y' durch' function (x) {return y;} ' und es sollte genauso funktionieren. – jib

Verwandte Themen