首页 > 解决方案 > 在 Python 中为子处理调用 FFMPEG 应用循环

问题描述

假设我有一个长度为 00:04:00(240 秒)的音频 mp3 文件。我想在 2 秒的范围内提取所述文件的各个部分,所以它将是:

File_01 00:00:00-00:00:02、File_02 00:00:02-00:00:04、File_03 00:00:04-00:00:06 ... File_120 00:03:58-00: 04:00。

我正在使用python,调用模块子进程来运行ffmpeg函数。我做了什么,我只是把它放在这样的循环中:

count = 0
count2 = 2
count3 = 1
while count2 <= audio_length:
    ffmpeg = 'ffmpeg -i input.mp3 -c copy -ss %d -to %d output%d.wav' % (count, count2, count3)
    subprocess.call(ffmpeg, shell=True)
    count = count + 2
    count2 = count2 + 2
    count3 = count3 + 1

但是,子流程部分花了很长时间,似乎卡住了。我搜索了一些见解,但我没有找到任何提到循环的内容。任何帮助表示赞赏。

标签: pythonaudioffmpegsubprocess

解决方案


如果您愿意使用外部库并使用离线音频文件,pydub具有内置实用程序来制作给定长度的可播放音频块。

make_chunk只需从 pydub.utils调用方法并提供块大小并导出可播放的音频块。

我拍摄了一个 34.6 秒长的文件,并分成 18 块,每块 2 秒。最后一个块可能少于 2 秒,具体取决于长度,在我的情况下为 0.6 秒。

工作代码:

from pydub import AudioSegment
from pydub.utils import make_chunks

audiofile = 'example.wav'

#set chunk duration in milliseconds
chunk_duration = 2000 #2 seconds

#Convert audio to audio segment
audio_segment = AudioSegment.from_wav(audiofile)
print("audio length in seconds={}".format(len(audio_segment) / float(1000.0)))

#make chunks
chunks = make_chunks(audio_segment, chunk_duration)

end = 0
for idx,chunk in enumerate(chunks):
    start = end
    end = start + (chunk_duration//1000)
    count = idx + 1
    print("Exporting File_{}_{}:{}.wav".format(count,start,end))
    chunk.export("File_{}_{}:{}.wav".format(count,start,end))

输出:

$python splitaudio.py 
audio length in seconds=34.6
Exporting File_1_0:2.wav
Exporting File_2_2:4.wav
Exporting File_3_4:6.wav
Exporting File_4_6:8.wav
Exporting File_5_8:10.wav
Exporting File_6_10:12.wav
Exporting File_7_12:14.wav
Exporting File_8_14:16.wav
Exporting File_9_16:18.wav
Exporting File_10_18:20.wav
Exporting File_11_20:22.wav
Exporting File_12_22:24.wav
Exporting File_13_24:26.wav
Exporting File_14_26:28.wav
Exporting File_15_28:30.wav
Exporting File_16_30:32.wav
Exporting File_17_32:34.wav
Exporting File_18_34:36.wav

推荐阅读