使用 WebRTC 将数据与视频同步
Synchronization of data with video using WebRTC
我正在使用 WebRTC
将视频从服务器发送到客户端浏览器(使用本机 WebRTC API
和像 Kurento 这样的 MCU 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/。它仍然需要精确的时间戳,我不确定如何知道时间戳是什么以及 Kurento 是否按原样传递它们。
- 利用WebRTC的统计API手动统计帧数(使用
getstats
),希望API提供的信息准确
最好的方法是什么,以及如何解决我在这两种方法中提到的问题?
编辑:需要元数据与适当帧的精确同步(分辨率不超过一帧)。
好的,首先让我们使用 getUserMedia 获取视频和音频,然后使用
使其成为原始数据
:
/*
*
* 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);
我怀疑每帧的数据量相当小。我会考虑将其编码为二维条形码图像,并以某种方式将其放置在每一帧中,这样它就不会被压缩删除。或者像这样编码时间戳。
然后在播放器端,您查看特定帧中的图像并获取数据,或者如果是。
我正在使用 WebRTC
将视频从服务器发送到客户端浏览器(使用本机 WebRTC API
和像 Kurento 这样的 MCU 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/。它仍然需要精确的时间戳,我不确定如何知道时间戳是什么以及 Kurento 是否按原样传递它们。 - 利用WebRTC的统计API手动统计帧数(使用
getstats
),希望API提供的信息准确
最好的方法是什么,以及如何解决我在这两种方法中提到的问题?
编辑:需要元数据与适当帧的精确同步(分辨率不超过一帧)。
好的,首先让我们使用 getUserMedia 获取视频和音频,然后使用
使其成为原始数据:
/*
*
* 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);
我怀疑每帧的数据量相当小。我会考虑将其编码为二维条形码图像,并以某种方式将其放置在每一帧中,这样它就不会被压缩删除。或者像这样编码时间戳。
然后在播放器端,您查看特定帧中的图像并获取数据,或者如果是。