为什么在 FFmpeg 中在网络摄像头视频输入之前指定音频输入会导致它们不同步?

为什么在 FFmpeg 中在网络摄像头视频输入之前指定音频输入会导致它们不同步?

我正在使用 FFmpeg 从网络摄像头和脉冲音频源流式传输到 RTMP 服务器。

我知道参数顺序在 FFmpeg 中会产生影响。

但我发现如果我在视频输入流之前指定音频输入流那么音频有延迟,大约落后于视频半秒。

既然这些只是两个输入流组合在一起的输出,为什么顺序会产生影响呢?

为了简化这篇文章,我已经剥离并测试了以下命令,实际上我正在使用硬件加速、AAC 和各种其他编解码器选项,输入排序的效果始终相同。

FFmpeg命令首先指定视频输入(无延迟):

ffmpeg -f v4l2 -input_format mjpeg -framerate 30 -video_size 1280x720 -i /dev/video1 -f pulse -i default -c:v libx264 -preset veryfast -f flv rtmp://a.rtmp.youtube.com/live2/${STREAM_KEY}

FFmpeg命令首先指定音频输入(音频落后视频 0.5 秒):

ffmpeg -f pulse -i default -f v4l2 -input_format mjpeg -framerate 30 -video_size 1280x720 -i /dev/video1 -c:v libx264 -preset veryfast -f flv rtmp://a.rtmp.youtube.com/live2/${STREAM_KEY}

FFmpeg 的标准输出消息似乎是相同的,除了流顺序之外。

当视频输入为第一个时输出:

Input #0, video4linux2,v4l2, from '/dev/video1':
  Duration: N/A, start: 331644.817465, bitrate: N/A
    Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Guessed Channel Layout for Input Stream #1.0 : stereo
Input #1, pulse, from 'default':
  Duration: N/A, start: 1596371796.728130, bitrate: 1536 kb/s
    Stream #1:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> h264 (libx264))
  Stream #1:0 -> #0:1 (pcm_s16le (native) -> mp3 (libmp3lame))

当音频输入第一次时输出:

Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, pulse, from 'default':
  Duration: N/A, start: 1596371788.496242, bitrate: 1536 kb/s
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Input #1, video4linux2,v4l2, from '/dev/video1':
  Duration: N/A, start: 331637.326454, bitrate: N/A
    Stream #1:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Stream mapping:
  Stream #1:0 -> #0:0 (mjpeg (native) -> h264 (libx264))
  Stream #0:0 -> #0:1 (pcm_s16le (native) -> mp3 (libmp3lame))

如你看到的,每种情况下的流映射都是正确的

这是怎么回事?任何见解表示赞赏。

FFmpeg 是在 Ubuntu 20.04 上从 git 编译的版本 n4.3.1。

答案1

我刚刚遇到了这个问题 - 无法弄清楚为什么我的视频总是落后 3 秒,无论我使用什么选项。然后我注意到了start时间:

Input #0, x11grab, from ':10.0':
  Duration: N/A, start: 1627448930.994615, bitrate: N/A
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, 25 fps, 25.08 tbr, 1000k tbn, 1000k tbc
Input #1, pulse, from 'grab.monitor':
  Duration: N/A, start: 1627448933.416430, bitrate: 1536 kb/s
    Stream #1:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s

一旦我切换:

Input #0, pulse, from 'grab.monitor':
  Duration: N/A, start: 1627449055.508778, bitrate: 1536 kb/s
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Input #1, x11grab, from ':10.0':
  Duration: N/A, start: 1627449055.550277, bitrate: N/A
    Stream #1:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 1920x1080, 25 fps, 24.92 tbr, 1000k tbn, 1000k tbc

没有更多问题了。我思考如果您要抓取没有时间戳的流,ffmpeg 将抓取输入 0 的开始时间,初始化输入 0,抓取输入 1 的开始时间,初始化输入 1,然后在我的情况下延迟视频 3 秒以尝试对齐他们。我会先保留哪个启动速度更快。

相关内容