FFmpeg concat视频和音频不同步

问题描述 投票:18回答:5

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

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

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

我有tried several flags来解决这个看似基于时间戳的问题。但这些似乎都没有解决问题。

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

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

更新

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

ffmpeg -y -ss 00:00:02.750 -i input.MOV -c copy -t 00:00:05.880 output.MOV

这导致了以下数据

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

从那时起,我试图在-to-t的不同地方使用-af apad -c:v copym和Here is the full ffprobe output,但我仍未能将持续时间保持不变。

Here is the original (red) vs the segment (green)

http://davidpennington.me/share/audio_sync_test_video.zip

Detailed Sample Files

我录制了一个示例视频,添加了将其删除的命令,然后将其连接起来。 ffmpeg -i segment1.mov -af apad -c:v copy <audio encoding params> -shortest -avoid_negative_ts make_zero -fflags +genpts padded1.mov

audio video ffmpeg concatenation
5个回答
12
投票

这两步过程应该有效

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

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

要么

使用同步流生成段

ffmpeg -f concat -i segments.txt -c copy test.mov

第2步Concat

segments.txt

其中COPY /b input_1.mts + input_2.mts + input_3.mts output.mts 由填充文件的名称组成。


4
投票

我也一直在努力解决这个问题。特别是在使用Panasonic AVCHD生成的MTS文件时。我目前的解决方案是在操作系统级别连接它们而不是ffmpeg。我在Windows上执行此操作,它看起来像这样:

$ cat input_1.mts input_2.mts input_3.mts > output.mts

在linux上它应该是这样的:

windows

您可以查找linuxfilter_complex二进制连接的文档。

如果原始格式适合您,这种连接方法与转码相关联即可。该方法实际上不使用CPU处理并保留原始质量。处理高质量的大宗媒体时双赢。


2
投票

你可以使用fmpeg -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 一次性连接不同的选项

-af aresample=async=1000

1
投票

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

对我来说,解决方案是将音频过滤器选项mkvmerge添加到ffmpeg命令,我在ffmpeg在线文档中作为示例找到并使用了verbatim。我不知道这个设置是否是最佳的,但结果是mp4,当iOs和VLC播放时,音频和视频保持同步。这个ffmpeg选项在连接期间和之后重新编码已连接的文件时都产生了正确的iO同步。


0
投票

如果输入的视频使用相同的设置进行编码,您可以使用mkvtoolnix中的mkvmerge -o output.mkv file1.mkv + file2.mkv + file3.mkv 代替:

for f in *.mp4;do width=1280;height=720;ffmpeg -i $f -filter:v "scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih), pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:($height-ih*min($width/iw\,$height/ih))/2" -c:v libx264 -crf 22 -preset slow -pix_fmt yuv420p -c:a libfdk_aac -vbr 3 -ac 2 -ar 44100 ${f%mp4}mkv;done

我需要连接使用不同设置编码的不同来源的视频,因此我使用这样的命令来首先调整输入视频的大小和重新编码:

for f in *.mkv;do ffprobe $f|&grep -q '1: Audio'||{ ffmpeg -i $f -f lavfi -i anullsrc -c:a libfdk_aac -shortest -c:v copy temp-$f;mv temp-$f $f; };done

有些视频没有音频通道,所以我不得不使用这样的命令为它们添加无声音频通道:

mkvmerge -o output.mkv $(printf %s\\n *.mkv|sed '1!s/^/+/')

然后我使用如下命令连接视频:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.