python3使用pydub切分音频文件
1.需求描述:编写python脚本,根据音频的静默切分音频,切分结果保存在音频同级文件夹res中,由py脚本生成exe应用,交付exe应用。
1.1切分文件
pydub.silence中split_on_silence方法可以根据音频的静默切文件,split_on_silence包含5个参数:
- audio_segment,待切分的音频文件
- min_silence_len,持续多少时间可认定为静默,默认值1000ms
- silence_thresh,声音大小小于多少时可认定为静默,默认值为-16dBFS
- keep_silence,为切分结果前端添加一段静默音频,默认值为100ms
- seek_step,两次切分处理的间隔时间,默认值1ms
音频切分文件 AudioSegmentation.py 代码如下:
from pydub import AudioSegment
import pydub
from pydub.silence import split_on_silence
import sys
import os
# 获取参数
audio_path = sys.argv[1]
min_silence_len = int(sys.argv[2])
silence_thresh = int(sys.argv[3])
# 创建结果保存目录
folder = os.path.split(audio_path)[0] + "\\res\\"
if not os.path.exists(folder):
os.mkdir(folder)
audio_type = os.path.splitext(audio_path)[-1][1:]
# 切分文件
audio_segment = AudioSegment.from_file(audio_path, format=audio_type)
list_split_on_silence = pydub.silence.split_on_silence(audio_segment, min_silence_len=min_silence_len,
silence_thresh=silence_thresh, keep_silence=0)
pydub.silence.split_on_silence()
for i in range(len(list_split_on_silence)):
new = list_split_on_silence[i]
save_name = folder+'%04d.%s' % (i, audio_type)
new.export(save_name, format=audio_type)
1.2生成exe文件
安装pyinstaller后,cmd使用指令pyinstaller -F AudioSegmentation.py
生成exe文件,生成的exe文件在dist文件夹下
exe文件使用指令例子:AudioSegmentation.exe 待切分文件.wav 200 -50
2.需求变更:切分后音频,需要保留前端的静默音频段,最后一个音频段保留后端静默音频段。生成json文件,文件格式如下
{
"FileName.wav": {
"StartPosition": 1000,
"EndPosition": 2000,
"Duration": 2400
}
}
- StartPosition,表示非静默音频段在切分后的音频段内的开始位置
- EndPosition,表示非静默音频段在切分后的音频段内的结束位置
- Duration,表示切分后的音频段的长度
2.1切分音频
pydub.silence中split_on_silence方法把静默音频段作为切分点,不会保留静默,所有不再使用该方法
pydub.silence中detect_nonsilent方法可以获取到非静默音频,即可知道所有非静默音频在原音频中的开始和结束位置,根据结束位置切分即可
detect_nonsilent相比于split_on_silence少了keep_silence,其余完全相同
音频切分文件 AudioSegmentation.py 代码如下:
from pydub import AudioSegment
import pydub
from pydub.silence import split_on_silence
import json
import sys
import os
# 获取参数
audio_path = sys.argv[1]
min_silence_len = int(sys.argv[2])
silence_thresh = int(sys.argv[3])
# 创建记过保存目录
folder = os.path.split(audio_path)[0] + "\\res\\"
if not os.path.exists(folder):
os.mkdir(folder)
audio_type = os.path.splitext(audio_path)[-1][1:]
# 切分文件
audio_segment = AudioSegment.from_file(audio_path, format=audio_type)
not_silence_ranges = pydub.silence.detect_nonsilent(audio_segment, min_silence_len=min_silence_len,
silence_thresh=silence_thresh, seek_step=1)
last_end_position = 0 # 上个非静默音频段结束位置,初始为0
json_dict = {}
for index in range(len(not_silence_ranges)):
json_dict2 = {}
current_end_position = round((not_silence_ranges[index][1])) # 获取当前非静默音频段结束位置
if index == len(not_silence_ranges)-1:
new = audio_segment[last_end_position:]
else:
new = audio_segment[last_end_position:current_end_position]
file_name = '%04d.%s' % (index, audio_type)
save_name = folder+'/'+file_name
new.export(save_name, format=audio_type)
last_end_position = current_end_position
# 获取非静默音频段在当前音频段的开始位置和结束位置,又调用了一次detect_nonsilent方法有点麻烦,暂时没想到更好的方法
new_no_silence = pydub.silence.detect_nonsilent(new, min_silence_len=min_silence_len, silence_thresh=silence_thresh,
seek_step=1)
new_start_position = new_no_silence[0][0]
new_end_position = new_no_silence[0][1]
json_dict2["StartPosition"] = new_start_position
json_dict2["EndPosition"] = new_end_position
json_dict2["Duration"] = int(new.duration_seconds*1000)
json_dict[file_name] = json_dict2
res = json.dumps(json_dict, indent=4, ensure_ascii=False)
f_res = open(folder+r"\res.json", "w", encoding='utf8')
f_res.write(res)