18+
реклама
18+
Бургер менюБургер меню

Александр Иванов – Python для творческих. Звук на твоей стороне. (страница 8)

18

"""Подгоняет пиковую громкость к заданному уровню."""

current_peak = np.max(np.abs(y))

if current_peak == 0:

return y

gain = target_peak / current_peak

return y * gain

# Нормализуем все части

intro = normalize_volume(intro, 0.9)

voice = normalize_volume(voice, 0.9)

outro = normalize_volume(outro, 0.9)

После такого выравнивания все три части будут иметь одинаковый пиковый уровень, и слушателю не придётся тянуться к регулятору громкости.

Собираем готовый эпизод подкаста

Теперь давайте соберём всё вместе в один большой скрипт, который принимает набор файлов и выдаёт готовый смонтированный эпизод. Этот скрипт можно будет использовать для каждого выпуска подкаста, меняя только имена файлов.

python

import librosa

import numpy as np

import soundfile as sf

def build_podcast(intro_file, voice_file, outro_file, output_file,

trim_start=180, trim_end=10,

silence_between=1.0,

target_sr=22050,

target_peak=0.9):

"""

Собирает эпизод подкаста из трёх файлов.

trim_start - сколько секунд отрезать от начала голосовой дорожки

trim_end - сколько секунд отрезать от конца голосовой дорожки

silence_between - длина паузы между частями в секундах

"""

print("=== Сборка эпизода ===")

# Загружаем

print("Загружаю файлы...")

intro, _ = librosa.load(intro_file, sr=target_sr)

voice, _ = librosa.load(voice_file, sr=target_sr)

outro, _ = librosa.load(outro_file, sr=target_sr)

# Обрезаем голос

start_sample = int(trim_start * target_sr)

end_sample = len(voice) - int(trim_end * target_sr)

voice = voice[start_sample:end_sample]

print(f"Голос после обрезки: {len(voice) / target_sr:.1f} сек")

# Нормализуем громкость

for arr in [intro, voice, outro]:

peak = np.max(np.abs(arr))

if peak > 0:

arr *= target_peak / peak

# Создаём паузу

silence = np.zeros(int(target_sr * silence_between))

# Склеиваем

final = np.concatenate([intro, silence, voice, silence, outro])

print(f"Финальная длина: {len(final) / target_sr:.1f} сек")

# Сохраняем

sf.write(output_file, final, target_sr)

print(f"Сохранено: {output_file}")

print("Готово!")

# Запускаем

build_podcast(

intro_file='intro.wav',

voice_file='raw_voice.wav',

outro_file='outro.wav',

output_file='episode_ready.wav',

trim_start=180,

trim_end=10,

silence_between=1.0

)

Запустите этот скрипт, указав свои файлы. Если у вас нет готовых джинглов для интро и аутро, не беда — можете пока использовать любые музыкальные фрагменты или даже тишину. Главное — понять процесс. Когда появятся настоящие джинглы, вы просто подставите их в скрипт, и всё будет работать.

Пакетная обработка: монтируем много файлов сразу