具有数百次剪切的 ffmpeg 性能 (atrim)

dra*_*kon 2 python audio ffmpeg

我有音频文件(想想〜2h),我想从中剪出很多片段(500+)和一个像这样的ffmpeg命令:

['ffmpeg', '-i', 'pipe:', '-filter_complex', 
'[0]atrim=end=30.69:start=0.0[s0];
 [0]atrim=end=34.31:start=31.18[s1];
 [0]atrim=end=38.65:start=34.43[s2]; 
 (... hundreds more)
 [s37][s38][s39][s40][s41]concat=a=1:n=42:v=0[s42]', '-map', '[s42]']
Run Code Online (Sandbox Code Playgroud)

使用 ffmpeg-python 构建的流映射:

  Stream #0:0 (mp3float) -> atrim
  (... hundreds more)
  Stream #0:0 (mp3float) -> atrim
  concat -> Stream #0:0 (libmp3lame)
Run Code Online (Sandbox Code Playgroud)

现在,这按预期工作,但在本地处理我拥有的文件大约需要 10 分钟,而当我将其部署到云中的某个服务器时,大约需要一个小时。显然,这绝对取决于机器,我肯定会缩放速度,但我也想知道是否有办法加快 ffmpeg 本身的处理速度。

感谢您的指点!

Leo*_*eon 6

ffmpeg为什么要通过管道传送文件?如果您按路径提供输入,ffmpeg则将能够在文件中查找并快速跳过必须删除的片段,而使用管道输入时,它别无选择,只能顺序扫描整个输入。

此外,当使用文件输入时,您可以利用带有流复制的解concat复用器,从而显着节省解码和重新编码的时间。

对于您的示例,concat 解复用器的输入应如下所示(请注意,不同的片段使用相同的文件名):

切断连接

ffconcat version 1.0

file input.mp3
inpoint 0.0
outpoint 30.69

file input.mp3
inpoint 31.18
outpoint 34.31

...
Run Code Online (Sandbox Code Playgroud)

ffmpeg命令行:

ffmpeg -i cut.ffconcat -codec copy cut.mp3
Run Code Online (Sandbox Code Playgroud)

在我的实验中(从 42 分钟长的 mp3 文件中剪切 250 个 5 秒片段),运行时间差异超过 3 倍:连续解复用器 + 流复制方法花费了 36 秒,而atrim+concat过滤器解决方案花费了 110 秒。

但请注意,使用连续解复用器方法时,剪切精度可能会更差(我怀疑它只会在音频帧边界处进行剪切)。