Озвучка видео ИИ-голосом через FFmpeg
FFmpeg умеет наложить любой звук на любое видео, но естественную речь не делает: его необязательный фильтр flite звучит как робот, и в большинстве сборок его нет. Практичный путь — два шага: озвучить сценарий движком синтеза речи, а затем дать FFmpeg положить этот звук на видео.
В руководстве первый шаг делается бесплатным движком SuperClonica офлайн, а для второго даны команды FFmpeg. Мы прогнали каждую команду на тестовом видео: видеопоток не перекодируется (-c:v copy), поэтому даже длинные ролики обрабатываются за секунды.
Озвучьте сценарий
Один раз установите движок командой python -m pip install superclonica-cpu; модель скачается при первом запуске, дальше всё работает офлайн. Сохраните дикторский текст в файл и озвучьте его:
superclonica --text-file script.txt --voice M3 --lang ru --normalize --output voice.wav
Сначала выберите голос на его странице в каталоге: фраза от 30 до 100 символов озвучивается бесплатно и без регистрации. Каждый голос говорит на 31 языке; поменяйте --lang, чтобы озвучить тот же сценарий по-английски, по-испански или по-немецки. Китайский пока не поддерживается.
Замените звуковую дорожку
Для записи экрана или ролика без звука возьмите картинку из видео, а звук — из озвучки:
ffmpeg -i video.mp4 -i voice.wav -map 0:v -map 1:a -c:v copy -c:a aac voiced.mp4
Видео сохраняет полную длину; если озвучка короче, дальше тишина. Не добавляйте здесь -shortest: при копировании потока он может зависнуть или обрезать картинку по длине голоса.
Наложите голос на музыку
Чтобы оставить исходный звук или музыку под дикторским текстом, приглушите их и смешайте:
ffmpeg -i video.mp4 -i voice.wav -filter_complex "[0:a]volume=0.25[music];[music][1:a]amix=inputs=2:duration=first:normalize=0[a]" -map 0:v -map "[a]" -c:v copy -c:a aac voiced.mp4
volume=0.25 оставляет музыку на четверть громкости, duration=first сохраняет длину видео, а normalize=0 не даёт amix вдвое приглушить голос.
Приглушайте музыку только во время речи
Сайдчейн-компрессор убавляет музыку, когда звучит голос, и возвращает её в паузах, как сделал бы монтажёр:
ffmpeg -i video.mp4 -i voice.wav -filter_complex "[1:a]asplit=2[v][key];[0:a][key]sidechaincompress=threshold=0.02:ratio=10:attack=20:release=400[music];[music][v]amix=inputs=2:duration=first:normalize=0[a]" -map 0:v -map "[a]" -c:v copy -c:a aac voiced.mp4
Увеличьте ratio, чтобы музыка проседала сильнее, и release, если она возвращается слишком резко.
Расставьте реплики по времени
Озвучьте каждую реплику в отдельный файл, задержите каждую до её момента в миллисекундах и смешайте все:
ffmpeg -i video.mp4 -i line1.wav -i line2.wav -filter_complex "[1:a]adelay=500:all=1[l1];[2:a]adelay=4000:all=1[l2];[0:a]volume=0.25[music];[music][l1][l2]amix=inputs=3:duration=first:normalize=0[a]" -map 0:v -map "[a]" -c:v copy -c:a aac voiced.mp4
Здесь первая реплика начинается на 0,5 с, вторая — на 4 с. Раз каждая реплика — отдельный файл, правка сценария означает переозвучку одной реплики, а не всей дорожки. Если субтитры уже есть, наше руководство «SRT в речь» соберёт дорожку по времени само.