使用 PyDub 去除波形文件开头和结尾的静音
remove silence at the beginning and at the end of wave files with PyDub
如何使用 PyDub 去除波形文件开头和结尾的静音?
我想我应该逐段访问并检查它是否静音(但我做不到):/
例如我有一个在开头、结尾或两者都有静音的波形文件(如下所示),我想删除文件开头和结尾的静音:
例如我想导入它
sound = AudioSegment.from_wav(inputfile)
循环每个声音样本以检查它是否无声并标记自波开始时的最后一个无声样本(标记 1),
然后在波形结束前到达最后一个样本 (marker2),我可以从两个标记导出新的声音文件
newsound = sound[marker1:marker2]
newsound.export(outputfile, format="wav")
我建议您以至少 10 毫秒的块为单位进行循环,以便更快地完成(更少的迭代),而且因为单个样本实际上并没有 "loudness"。
声音是振动,所以至少需要2个样本来检测是否真的有声音,(但那只能告诉你高频)。
无论如何……像这样的东西可以工作:
from pydub import AudioSegment
def detect_leading_silence(sound, silence_threshold=-50.0, chunk_size=10):
'''
sound is a pydub.AudioSegment
silence_threshold in dB
chunk_size in ms
iterate over chunks until you find the first one with sound
'''
trim_ms = 0 # ms
assert chunk_size > 0 # to avoid infinite loop
while sound[trim_ms:trim_ms+chunk_size].dBFS < silence_threshold and trim_ms < len(sound):
trim_ms += chunk_size
return trim_ms
sound = AudioSegment.from_file("/path/to/file.wav", format="wav")
start_trim = detect_leading_silence(sound)
end_trim = detect_leading_silence(sound.reverse())
duration = len(sound)
trimmed_sound = sound[start_trim:duration-end_trim]
您可以使用此代码:
from pydub.silence import detect_nonsilent
def remove_sil(path_in, path_out, format="wav"):
sound = AudioSegment.from_file(path_in, format=format)
non_sil_times = detect_nonsilent(sound, min_silence_len=50, silence_thresh=sound.dBFS * 1.5)
if len(non_sil_times) > 0:
non_sil_times_concat = [non_sil_times[0]]
if len(non_sil_times) > 1:
for t in non_sil_times[1:]:
if t[0] - non_sil_times_concat[-1][-1] < 200:
non_sil_times_concat[-1][-1] = t[1]
else:
non_sil_times_concat.append(t)
non_sil_times = [t for t in non_sil_times_concat if t[1] - t[0] > 350]
sound[non_sil_times[0][0]: non_sil_times[-1][1]].export(path_out, format='wav')
pydub
自从第一次提出这个问题后可能已经更新,但这是我用来 trim 尾随和前导沉默的代码:
from pydub import AudioSegment
from pydub.silence import detect_leading_silence
trim_leading_silence: AudioSegment = lambda x: x[detect_leading_silence(x) :]
trim_trailing_silence: AudioSegment = lambda x: trim_leading_silence(x.reverse()).reverse()
strip_silence: AudioSegment = lambda x: trim_trailing_silence(trim_leading_silence(x))
sound = AudioSegment.from_file(file_path_here)
stripped = strip_silence(sound)
来自 pydub.silence
的 detect_leading_silence
为您提供了索引,您可以使用这些索引对加载的 AudioSegment
进行切片。基本上,您可以将 AudioSegment
、trim 反转,然后再将其反转为 trim 尾随静音。从两端剥离沉默等同于 trim 前导和尾随沉默。
请注意,如果加载的 AudioSegment
无声或在 trim 操作后变得无声,strip_silence
应该引发 IndexError
。
我上次查看时,默认块大小为 10 毫秒,默认静音阈值为 -50 dBFS。
我的pydub
版本是0.25.1,我的ffmpeg
版本是4.3.1。
如何使用 PyDub 去除波形文件开头和结尾的静音?
我想我应该逐段访问并检查它是否静音(但我做不到):/
例如我有一个在开头、结尾或两者都有静音的波形文件(如下所示),我想删除文件开头和结尾的静音:
例如我想导入它
sound = AudioSegment.from_wav(inputfile)
循环每个声音样本以检查它是否无声并标记自波开始时的最后一个无声样本(标记 1), 然后在波形结束前到达最后一个样本 (marker2),我可以从两个标记导出新的声音文件
newsound = sound[marker1:marker2]
newsound.export(outputfile, format="wav")
我建议您以至少 10 毫秒的块为单位进行循环,以便更快地完成(更少的迭代),而且因为单个样本实际上并没有 "loudness"。
声音是振动,所以至少需要2个样本来检测是否真的有声音,(但那只能告诉你高频)。
无论如何……像这样的东西可以工作:
from pydub import AudioSegment
def detect_leading_silence(sound, silence_threshold=-50.0, chunk_size=10):
'''
sound is a pydub.AudioSegment
silence_threshold in dB
chunk_size in ms
iterate over chunks until you find the first one with sound
'''
trim_ms = 0 # ms
assert chunk_size > 0 # to avoid infinite loop
while sound[trim_ms:trim_ms+chunk_size].dBFS < silence_threshold and trim_ms < len(sound):
trim_ms += chunk_size
return trim_ms
sound = AudioSegment.from_file("/path/to/file.wav", format="wav")
start_trim = detect_leading_silence(sound)
end_trim = detect_leading_silence(sound.reverse())
duration = len(sound)
trimmed_sound = sound[start_trim:duration-end_trim]
您可以使用此代码:
from pydub.silence import detect_nonsilent
def remove_sil(path_in, path_out, format="wav"):
sound = AudioSegment.from_file(path_in, format=format)
non_sil_times = detect_nonsilent(sound, min_silence_len=50, silence_thresh=sound.dBFS * 1.5)
if len(non_sil_times) > 0:
non_sil_times_concat = [non_sil_times[0]]
if len(non_sil_times) > 1:
for t in non_sil_times[1:]:
if t[0] - non_sil_times_concat[-1][-1] < 200:
non_sil_times_concat[-1][-1] = t[1]
else:
non_sil_times_concat.append(t)
non_sil_times = [t for t in non_sil_times_concat if t[1] - t[0] > 350]
sound[non_sil_times[0][0]: non_sil_times[-1][1]].export(path_out, format='wav')
pydub
自从第一次提出这个问题后可能已经更新,但这是我用来 trim 尾随和前导沉默的代码:
from pydub import AudioSegment
from pydub.silence import detect_leading_silence
trim_leading_silence: AudioSegment = lambda x: x[detect_leading_silence(x) :]
trim_trailing_silence: AudioSegment = lambda x: trim_leading_silence(x.reverse()).reverse()
strip_silence: AudioSegment = lambda x: trim_trailing_silence(trim_leading_silence(x))
sound = AudioSegment.from_file(file_path_here)
stripped = strip_silence(sound)
来自 pydub.silence
的 detect_leading_silence
为您提供了索引,您可以使用这些索引对加载的 AudioSegment
进行切片。基本上,您可以将 AudioSegment
、trim 反转,然后再将其反转为 trim 尾随静音。从两端剥离沉默等同于 trim 前导和尾随沉默。
请注意,如果加载的 AudioSegment
无声或在 trim 操作后变得无声,strip_silence
应该引发 IndexError
。
我上次查看时,默认块大小为 10 毫秒,默认静音阈值为 -50 dBFS。
我的pydub
版本是0.25.1,我的ffmpeg
版本是4.3.1。