2015-05-22 2 views
16

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

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

Некоторые опции я думал:

  • Отправка данных по WebRTC DataChannel. Но я не знаю, как обеспечить синхронизацию данных по каждому кадру. Но я не мог найти способ обеспечить передачу данных по каналу данных и синхронизацию видеоканала (опять же, я надеюсь получить точный уровень одиночного кадра).
  • Отправка данных вручную клиенту в некотором роде (WebRTC DataChannel, websockets и т. Д.) С отметками времени, соответствующими отметкам времени видео. Однако, даже если Kurento или другие средние серверы сохраняют информацию о отметке времени в видео, в соответствии со следующим ответом, нет подходящего способа получить метки времени видео из javascript: How can use the webRTC Javascript API to access the outgoing audio RTP timestamp at the sender and the incoming audio RTP timestamp at the receiver?. Я думал об использовании события стандартного видеоэлемента timeupdate, но я не знаю, будет ли он работать для точного уровня кадра, и я не уверен, что это значит в живом видео, как в WebRTC.
  • Отправка данных вручную и прикрепление их к видео применительно как другое TextTrack. Затем используйте onenter и onexit, чтобы прочитать его синхронно: http://www.html5rocks.com/en/tutorials/track/basics/. Он по-прежнему требует точных временных меток, и я не уверен, как узнать, какие временные метки и если Куренто передает их как есть.
  • Использование API статистики WebRTC для подсчета кадров вручную (с использованием getstats) и надеемся, что информация, предоставленная этим API, является точной.

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

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

+0

Вы никогда не получите идеальные синхронизированные потоки, если будете их разделять. Вы можете внедрить системы буферизации, чтобы гарантировать отсутствие прогресса вперед, пока в обоих потоках не будет доступного буфера. Лучше всего забыть идеальный кадр для соответствия кадра, если вы хотите, чтобы он затем закодировал его в видеопоток как видео на лету. Помимо звука и графики, я не могу думать, почему вам нужна такая высокая точность. Вы забываете, что идеальные моменты времени становятся намного проще. – Blindman67

+0

Спасибо, хорошая точка. В любом случае возникает вопрос о том, как это сделать программно, предполагая, что я могу убедиться, что поток метаданных уже достигнут в браузере перед видеопотоком. Ваше предложение перекодировать видео звучит неплохо, но мне все же нужно сопоставлять время потока видео и потока метаданных - я даже не уверен, что средний сервер сохраняет метки времени презентации. – MaMazav

+1

Медиапотоки предоставляют некоторую помощь. Если вы используете HTML5-видео, вы можете использовать буферизацию для возврата объекта TimeRanges, чтобы вы знали, что было буферизировано. Интерфейс HTMLMediaElement предоставляет currentTime как атрибут read write. Вы можете использовать его, чтобы получить время в секундах видео. Чтобы получить текущий номер кадра 'frameNumber = Math.floor (videoElement.currentTime/frameRate);' Запись в currentTime приведет к тому, что видео будет искать к этому времени. – Blindman67

ответ

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); 
+0

Похоже на красивое направление. Однако я пока не понимаю, как я могу синхронизировать метаданные с правильным видеокадром? И вообще, я предпочитаю не использовать MediaSource, поскольку он имеет некоторые ограничения (например, сегмент должен начинаться с ключевого кадра https://code.google.com/p/chromium/issues/detail?id=229412) – MaMazav

+1

Ну, у вас есть данные vídeo , так что теперь вы можете манипулировать им в первую очередь, может быть, с таймерами, и при необходимости использовать более или менее латентность, это единственный способ, который, как я думаю, имеет прямо сейчас, или не использовать webRTC, искать веб-узлы. – Jairo

+0

Таймеры недостаточно точны для моих нужд. Websockets - отличная идея, которую я уже исследовал, но тогда мне нужно использовать MediaSource, который имеет свои недостатки. – MaMazav

Смежные вопросы