使用 FFMPEG 有效地连接和淡入淡出 .ts 文件

Efficiently concatenating & crossfading .ts files with FFMPEG

我想高效将多个传输文件交叉淡化到一个 m4a 文件中。这意味着分割文件,在连续传输文件的 beginning/end 处交叉淡入淡出 3 秒,然后将子集和新交叉淡入淡出的重叠连接在一起,以最小化 decoding/re-encoding.

Gyan provides a solution 正确交叉淡入淡出音频文件列表。我能够修改此程序以生成适合我目的的正确输出 m4a 文件。 但是,这需要重新编码每个音频文件的整体。要交叉淡化 10 个音频文件(每个文件的长度在 3-5 分钟之间),此解决方案运行 8-12 秒,这不符合为我的真实 time/live 流用例提供此音频的标准。

为了避免这种 decoding/recoding 瓶颈,我编写了一个程序来分割每个传输文件,淡入淡出重叠部分,然后连接所有相关组件。对于上面的 10 个音频文件案例,该程序在 1-2 秒内运行,这确实符合我的实时用例。

以下是连接两个 10 秒传输文件的缩写版本 (a.tsb.ts)。这些文件是 AAC 编码的,单声道的,并且只包含不同频率的正弦波。

ffmpeg -i a.ts -map 0 -f segment -segment_times 7 -c:a copy a_%d.ts
ffmpeg -i b.ts -map 0 -f segment -segment_times 3 -c:a copy b_%d.ts

ffmpeg -i a_1.ts -i b_0.ts -filter_complex acrossfade=d=3:c1=qua:c2=qua xfade.m4a
ffmpeg -i xfade.m4a -c:a copy xfade.ts

ffmpeg -i "concat:a_0.ts|xfade.ts|b_1.ts" -c:a copy out.m4a

请注意,交叉淡化两个重叠的 ~3 秒文件(a_1.tsb_0.ts)需要写入 .m4a,然后再转换回 .ts。尝试交叉淡入淡出 -> .ts,或连接 .ts 和 .m4a 文件导致无法播放音频或 out.m4a 文件中的音频丢失。

此程序生成的音频文件几乎是正确的(17 秒的音频,两个文件之间的交叉淡入淡出 3 秒)。下面是波形图。顶部是常规交叉淡入淡出产生的波形,带有整个文件的编码(Gyan 的解决方案)以供比较。下面是我程序制作的

请注意,在交叉淡入淡出的边界处引入了 'artifacts'。这些小间隙导致音频文件在交叉淡入淡出开始时音量 "dip",并且在交叉淡入淡出结束时有咔嗒声。对于常规的、低效的交叉淡入淡出,这些伪影不存在。

我的问题是:

感谢所有阅读本文的人。

编辑:我应该补充一点,无论使用什么片段时间/音频文件作为输入,这些伪影都会存在。这些工件似乎也是确定性的;对于完全相同的输入,它们也会在完全相同的时间出现。

音频编码器使用一种叫做 "bit reservoir" 的东西,这意味着不能连接单个帧,因为它们可能需要来自另一个帧中的存储库的位。为了 bootstrap 这个过程,一些编解码器使用了一种叫做 priming samples 的东西。这些样本构成了一个虚拟框架来填充钻头储层。长话短说,无缝连接音频意味着前一帧和下一帧必须就水库的状态和内容达成一致。有一些技术可以解决这个问题,但它们都需要重新编码。

你的例子中的差距是你切断的水库中丢失的位 and/or 新编码的启动样本。

TLDR。你是 SOL。