Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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
WebRTC:在JavaScript和本机代码对等方之间同步视频帧_Javascript_C++_Video Streaming_Webrtc_Audio Video Sync - Fatal编程技术网

WebRTC:在JavaScript和本机代码对等方之间同步视频帧

WebRTC:在JavaScript和本机代码对等方之间同步视频帧,javascript,c++,video-streaming,webrtc,audio-video-sync,Javascript,C++,Video Streaming,Webrtc,Audio Video Sync,它遵循了我试图实现的设计方法:我有一个JavaScript对等机,它正在向对等机发送视频曲目。在传输过程中的某个时刻(实际上是在连接建立之后,但可能是在任何时刻),我想在JS对等端启动秒表并执行一些临时操作,实际上是在覆盖视频播放的画布上进行渲染。在本地对等端,我希望能够在JS对等点上秒表开始的瞬间同步,并且只考虑在该时刻记录的接收到的帧,执行其他类型的处理。我现在所做的(脆弱和有限的解决方案): 一旦对等点连接,跟踪rtpeerconnection.iceConnectionState,我就

它遵循了我试图实现的设计方法:我有一个JavaScript对等机,它正在向对等机发送视频曲目。在传输过程中的某个时刻(实际上是在连接建立之后,但可能是在任何时刻),我想在JS对等端启动秒表并执行一些临时操作,实际上是在覆盖视频播放的画布上进行渲染。在本地对等端,我希望能够在JS对等点上秒表开始的瞬间同步,并且只考虑在该时刻记录的接收到的帧,执行其他类型的处理。我现在所做的(脆弱和有限的解决方案):

  • 一旦对等点连接,跟踪
    rtpeerconnection.iceConnectionState
    ,我就启动JS对等点上的秒表
  • 当第一个
    webrtc::VideoFrame
    到达本机对等机时,我存储帧时间间隔
  • 在本机对等机上,我使用第一帧时间戳来计算相对时间,类似于秒表在JS对等机上允许的方式

这种设计是有限的,因为我可能希望在任何时刻同步,而不仅仅是在建立对等连接时,而且也很脆弱,因为我认为WebRTC协议允许出于任何原因(延迟或传输错误)丢弃第一个接收到的帧。理想情况下,我希望在JS对等机中选择的同步点上获取一个时间戳,将其发送到本机对等机,并能够比较
webrtc::VideoFrame
时间戳。我不能天真地这样做,因为
VideoFrame::timestamp_us()
明显地被一些我不知道的量所扭曲。另外,我无法解释
VideoFrame::timestamp()
,它在
api/video/video\u frame.h
中的文档记录很差,
VideoFrame::ntp\u time\ms()
被弃用,实际上总是返回
-1
。我应该怎么做才能在两个对等点之间完成这种同步?

可以通过在NTP发送方时间中向接收方发送同步事件时间戳来正确实现设计。然后,接收方必须能够估计帧上的发送方NTP时间戳,并将其与同步事件的时间戳进行比较。支持此方法的概念验证补丁已存在,并已在此跟踪中推送到本机WebRTC项目。更多细节将在后面介绍。

我建议使用带内信号。您打算使用canvas操作JS端。当您想要开始同步时,只需使用canvas setPixelData()发送一个全黑帧即可。本机客户端可以识别这样的帧,跳过它(你不想闪烁,是吗?)并切换到“其他类型的处理”。我根本不操纵JS端视频,它只是画布中的一个覆盖。视频曲目是我使用
getUserMedia()
获得的网络摄像头的流。同步信号应该尽可能地谨慎:黑色帧肯定不好,而且我可能会运气太差,完全错过它。在考虑它之前,我需要证明从
getUserMedia()
对视频轨迹进行视频操作实际上是可行的。但是说真的:我认为我的标准称为Web实时通信的标准应该真的给了我一些设施,可以按照我描述的方式同步两个对等流。@AlexCohn非常有趣:我发现通过将MediaStreamTrack重定向到canvas元素并用
HTMLCanvasElement.captureStream()
。这在MS Edge中还不受支持,这意味着对我来说还不是一个好的解决方案。不过,我真的认为在本地代码对等机中应该有其他解决方案:如果webrtc::VideoFrame保留了RTP时间戳,这将与JS端的Date.now(),这个问题实际上是不需要动脑筋的。我担心JS无法访问视频帧内部,因此无法访问其时间戳。至于带外同步,我会选择简单的UTC。在标准视频中,视频帧之间的传输时间应远小于200毫秒,这样发送方和接收方之间就不会错过任何一帧。至于本地时钟偏移,这在现代连接设备上可能可以忽略不计,但即使不是,也有众所周知的算法来补偿它。@AlexCohn是的,我知道JS无法访问内部(尽管事情是这样的):我说的是本机代码端也不公开远程对等时间戳或估计的偏移(至少不是以一种明显的方式,而且API也没有真正的文档化)。我在中问了同样的问题:我仍然希望一些实际处理内部构件的开发人员能够提供一些支持。