FFmpeg concat视频和音频不同步

Xeo*_*oss 22 audio video ffmpeg concatenation

使用ffmpeg concat连接多个文件似乎导致音频的时间戳或偏移不匹配.我尝试了几个视频,并注意到h.264/MP4的相同问题.

使用concat 和编码视频似乎工作正常.音频保持同步,因为ffmpeg执行完整的转换计算,似乎可以使一切正常.

但是,简单地连接视频而不进行任何转换或编码会导致同步问题缓慢增加.显然,对视频进行编码而不是简单地加入它们将导致信息/质量的损失,所以我宁愿找到解决这个问题的方法.

我已经尝试了几个标志来解决这个似乎基于时间戳的问题.但这些似乎都没有解决问题.

ffmpeg -f concat -fflags +genpts -async 1 -i segments.txt test.mov
ffmpeg -auto_convert 1 -f concat -fflags +genpts -async 1 -i segments.txt -c copy test2.mov
ffmpeg -f concat -i segments.txt -c copy -fflags +genpts test3.mp4
ffmpeg -f concat -fflags +genpts -async 1 -i segments.txt -copyts test4.mov
ffmpeg -f concat -i segments.txt -copyts test5.mov
ffmpeg -f concat -i segments.txt -copyts -c copy test6.mov
ffmpeg -f concat -fflags +genpts -i segments.txt -copyts -c copy test7.mov
Run Code Online (Sandbox Code Playgroud)

注意:我在SO上可以找到的所有其他问题似乎只是通过重新编码视频来"修复"问题.不是一个好的解决方案

更新

我意识到concat不是问题所在.原始剪辑集的时间戳不匹配.以某种方式c​​oncat +编码解决了这个问题,但我不想每次重新编码视频和松散的质量.

ffmpeg -y -ss 00:00:02.750 -i input.MOV -c copy -t 00:00:05.880 output.MOV
Run Code Online (Sandbox Code Playgroud)

这导致了以下数据

ffprobe -v quiet -show_entries stream=start_time,duration output.MOV

start_time=-0.247500
duration=6.131125
start_time=-0.257333
duration=6.155333
Run Code Online (Sandbox Code Playgroud)

从那时起,我一直尝试使用-tom和-t不同的地方-af apad -c:v copy,但我仍然没有得到相同的持续时间.

这是完整的ffprobe输出

这是原始(红色)与细分(绿色)

详细的示例文件

我录制了一个示例视频,添加了斩断的命令,然后将其连接起来.http://davidpennington.me/share/audio_sync_test_video.zip

Gya*_*yan 14

这两步过程应该有效

步骤1 在每个段中填充音频

ffmpeg -i segment1.mov -af apad -c:v copy <audio encoding params> -shortest -avoid_negative_ts make_zero -fflags +genpts padded1.mov
Run Code Online (Sandbox Code Playgroud)

要么

使用同步流生成段

ffmpeg -y -ss 00:00:02.750 -i input.MOV -c copy -t 00:00:05.880 -avoid_negative_ts make_zero -fflags +genpts segment.MOV
Run Code Online (Sandbox Code Playgroud)

第2步 Concat

ffmpeg -f concat -i segments.txt -c copy test.mov
Run Code Online (Sandbox Code Playgroud)

其中segments.txt包含填充文件的名称.

  • 您的片段具有负 PTS,因为 ffmpeg 在分割点之前的关键帧处剪切片段,但将 PTS 0 分配给您的分割点,因此之前的帧具有负 PTS。所以我编辑的命令可以解决这个问题。然而,有一个问题。分割点之前的音频量与之前的视频量不相等,因此接头处仍然会出现一些静音。sboisse 的方法可能是最安全的。 (2认同)

Pau*_*aul 12

我遇到了类似的问题并找到了一个有效的解决方案,至少对我来说是这样。就我而言,我还连接了文件,发现 iO 存在音频/视频同步问题,但 Windows 没有(例如,VLC 媒体播放器使用相同的 mp4 文件没有显示同步问题)。iO 播放此串联 mp4 的症状是,最初同步良好,随后随着电影播放,同步丢失越来越多,音频速度比视频快。有趣的是,通过将电影进度滑块推进到电影中的任何点,可以暂时恢复同步,但随着电影继续在 iO 中播放,同步将再次丢失。通过在 iO 和 Windows VLC 中同时播放同一部电影,并且最初尽可能地相互同步,通过观察它们之间“回声”的演变,我得出的结论是 iO 音频速度太快(假设Windows 播放器是正确的)。

对我来说,解决方案是将音频过滤器选项添加-af aresample=async=1000到 ffmpeg 命令中,我在 ffmpeg 在线文档中找到了该选项作为示例并逐字使用。我不知道这个设置是否是最佳的,但结果是 mp4 在 iO 和 VLC 播放时音频和视频保持同步。此 ffmpeg 选项在串联期间以及之后重新编码已串联的文件时产生了正确的 iO 同步。


小智 3

你可以用来filter_complex一次性连接不同的选项

ffmpeg -i input1.mp4 -i input2.webm \
-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" <encoding options> output.mkv
Run Code Online (Sandbox Code Playgroud)

  • 您的命令使用过滤器,因此将重新编码,但 Xeoncross 希望避免这种情况。 (3认同)