we_*_*mor 5 javascript domexception mediadevices
我正在尝试在 nodeJS 服务器上创建照片捕获 Web 应用程序,并且我正在使用下面的javascript代码。
const btn = document.querySelector('#btn');
btn.addEventListener('click', (event) => {
navigator.mediaDevices.getUserMedia({video: true})
.then(gotMedia)
.catch(error => console.error('getUserMedia() error:', error));
event.preventDefault()
})
Run Code Online (Sandbox Code Playgroud)
而gotMedia函数是这样的:
function gotMedia(mediaStream) {
const mediaStreamTrack = mediaStream.getVideoTracks()[0];
const imageCapture = new ImageCapture(mediaStreamTrack);
console.log(imageCapture);
const canvas = document.querySelector('canvas');
// ...
imageCapture.grabFrame()
.then(imageBitmap => {
canvas.width = imageBitmap.width;
canvas.height = imageBitmap.height;
canvas.getContext('2d').drawImage(imageBitmap, 0, 0);
})
.catch(error => console.error('grabFrame() error:', error));
}
Run Code Online (Sandbox Code Playgroud)
一切正常,图像捕捉正常,但是当我一张又一张地快速拍摄照片时,出现错误,提示:
grabFrame() 错误:DOMException:关联的 Track 处于无效状态。
当我拍摄太多照片时(例如快速单击约 20 秒以上),通常会发生这种情况,但前五张快照也会发生这种情况。有谁知道发生了什么事以及我应该改变什么才能解决这个问题?感谢您的时间。
小智 6
根据规范,此类错误可能是由于不可接受的状态造成的。在铬源中我发现了这种方法。
我已经使用这样的代码克服了错误:
const promise = getPrevImagePromise();
if (!promise && !(imageCapture.track.readyState != 'live' || !imageCapture.track.enabled || imageCapture.track.muted)) {
const imagePromise = imageCapture.grabFrame()
.then((image) => {
// do work with image
})
.then(() => {
deletePrevImagePromise()
})
.catch((error) => {
//
});
setPrevImagePromise(imagePromise);
}
Run Code Online (Sandbox Code Playgroud)
我遇到了同样的问题,无法让前沿grabFrame功能可靠地工作。
相反,您可以从中间视频源进行绘制。在你的函数中,它看起来像这样(未经测试):
function gotMedia(mediaStream) {
const mediaStreamTrack = mediaStream.getVideoTracks()[0];
const canvas = document.querySelector('canvas');
const video = document.createElement('video');
video.autoplay = true;
video.srcObject = mediaStream;
video.onplay = () => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0);
};
}
Run Code Online (Sandbox Code Playgroud)
当然,如果您要捕获大量帧,最好在流旁边创建一个视频并每次都从中捕获。