Следующий код работает, когда сначала загружается клиент наблюдения за видео, а затем загружается клиент веб-камеры, он работает безупречно, однако, если порядок изменяется или каким-либо образом поток прерывается, например, путем обновления любого клиента, поток завершится ошибкой и Источник мультимедиа изменит свое состояние готовности на закрытое.
Я предполагаю, что видео, получаемое при запуске, требует заголовков инициализации для запуска, и, поскольку поток читается в середине, он никогда не получает указанные заголовки инициализации. Я не знаю, как добавить такой заголовок в файл 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.