pydub 可以设置 maximum/minimum 音量吗?
Can pydub set the maximum/minimum volume?
如题,我可以给maximum/minimum音量设置一个值,即输出的音频文件不会太大声或太小声吗? (不是正常化,我只是想把特定的音量调到正常,如下图。)
Loudness 有点复杂 - 一个简单的解决方案是使用一种更简单的方法(如 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)
如题,我可以给maximum/minimum音量设置一个值,即输出的音频文件不会太大声或太小声吗? (不是正常化,我只是想把特定的音量调到正常,如下图。)
Loudness 有点复杂 - 一个简单的解决方案是使用一种更简单的方法(如 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)