Прямая трансляция веб-камеры с веб-камеры (с использованием getUserMedia) путем записи фрагментов с помощью MediaRecorder через WEB API с помощью WebSockets и MediaSource

Я пытаюсь транслировать видео с веб-камеры другим клиентам в режиме реального времени, но у меня возникают проблемы, когда зритель начинает смотреть в середине.

Для этого я получаю поток веб-камеры, используя getUserMedia (и все его братья и сестры).

Затем, по нажатию кнопки, я начинаю записывать поток и отправляю каждый сегмент / кусок / как вы его называете на серверную часть веб-сокета вещателя:

var mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start(1000);
mediaRecorder.ondataavailable = function (event) {
    uploadVideoSegment(event); //wrap with a blob and call socket.send(...)
}

На стороне сервера (веб-API, используя Microsoft.Web.WebSockets) я получаю байт [] как есть.

Затем я отправляю byte [] зрителям, которые в данный момент подключены к Broadcaster, считываю его по событию onmessage сокета с помощью FileReader и добавляю Uint8Array к sourceBuffer MediaSource, который является src элемента HTML5 video.

Когда зрители получают байт [] с самого начала, в частности, первые 126 байтов, которые начинаются с EBMLHeader (0x1A45DFA3) и заканчиваются началом кластера (0x1F43B675), а затем - всей массой мультимедиа - все воспроизводится нормально.

Проблема возникает, когда новый зритель присоединяется в середине и получает второй блок и позже.

Я пытался исследовать и немного пачкать руки некоторыми способами. Я так понимаю, что шапка необходима (http://www.slideshare.net/mganeko/media-recorder-and-webm), что есть кое-что касающееся ключевых кадров и всего такого, но я очень быстро запутался.

До сих пор я пытался написать свой собственный простой синтаксический анализатор webm на c # (из ссылки на проект node.js в github -https://github.com/mganeko/wmls). Таким образом, я отделил заголовок от первого чанка, кэшировал его и попытался отправить его с каждым чанком позже. Конечно, это не сработало.

Я думаю, что, возможно, MediaRecorder разделяет кластер по центру, так как событие ondataavailable вызывается (это потому, что я заметил, что запуск второго блока не начинается с заголовка кластера).

В этот момент я застрял, не зная, как использовать парсер, чтобы он заработал.

Затем я прочитал об использовании ffmpeg для преобразования потока webm. Каждый кадр также является ключевым кадром -Кодирование FFMPEG в MPEG-DASH - или WebM с кластерами ключевых кадров - для MediaSource API (в ответе Криса Ноле).

Я пытался использовать FFMpegConverter (для .Net), используя:

var conv = new FFMpegConverter();
var outputStream = new MemoryStream();

var liveMedia = conv.ConvertLiveMedia("webm", outputStream, "webm", new ConvertSettings { VideoCodec = "vp8", CustomOutputArgs = "-g 1" });
liveMedia.Start();
liveMedia.Write(vs.RawByteArr, 0, vs.RawByteArr.Length); //vs.RawByteArr is the byte[] I got from the MediaRecorder
liveMedia.Stop();

byte[] buf = new byte[outputStream.Length];
outputStream.Position = 0;
outputStream.Read(buf, 0, (int)outputStream.Length);

Я не знаком с FFMPEG, так что, вероятно, я не получаю правильные параметры, хотя в ответе это то, что я видел, но они вроде как написали это очень скоро.

Конечно, здесь я столкнулся с множеством проблем: при использовании веб-сокетов запуск FFMpegConverter просто заставлял закрывать канал веб-сокетов. (Я буду рад, если кто-то может объяснить, почему).

Я не сдавался, я написал все без веб-сокетов, используя методы HttpGet (для извлечения сегмента с сервера) и HttpPost (с множественными BLOB-объектами и всем последующим участником для публикации записанных кусков) и попытался использовать FFMpegConverter, как упомянуто выше.

Для первого сегмента это работало, НО превзошел байт [] с половинной длиной исходного (я буду рад, если кто-то мог бы объяснить это также), а для других кусков это вызвало исключение (каждый раз, не только один раз) говоря, что труба закончилась.

Я заблудился.

Пожалуйста, помогите мне, кто-нибудь. Основные 4 вопроса:

Как можно воспроизвести фрагменты, которые следуют за первым фрагментом MediaRecorder? (Между тем, я просто запускаю события закрытия / окончания sourcebuffer, и sourceBuffer отсоединяется от его родительского объекта MediaSource (вызывая исключение типа «sourceBuffer был удален из его родителя») из-за того, что byte [] передан это нехорошо - Может быть, я не использую анализатор webm, который я написал правильно, чтобы обнаружить важные части во втором фрагменте (который, кстати, не начинается с кластера - почему я написал, что кажется, что MediaRecorder режет кластер посередине))

Почему FFMpeg вызывает закрытие WebSockets?

Использую ли я FFMpegConverter.ConvertLiveMedia с правильными параметрами, чтобы получить новый сегмент webm со всей информацией, необходимой для его получения в качестве отдельного чанка, без зависимости от прежних чанков (как сказал Крис Нолет в своем ответе в ТАК ссылка выше)?

Почему FFMpegConverter генерирует исключение "конец канала"?

Любая помощь будет чрезвычайно ценится.

Ответы на вопрос(0)

Ваш ответ на вопрос