Событие обратного вызова для getUserMedia()
Я пытаюсь сделать снимок с моей веб-камеры с помощью navigator.mediaDevices.getUserMedia()
а также canvas.getContext('2d').drawImage()
функции.
Когда я делаю это так, это работает отлично:
function init(){
myVideo = document.getElementById("myVideo")
myCanvas = document.getElementById("myCanvas");
videoWidth = myCanvas.width;
videoHeight = myCanvas.height;
startVideoStream();
}
function startVideoStream(){
navigator.mediaDevices.getUserMedia({audio: false, video: { width: videoWidth, height: videoHeight }}).then(function(stream) {
myVideo.src = URL.createObjectURL(stream);
}).catch(function(err) {
console.log("Unable to get video stream: " + err);
});
}
function snapshot(){
myCanvas.getContext('2d').drawImage(myVideo, 0, 0, videoWidth, videoHeight);
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="debug.js"></script>
</head>
<body onload="init()">
<div id="mainContainer">
<video id="myVideo" width="640" height="480" autoplay style="display: inline;"></video>
<canvas id="myCanvas" width="640" height="480" style="display: inline;"></canvas>
<input type="button" id="snapshotButton" value="Snapshot" onclick="snapshot()"/>
</div>
</body>
</html>
Дело в том, что я не хочу использовать нажатие кнопки для создания снимка, но делаю снимок, как только будет загружен поток с камеры. Я попытался вызвать функцию snapshot() сразу после установки источника видео:
function init(){
myVideo = document.getElementById("myVideo")
myCanvas = document.getElementById("myCanvas");
videoWidth = myCanvas.width;
videoHeight = myCanvas.height;
startVideoStream();
}
function startVideoStream(){
navigator.mediaDevices.getUserMedia({audio: false, video: { width: videoWidth, height: videoHeight }}).then(function(stream) {
myVideo.src = URL.createObjectURL(stream);
snapshot();
}).catch(function(err) {
console.log("Unable to get video stream: " + err);
});
}
function snapshot(){
myCanvas.getContext('2d').drawImage(myVideo, 0, 0, videoWidth, videoHeight);
}
Но это не работает. Мой холст остается белым. Я предполагаю, что это потому, что поток камеры не полностью загружен в этот момент.
Так есть ли какое-либо другое событие, которое может быть запущено, которое я мог бы использовать для рисования снимка, как только будет загружен канал камеры? Или я на неправильном пути?
Заранее спасибо!
1 ответ
Ждать loadedmetadata
событие:
navigator.mediaDevices.getUserMedia({video: true})
.then(stream => video.srcObject = stream)
.then(() => new Promise(resolve => video.onloadedmetadata = resolve))
.then(() => canvas.getContext('2d').drawImage(video, 0, 0, 160, 120))
.catch(e => console.log(e));
<video id="video" width="160" height="120" autoplay></video>
<canvas id="canvas" width="160" height="120"></canvas>
Вышеупомянутое должно работать во всех браузерах (которые делают WebRTC).
В Chrome вы также можете сделать это- ноplay()
пока не возвращает обещание ни в одном другом браузере.
Также обратите внимание, что URL.createObjectURL(stream)
устарела. использование srcObject
,