我正在尝试使用 numpy、struct 等各种模块在 python 中处理音频文件。但是我真的很难检测文件中的静音,比如哪里存在静音。我遇到的方法之一是在音频信号上滑动固定时间间隔的窗口并记录元素平方和。我是Python新手,几乎不知道它因此无法实现这个方法。
如果您对外部库开放,实现此目的的快速方法之一是使用 pydub。
pydub
有一个名为 silence 的模块,它具有方法 detect_silence
和 detect_nonsilent
可能对您的情况有用。
但是,唯一需要注意的是安静时间至少需要半秒。
下面是我尝试使用音频文件的示例实现。
但是,由于我的情况下沉默时间不到半秒,因此只有少数沉默范围是正确的。
您可能想尝试一下,通过调整
min_silence_len
和 silence_thresh
看看它是否适合您。
节目
from pydub import AudioSegment, silence
myaudio = AudioSegment.from_wav("a-z-vowels.wav")
silence = silence.detect_silence(myaudio, min_silence_len=1000, silence_thresh=-16)
silence = [((start/1000),(stop/1000)) for start,stop in silence] #convert to sec
print(silence)
结果
[(0, 1), (1, 14), (14, 20), (19, 26), (26, 27), (28, 30), (29, 32), (32, 34), (33, 37), (37, 41), (42, 46), (46, 47), (48, 52)]
为了获得更好的结果,请使用 dBFS
from pydub import AudioSegment,silence
myaudio = intro = AudioSegment.from_mp3("RelativityOverview.mp3")
dBFS=myaudio.dBFS
silence = silence.detect_silence(myaudio, min_silence_len=1000, silence_thresh=dBFS-16)
silence = [((start/1000),(stop/1000)) for start,stop in silence] #in sec
print(silence)
with wave.open(filename, 'r') as wav_file:
signal = wav_file.readframes(-1)
channels = [{} for _ in range(wav_file.getnchannels())]
fs = wav_file.getframerate()
signal = np.frombuffer(signal, dtype='int16')
def_sile, sile_upto = signal // 5, fs // 44
5,44,3可以是其他合适的整数
如果帧的值(下面的数据变量)大于 def_sile ,则该帧是安静的
如果该秒内的安静帧数大于 sile_upto,则该秒是安静的
tongsoframe = len(signal) // len(channels)
dodaiaudio = tongsoframe // fs
for index, datum in enumerate(signal):
if datum > def_sile:
mocthoigian: int = index//len(channels)//fs
if mocthoigian not in channels[index % len(channels)]:
channels[index % len(channels)][mocthoigian]: list = list()
channels[index % len(channels)][mocthoigian].append(datum)
silent_second_list = list()
for tg in range(dodaiaudio):
if tg not in channels[0]:
silent_second_list.append(tg)
continue
numberofframes: int = len(channels[0][tg])
# numberofframes là số frames có tín hiệu trên mốc im lặng trong giây thứ tg
if numberofframes < sile_upto:
# nếu numberofframes dưới mốc tối đa sile_upto -> nằm trong giới hạn im lặng
silent_second_list.append(tg)
print(silent_second_list)