实时音频和视频从一个音频源和两个视频源录制:
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
。当系统进入挂起或类似状态时,这可能会弄乱,因此请注意这一点。
使用asetpts
和setpts
还可以省去第二遍使用-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 将略大于零。但到目前为止,这对于我的目的来说已经足够了。