Синхронизация данных с видео с помощью WebRTC

Я использую WebRTC для отправки видео с сервера на браузер клиента (используя собственный WebRTC API и MCU WebRTC сервер, например Kurento).

Прежде чем отправлять его клиентам, каждый кадр видео содержит метаданные (например, субтитры или любой другой аппликативный контент). Я ищу способ отправить эти метаданные клиенту, чтобы он оставался синхронизированным (до момента его фактического представления). Кроме того, я хотел бы иметь доступ к этим данным со стороны клиента (по Javascript).

Некоторые варианты, о которых я думал:

  • Отправка данных с помощью WebRTC DataChannel. Но я не знаю, как обеспечить синхронизацию данных по каждому кадру. Но я не мог найти способ обеспечить передачу данных по каналу данных и синхронизацию видеоканала (опять же, я надеюсь получить точный уровень одиночного кадра).
  • Отправка данных вручную клиенту в некотором роде (WebRTC DataChannel, websockets и т.д.) с отметками времени, которые соответствуют отметкам времени видео. Однако, даже если Kurento или другие средние серверы сохраняют информацию о отметке времени в видео, согласно следующему ответу, нет подходящего способа получить метки времени видео из javascript: Как использовать API Javascript WebRTC для доступа к исходящей звуковой метке RTP в отправителе и временной отметке времени RTP в приемнике?. Я думал об использовании стандартного видеоэлемента timeupdate, но я не знаю, будет ли он работать для точного уровня кадра, и я не уверен, что это значит в реальном видео, как в WebRTC.
  • Отправка данных вручную и присоединение к видео в качестве другого TextTrack. Затем используйте onenter и onexit, чтобы прочитать его синхронно: http://www.html5rocks.com/en/tutorials/track/basics/. Он по-прежнему требует точных временных меток, и я не уверен, как узнать, какие временные метки и если Куренто передает их как есть.
  • Используя API статистики WebRTC для ручного подсчета кадров (используя getstats) и надейтесь, что информация, предоставленная этим API, будет точной.

Каков наилучший способ сделать это и как решить проблемы, о которых я упомянул в любом случае?

EDIT: Требуется точная синхронизация (с разрешением не более одного кадра) метаданных с соответствующим фреймом.

Ответы

Ответ 1

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

Затем на стороне игрока вы просматриваете изображение в определенном кадре и извлекаете данные или, если хотите,

Ответ 2

Хорошо, сначала давайте получим видео и аудио с помощью getUserMedia и дадим исходные данные с помощью

https://github.com/streamproc/MediaStreamRecorder

:

/*
 *
 *  Video Streamer
 *
 */


<script src="https://cdn.webrtc-experiment.com/MediaStreamRecorder.js"> </script>
<script>

// FIREFOX

var mediaConstraints = {
    audio: !!navigator.mozGetUserMedia, // don't forget audio!
    video: true                         // don't forget video!
};

navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);

function onMediaSuccess(stream) {
    var mediaRecorder = new MediaStreamRecorder(stream);
    mediaRecorder.mimeType = 'video/webm';
    mediaRecorder.ondataavailable = function (blob) {
        // POST/PUT "Blob" using FormData/XHR2

    };
    mediaRecorder.start(3000);
}

function onMediaError(e) {
    console.error('media error', e);
}
</script>



// CHROME

var mediaConstraints = {
    audio: true,
    video: true
};

navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);

function onMediaSuccess(stream) {
    var multiStreamRecorder = new MultiStreamRecorder(stream);
    multiStreamRecorder.video = yourVideoElement; // to get maximum accuracy
    multiStreamRecorder.audioChannels = 1;
    multiStreamRecorder.ondataavailable = function (blobs) {
        // blobs.audio
        // blobs.video
    };
    multiStreamRecorder.start(3000);
}

function onMediaError(e) {
    console.error('media error', e);
}

Теперь вы можете отправить данные через DataChannels и добавить свои метаданные в стороне получателя:

/*
 *
 *  Video Receiver
 *
 */


 var ms = new MediaSource();

 var video = document.querySelector('video');
 video.src = window.URL.createObjectURL(ms);

 ms.addEventListener('sourceopen', function(e) {
   var sourceBuffer = ms.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
   sourceBuffer.appendBuffer(/* Video chunks here */);
 }, false);