将MediaDevices.enumerateDevices()的值赋给JavaScript中的全局变量

将MediaDevices.enumerateDevices()的值赋给JavaScript中的全局变量,javascript,html,mobile,camera,webrtc,Javascript,Html,Mobile,Camera,Webrtc,我有一个关于JavaScript序列的问题。让我先向您展示我的代码: 这是我的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

我有一个关于JavaScript序列的问题。让我先向您展示我的代码:

这是我的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>

快照照片

下面是我的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);

变量Id;
//列出摄像机和麦克风。
如果(!navigator.mediaDevices | |!navigator.mediaDevices.enumerateDevices){
log(“enumerateDevices()不受支持”);
}
navigator.mediaDevices.enumerateDevices()
.然后(功能(设备){
设备。forEach(功能(设备){
if(device.kind==“videoinput”&&device.label.indexOf('back')>=0){
Id=device.deviceId;
警报(“ID 1:+ID”);
}
});
})
.catch(函数(err){
console.log(err.name+“:”+err.message);
});
//将事件侦听器放置到位
addEventListener(“DOMContentLoaded”,函数(){
//抓取元素、创建设置等。
警报(“ID 2:+ID”);
var canvas=document.getElementById(“canvas”),
视频对象={
视频:{
可选:[{deviceId:Id}]
}
},
context=canvas.getContext(“2d”),
video=document.getElementById(“视频”),
errBack=函数(错误){
日志(“视频捕获错误:”,错误代码);
};
//触发拍照
document.getElementById(“snap”).addEventListener(“单击”,函数)(){
drawImage(视频,0,0,640,480);
//获取图像
var image=convertCanvasToImage(画布);
//行动
document.getElementById(“pngHolder”).appendChild(图像);
//将画布转换为图像
函数转换器CANVASTOIMAGE(画布){
var image=新图像();
image.src=canvas.toDataURL(“image/png”);
返回图像;
}
});
//警报(“ID 2:+ID”);
//将视频侦听器放置到位
if(navigator.getUserMedia){//Standard
getUserMedia(videoObj,函数(流){
video.src=流;
video.play();
},errBack);
}else if(navigator.webkitGetUserMedia){//WebKit前缀
webkitGetUserMedia(videoObj,函数(流){
video.src=window.webkitURL.createObjectURL(流);
video.play();
},errBack);
}else if(navigator.mozzetusermedia){//Firefox前缀
mozGetUserMedia(videoObj,函数(流){
video.src=window.URL.createObjectURL(流);
video.play();
},errBack);
}
},假);
我想将
device.deviceId
的值插入我在JavaScript行的第一行定义的变量
Id
。它仍然是成功的(通过
警报(“ID 1:+ID”);
显示)。但是当我尝试将它放入
可选:[{deviceId:Id}]
时,
Id
没有任何值

而且,当我尝试用浏览器运行它时,我发现
警报(“ID2:+ID”)而不是
警报(“ID 1:+ID”)。事实上,我已经发出了
警报(“ID 1:+ID”)第一个。我想这就是变量仍然为空的原因


我的问题是如何将
device.deviceId
值插入
可选:[{deviceId:Id}]

navigator.mediaDevices.enumerateDevices()是异步的。它返回一个承诺(想想回调,但更喜欢)


您应该从那里触发对getUserMedia的调用,或者等待DOMContentLoaded和enumerateDevices,然后执行getUserMedia。

navigator.mediaDevices.enumerateDevices和
DOMContentLoaded
正在比赛,后者获胜,因此您在设置之前使用
Id

要解决此问题,请使用临时的haveId承诺:

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
var haveId=navigator.mediaDevices.enumerateDevices()
.then(devices=>devices.find(d=>d.kind==“videoinput”&&
d、 label.indexOf(“back”)>=0);
//将事件侦听器放置到位
addEventListener(“DOMContentLoaded”,函数(){
haveId.then(id=>{
//抓取元素、创建设置等。
警报(“ID 2:+ID”);
var canvas=document.getElementById(“canvas”),

videoObj={video:{deviceId:id}},//对不起,我还是不理解你的例子。我试图实现它,但它在“=>”和“haveId.then(id=>{)处显示了错误。你想详细说明一下吗?@YusrilMaulidanRaji哦,这些,只是用于brievity的。用
函数(x)替换每个
x=>y
{return y;}
,它的工作原理应该是一样的。