![测量/消除 H.264 视频延迟](https://linux22.com/image/1632147/%E6%B5%8B%E9%87%8F%2F%E6%B6%88%E9%99%A4%20H.264%20%E8%A7%86%E9%A2%91%E5%BB%B6%E8%BF%9F.png)
我有一个 IP 摄像机,它发送一个 H.264 视频流,该视频流应该与单独的音频流混合/多路复用。
直接混合
ffmpeg -i <video> -i <audio> -map 0:v -map 1:a <output>
音频/视频似乎有长达数秒的延迟。我希望尽可能消除这种情况。
我可以以某种方式手动做到这一点(-itsoffset
) 通过尝试和错误进行二分法,但(除此之外,这很尴尬和麻烦)偏移量似乎有所不同。我们在同一天使用相同的设置以相同的方式记录了一些好的和坏的(偏移量> = 1 秒)记录。
事先的音频处理都是模拟的,因此输入延迟应该可以忽略不计。
这种抵消至少似乎源于两个地方:
- 编码 + 传输(直接查看流时大约需要半秒[比较例如挥手])
- ffmpeg 混合自身(ffmpeg 输出具有更高的音频-视频偏移)
关于1
有没有办法以编程方式近似先验视频延迟?
多路复用计算机和摄像机运行 NTP 客户端,以便它们的时钟看起来是一致的。
如果我可以从 H.264 元数据字段中推断出摄像机的系统时间,我可以通过减去本地时间直接得到偏移量。我偶然发现了聚合酶链反应和公共科学图书馆(添加。这里),但是我对H.264的了解太浅薄了。
关于2
什么原因导致了额外的偏移?
编辑
实际的完整 ffmpeg 命令是:
ffmpeg
-use_wallclock_as_timestamps 1 \
-fflags +genpts \
-max_delay 2000000 \
-thread_queue_size 1024 \
-i <rtsp-video> \
-max_delay 2000000 \
-thread_queue_size 1024 \
-itsoffset <audio-offset> \
-f pulse \
-i <audio-device> \
-af "aresample=async=1" \
-codec:a aac \
-b:a 384k \
-ar 48000 \
-vcodec copy \
-tune zerolatency \
-map 0:v -map 1:a \
-max_muxing_queue_size 99999 \
-f flv \
-y \
<output>
此外,我发现开放RTSP(livemedia-utils
在 Debian 和live-media
Arch 上)获取一个参数o
(例如o=- 1599320926814396
),该参数与摄像头 UTC 系统时间(以微秒为单位)很好地对应,也显示在 Web 界面上。我认为这是进一步调查的一个有希望的开端。
例如
$ date -d@$( echo $(openRTSP -r rtsp://109.98.78.106 2>&1 | grep -Po '(?<=o=-\s)\d+' | head -n1 ) / 1000000 | bc )
Sat Sep 5 05:48:46 PM CEST 2020
答案1
关于 1,答案是 H.264视频比特流不包含可用的时间戳信息。其中任何一个都会在运输RTSP (RTP) 数据包。有关此内容的更多信息,请参阅以下问题的答案:
https://stackoverflow.com/questions/6149983/h-264-rtsp-absolute-timestamp
这可能会让你以半自动化的方式解决一些事情。
关于 2,ffmpeg
将在随机点拾取 RTSP 流,视频在获得 I 图像之前无法解码。我不知道ffmpeg
比特流如何重新打包,但如果在同步点之前在流的开头有一些 RTP 数据包被丢弃,我不会感到惊讶。
不确定您的使用情况,但如果您想使用廉价的 IP 摄像机从混音器中获取音频并实时播放视频,那么这只是痛苦世界的开始。
答案2
对于其他偶然发现这篇文章的人来说:我最终得到了以下内容(那种作品):
- 在录音电脑上设置本地 ntp 服务器
- 将摄像机 ntp 客户端设置为录制计算机 ntp 服务器,并将其设置为定期同步
- 录音计算机的系统时间和 RTP 流的时间戳之间的差异可以让您粗略地估计数据包的传输时间。
- 在录制之前执行一次此操作,并使用该偏移量计算一个值作为偏移量插入到 ffmpeg 中。