FFmpeg:音频开始时间偏离

FFmpeg:音频开始时间偏离

实时音频和视频从一个音频源和两个视频源录制:

ffmpeg -y -copyts \
  -f pulse -thread_queue_size 1024 -i alsa_input.usb-Focusrite_Scarlett_2i2_USB_Y8CAJW2063E5BD-00.analog-stereo \
  -f v4l2 -thread_queue_size 1024 -video_size 1920x1080 -input_format mjpeg -i /dev/video0 \
  -f v4l2 -thread_queue_size 1024 -video_size 1920x1080 -input_format mjpeg -i /dev/video6 \
  -map 0:a -map 1:v -map 2:v -c:v libx264 -preset ultrafast test.mp4

-copyts两个视频流同步的效果(另见FFmpeg:同步来自两个网络摄像头的流)。但是录音中听不到任何声音。查看输出中的开始时间可以解释原因:

Input #0, pulse, from 'alsa_input.usb-Focusrite_Scarlett_2i2_USB_Y8CAJW2063E5BD-00.analog-stereo':
  Duration: N/A, start: 1599927759.812456, bitrate: 1536 kb/s
    Stream #0:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
Input #1, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 54432.851793, bitrate: N/A
    Stream #1:0: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 1920x1080, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Input #2, video4linux2,v4l2, from '/dev/video6':
  Duration: N/A, start: 54433.882342, bitrate: N/A
    Stream #2:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 1920x1080, 30 fps, 30 tbr, 1000k tbn, 1000k tbc

视频设备的两个时间非常接近,符合预期:54432.851793 和 54433.882342。但音频设备的时间相差甚远:1599927759.812456。

任何想法如何解决这一问题?

答案1

音频设备提供的时间实际上是更合理的:它似乎是自纪元以来的时间。参见https://stackoverflow.com/questions/10266451/where-does-v4l2-buffer-timestamp-value-starts-counting了解更多信息。这也表明了修复此问题的方法:-af "asetpts=PTS-x/TB"x系统启动时的时间(秒)是多少(不是正常运行时间,但系统启动的时间点)。您可以从/proc/stats以 开头的行获取它btime。当系统进入挂起或类似状态时,这可能会弄乱,因此请注意这一点。

使用asetptssetpts还可以省去第二遍使用-start_at_zero,这是在FFmpeg:同步来自两个网络摄像头的流。这是一个完整的示例解决方案:

btime_=`grep btime /proc/stat | awk '{print $2}'`
utime_=`awk '{print $1}' /proc/uptime`
btime_utime_=`echo "${btime_?} + ${utime_?}" | bc -l`
ffmpeg -y -copyts \
  -f pulse -thread_queue_size 1024 -i alsa_input.usb-Focusrite_Scarlett_2i2_USB_Y8CAJW2063E5BD-00.analog-stereo \
  -f v4l2 -thread_queue_size 1024 -video_size 1920x1080 -input_format mjpeg -i /dev/video0 \
  -f v4l2 -thread_queue_size 1024 -video_size 1920x1080 -input_format mjpeg -i /dev/video6 \
  -map 0:a -map 1:v -map 2:v -c:v libx264 -preset ultrafast \
  -af "asetpts=PTS-${btime_utime_?}/TB" \
  -vf "setpts=PTS-${utime_?}/TB" \
  test.mp4

请注意,按正常运行时间进行移动(为了避免第二次通过-start_at_zero)并不完全准确,因为第一个 PTS 将略大于零。但到目前为止,这对于我的目的来说已经足够了。

相关内容