Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用WebRTC将数据与视频同步_Javascript_Html_Video_Video Streaming_Webrtc - Fatal编程技术网

Javascript 使用WebRTC将数据与视频同步

Javascript 使用WebRTC将数据与视频同步,javascript,html,video,video-streaming,webrtc,Javascript,Html,Video,Video Streaming,Webrtc,我使用WebRTC将视频从服务器发送到客户端浏览器(使用原生WebRTC API和MCU-WebRTC服务器,如Kurento) 在发送给客户端之前,视频的每一帧都包含元数据(如字幕或任何其他应用程序内容)。我正在寻找一种方法,将此元数据发送到客户端,使其保持同步(到实际呈现的时间)。此外,我希望能够从客户端(通过Javascript)访问这些数据 我想到的一些选择: 通过WebRTC数据通道发送数据。但我不知道如何确保数据在每帧的基础上同步。但我找不到一种方法来确保数据通道和视频通道发送的数

我使用
WebRTC
将视频从服务器发送到客户端浏览器(使用原生
WebRTC API
MCU-WebRTC
服务器,如Kurento)

在发送给客户端之前,视频的每一帧都包含元数据(如字幕或任何其他应用程序内容)。我正在寻找一种方法,将此元数据发送到客户端,使其保持同步(到实际呈现的时间)。此外,我希望能够从客户端(通过Javascript)访问这些数据

我想到的一些选择:

  • 通过WebRTC数据通道发送数据。但我不知道如何确保数据在每帧的基础上同步。但我找不到一种方法来确保数据通道和视频通道发送的数据是同步的(同样,我希望获得单帧的精度水平)
  • 以某种方式(WebRTC数据通道、websockets等)将数据手动发送到客户端,时间戳与视频的时间戳匹配。但是,即使Kurento或其他中间服务器在视频中保留时间戳信息,根据以下答案,也没有实用的方法从javascript获取视频时间戳: . 我曾考虑过使用标准视频元素的
    timeupdate
    事件,但我不知道它是否适用于帧的精度级别,我也不确定它在WebRTC中的直播视频中意味着什么
  • 手动发送数据并将其作为另一个
    textrack
    附加到视频。然后使用
    oneter
    onexit
    同步读取它:。它仍然需要精确的时间戳,我不知道如何知道时间戳是什么,以及Kurento是否按原样传递时间戳
  • 使用WebRTC的统计API手动计数帧(使用
    getstats
    ),希望此API提供的信息准确无误
做这件事的最好方法是什么,以及如何解决我提到的问题


编辑:需要将元数据与相应帧精确同步(分辨率不超过一帧)。

好的,首先让我们使用getUserMedia获取视频和音频,并使用

:


我怀疑每帧的数据量相当小。我会把它编码成一个二维条码图像,然后把它放在每一帧中,这样它就不会被压缩掉。或者只是像这样编码时间戳


然后,在播放器端,您查看特定帧中的图像,然后将数据取出,或者如果是这样的话。

如果将它们分开,您将永远无法获得完美的同步流。您可以实现一个缓冲系统,以确保在两个流中都有可用的可接受缓冲区之前,不会有任何向前的进展。你最好的办法是忘记完美的帧对帧匹配,如果你想要的话,然后将其编码到视频流中作为动态视频。除了音频和图形,我想不出你为什么需要如此高的精度。如果你忘记了完美的时机,事情就简单多了。谢谢,说得好。无论如何,问题在于如何通过编程实现,假设我可以确保元数据流在视频流之前已经到达浏览器。你关于重新编码视频的建议听起来不错,但我仍然需要匹配视频流和元数据流的时间-我甚至不确定中间服务器是否保留了演示时间戳。媒体流提供了一些帮助。如果您使用的是HTML5视频,您可以使用buffered返回一个TimeRanges对象,让您知道缓冲了什么。HTMLMediaElement接口提供currentTime作为读写属性。您可以使用它获取视频的时间(以秒为单位)。获取当前帧号
frameNumber=Math.floor(videoElement.currentTime/frameRate)写入currentTime将导致视频搜索到该时间。这似乎是一个不错的方向。但是,我还不明白如何将元数据同步到正确的视频帧?不管怎样,我不喜欢使用MediaSource,因为它有一些限制(例如,段应该以关键帧开始)好吧,你有vídeo数据,所以现在你可以在第一次尝试中操纵它,也许可以使用计时器,根据需要增加或减少延迟,这是我认为我们现在唯一的方法,或者不使用webRTC,选择WebSocket。计时器不够精确,无法满足我的需要。Websockets是一个很好的主意,我已经研究过了,但是我需要使用MediaSource,它有它的缺点。好吧,让我用Websockets写一个答案,你不需要MediaSource,这里的问题是使用webRTC,来自服务器的视频是一个文件,静态视频,不像会议那样是实时的,对吗?它是实时视频。当然,如果我需要元数据,并且既没有延迟要求,也没有对等连接,那么我没有任何理由选择webrtc。
/*
 *
 *  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);
}
/*
 *
 *  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);