В качестве заголовка, могу ли я установить значение максимальной/минимальной громкости, то есть в выходном аудиофайле не будет слишком громко или слишком тихо? (Не нормализовать, я просто хочу настроить конкретную громкость на нормальную, как на фото ниже.)
Может ли pydub установить максимальную/минимальную громкость?
Ответы (2)
Громкость немного сложна. Простое решение состоит в измерении одним из более простых методов, таких как dBFS и установите усиление для всего вашего аудио, чтобы оно соответствовало.
sounds = [audio_segment1, audio_segment2, audio_segment3, audio_segment4]
def set_loudness(sound, target_dBFS):
loudness_difference = target_dBFS - sound.dBFS
return sound.apply_gain(loudness_difference)
# -20dBFS is relatively quiet, but very likely to be enough headroom
same_loudness_sounds = [
set_loudness(sound, target_dBFS=-20)
for sound in sounds
]
Одним из усложняющих факторов является то, что некоторые из ваших звуков могут иметь продолжительные части тишины или даже просто очень тихие части. Это понизит среднее значение, и вам, возможно, придется написать более сложное измерение громкости. Опять же, простой способ: вы можете разрезать звук на более короткие фрагменты и просто использовать самый громкий, предполагая, что весь ваш звук длится 15 минут, мы можем взять фрагменты по 1 минуте:
from pydub.utils import make_chunks
def get_loudness(sound, slice_size=60*1000):
return max(chunk.dBFS for chunk in make_chunks(sound, slice_size))
# ...and replace set_loudness() in above example with…
def set_loudness(sound, target_dBFS):
loudness_difference = target_dBFS - get_loudness(sound)
return sound.apply_gain(loudness_difference)
Это то, что я делаю, и это хорошо работает для меня. Недостатком является плохая производительность, если sample_rate слишком мал.
from pydub import AudioSegment
from pydub.utils import make_chunks
def match_target_amplitude(sound, target_dBFS):
change_in_dBFS = target_dBFS - sound.dBFS
return sound.apply_gain(change_in_dBFS)
def sound_slice_normalize(sound, sample_rate, target_dBFS):
def max_min_volume(min, max):
for chunk in make_chunks(sound, sample_rate):
if chunk.dBFS < min:
yield match_target_amplitude(chunk, min)
elif chunk.dBFS > max:
yield match_target_amplitude(chunk, max)
else:
yield chunk
return reduce(lambda x, y: x + y, max_min_volume(target_dBFS[0], target_dBFS[1]))
sound = AudioSegment.from_mp3("vanilla_sky.mp3")
normalized_db = min_normalized_db, max_normalized_db = [-32.0, -18.0]
sample_rate = 1000
normalized_sound = sound_slice_normalize(sound, sample_rate, normalized_db)