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)