以下代码在首先加载视频观察客户端然后加载网络摄像头客户端时工作正常,但是,如果切换顺序或以任何方式中断流,例如通过刷新任一客户端,流将失败并且媒体源将其就绪状态更改为关闭。
我的假设是,在开始时接收到的视频需要初始化标头来启动,并且由于流是在中途读取的,所以它永远不会得到所说的初始化标头。我不确定如何将此类标头添加到 webm 文件中。
我试图更改源缓冲区上的序列模式,但什么也没做。我已经尝试重新启动录像机并且可行,但我的最终计划是拥有多个观察客户端,并且在每次重新连接时重新启动录像机并不是最佳的。
相机客户端
main();
function main() {
if (hasGetUserMedia()) {
const constraints = {
video: {
facingMode: 'environment',
frameRate: {
ideal: 10,
max: 15
}
},
audio: true
};
navigator.mediaDevices.getUserMedia(constraints).
then(stream => {
setupRecorder(stream);
});
}
}
function setupRecorder(stream) {
let mediaRecorder = new MediaRecorder(stream, {
mimeType: 'video/webm; codecs="opus, vp9"'
});
mediaRecorder.ondataavailable = e => {
var blob = e.data;
socket.emit('video', blob);
}
mediaRecorder.start(500);
}
服务器只是广播接收到的任何内容
观察客户
var sourceBuffer;
var queue = [];
var mediaSource = new MediaSource();
mediaSource.addEventListener('sourceopen', sourceOpen, false);
main();
socket.on('stream', data => {
if (mediaSource.readyState == "open") {
if (sourceBuffer.updating || queue.length > 0) {
queue.push(data.video);
} else {
sourceBuffer.appendBuffer(data.video);
}
}
});
function main() {
videoElement = document.querySelector('#video');
videoElement.src = URL.createObjectURL(mediaSource);
}
function sourceOpen(e) {
console.log('open');
sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="opus, vp9"');
sourceBuffer.addEventListener('updateend', () => {
console.log(sourceBuffer.updating, mediaSource.readyState);
if (queue.length > 0 && !sourceBuffer.updating) {
sourceBuffer.appendBuffer(queue.shift());
}
});
}
所以事实上,代码只是以一种不正确的方式工作,因此套接字发送服务器没有任何问题。它要么与 MediaRecorder 或 MediaSource 有关。