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)