利用 AudioSegment 库抽出音轨,肯定时间段距离采样音频的 dBFS,如果小于阈值(个别认为小于 -50 为静音),当然还存在负无穷的景象须要判断。
def audio_silence_check_service(video_location):
download_video_to_local(location=video_location, video_filename=video_filename)
extract_audio_result = extract_audio_from_video(video_filename, audio_filename)
is_exist_silence = False
silence_desc = ''
silence_detect_result = []
if extract_audio_result:
silence_detect_result = silence_detect(audio_filename)
for silence_chunk in silence_detect_result.get('silence_result'):
if int(silence_chunk[1]) - int(silence_chunk[0]) > int(int(silence_detect_result.get('audio_duration')) / 3):
silence_desc += f'{silence_chunk[0]}~{silence_chunk[1]},'
if silence_desc:
silence_desc += 'ms 存在静音'
is_exist_silence = True
else:
is_exist_silence = True
silence_desc = f'{qipuid} 未获取到音轨'
logger_error(silence_desc)
return is_exist_silence, silence_desc, silence_detect_result
def silence_detect(audio_file, silence_threshold=-50, chunk_size=10):
sound = AudioSegment.from_file(audio_file, format="wav")
assert chunk_size > 0
silence_chunks = list()
silence_chunks_start_ms = -1
sound_duration = len(sound)
for current_ms in range(0, sound_duration, chunk_size):
current_ms_chunks_dBFS = sound[current_ms: current_ms + chunk_size].dBFS
if current_ms_chunks_dBFS < silence_threshold or current_ms_chunks_dBFS == -inf:
if silence_chunks_start_ms == -1:
silence_chunks_start_ms = current_ms
else:
if current_ms <= sound_duration <= current_ms + chunk_size:
silence_chunks.append([silence_chunks_start_ms, sound_duration])
silence_chunks_start_ms = -1
else:
if silence_chunks_start_ms != -1:
silence_chunks.append([silence_chunks_start_ms, current_ms])
silence_chunks_start_ms = -1
return {'audio_duration': sound_duration, 'silence_result': silence_chunks}
def download_video_to_local(location, video_filename):
res = get(location)
with open(video_filename, r'wb') as f:
f.write(res.content)