Итак, я пытаюсь создать приложение для прямой трансляции и столкнулся со странной проблемой.
Итак, я использую getUserMedia
для захвата видео от пользователя, после чего пользователь помечается как вещатель. Затем я использую MediaRecorder
, чтобы получить фактические видеоданные из MediaStream
и отправить их через веб-сокет.
Веб-сокет просто транслирует видеоданные всем подключенным клиентам, однако по какой-то причине он правильно воспроизводится только на проигрывателе вещателя, но когда я пытаюсь воспроизвести тот же самый поток с другого клиента, он просто выдает мне эту ошибку:
Uncaught DOMException: Failed to execute 'appendBuffer' on 'SourceBuffer': This SourceBuffer has been removed from the parent media source.
Когда я смотрю в chrome://media-internals, я вижу эту ошибку:
00:00:00 94 error Unexpected element ID 0x8c
00:00:00 94 error Append: stream parsing failed. Data size=33926 append_window_start=0 append_window_end=inf
00:00:00 94 pipeline_error CHUNK_DEMUXER_ERROR_APPEND_FAILED
Скрипты и все конечно одинаково на обоих клиентах. Единственное, что отличается и что, как я думал, может быть виновником, заключается в том, что поток вещателя не начался немедленно, поскольку вещателю сначала нужно отправить видеоданные на сервер веб-сокетов, чтобы сервер мог передать что-либо обратно. Однако клиенты, не являющиеся вещателями, как бы прыгают в «середину» потока.
Единственное другое отличие состоит в том, что трансляция загружает и загружает видеоданные через один и тот же сокет, но я не понимаю, как это повлияет на проблему.
РЕДАКТИРОВАТЬ: после запуска теста, когда оба клиента были подключены к веб-сокету БЕЗ потоковой передачи видео, а затем запуска потока после этого, оба клиента работали, что означает, что проблема возникает из-за того, что другие клиенты прыгают в поток на полпути, как это исправить?
Однако я новичок во всем этом, поэтому я не уверен, что это хорошее рассуждение. Для справки, это скрипт:
var socket = new WebSocket('websocket');
socket.binaryType = 'arraybuffer';
var broadcastMs = new MediaSource();
var video = document.querySelector("#broadcast");
video.src = window.URL.createObjectURL(broadcastMs);
var msReady = false;
var sourceBuffer = false;
var queue = [];
broadcastMs.addEventListener('sourceopen', function(e)
{
sourceBuffer = broadcastMs.addSourceBuffer('video/webm; codecs="opus,vp8"');
sourceBuffer.addEventListener('update', function()
{
if ( queue.length > 0 && !sourceBuffer.updating )
sourceBuffer.appendBuffer(queue.shift());
});
msReady = true;
});
socket.onmessage = function(ev)
{
setTimeout(function()
{
if ( msReady )
{
if ( sourceBuffer.updating )
queue.push(ev.data);
else
sourceBuffer.appendBuffer(ev.data);
}
}, 50);
};