FFmpeg合并视频时出现音频丢帧问题

4
我有一个mp4文件,想要将视频中的两个连续片段提取出来并渲染成单独的文件,最后将它们重新组合成原始视频。例如,对于我的视频video.mp4,我可以运行:
ffmpeg -i video.mp4 -ss 56 -t 4 out1.mp4
ffmpeg -i video.mp4 -ss 60 -t 4 out2.mp4

创建包含video.mp4的00:00:56到00:01:00的out1.mp4,以及包含00:01:00到00:01:04的out2.mp4。然而,后来我想要能够快速地重新组合它们(即不需要重新编码),因此我使用concat demuxer
ffmpeg -f concat -safe 0 -i files.txt -c copy concat.mp4

其中files.txt包含

file out1.mp4
file out2.mp4

理论上,这应该会将 video.mp4 的 00:00:56 到 00:01:04 部分还原出来,然而在拼接的位置总是会出现丢失音频帧的情况,产生非常不愉快的声音伪影,如果你愿意,可以称之为音频尖峰

missing audio frames

我曾尝试在视频的两个部分最初创建时使用async-af apad,但仍然面临相同的问题,并未在其他地方找到解决方案。我在多种不同的用例中都遇到了这个问题,因此希望这个简单的示例能揭示真正的问题。
1个回答

8
我建议您将片段导出为带有PCM音频的MOV格式,再将它们拼接在一起,但不重新编码音频。
ffmpeg -i video.mp4 -c:a pcm_s16le -ss 56 -t 4 out1.mov
...

然后

ffmpeg -f concat -safe 0 -i files.txt -c:v copy concat.mp4

抱歉,我之前使用了 -c copy 参数。但你的解决方案可行!能否解释一下原因或提供更多信息来源呢?我的假设是最初我将音频编码成 AAC 格式,并且压缩可能在边界处产生了明显效应。这是正确的吗? - Shaun
2
基于DCT的音频编解码器,如MP3、AAC,依赖于相邻的音频帧进行解码。在流的开始处,有一个用于此目的的引导帧。它具有负时间戳,因此在连接时,它的时间戳会与前一个文件的最终数据包发生冲突,并被连接操作删除。PCM是自包含的解码格式,因此不会受到这种影响。 - Gyan
@Gyan,难道没有MP4容器支持的“非DCT-Based”编解码器,这样我们就不需要仅为此更改容器了吗? - Proviste

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接