Замена аудио в готовом медиа файле с помощью FFmpeg

Ярослав Семенов
3 min readDec 17, 2018

Иногда случаются ситуации, когда ты экспортнул длиииинный видос, но накосячил со звуком. Ну или же у нас есть готовый файл с черновым звуком, а звукорежиссёр прислал сведённое аудио. Как заменить аудио в уже готовом файле? Ответ, как обычно — FFmpeg)

На всякий случай — вот ссылки на то, как установить FFmpeg на Windows и OS X, и на статью про графическую оболочку для Windows. Про базовые команды FFmpeg можно почитать тут.

Тут стоит упомянуть про синтаксис, который я использую в статье: -с:v — это сокращение от -codec:video, соответственно -c:a — это -codec:audio. Также есть промежуточные варианты: -vcodec и -acodec. Если вы только начали изучать ffmpeg, то возможно использование несокращённых вариантов команд сделают вашу жизнь чуточку легче)

Предварительно можно экспортнуть аудио-дорожку в формат, подходящий для медиа-контейнера выходного файла. Если вы экспортировали в mov или mp4 с кодеком видео H.264, то выбирайте кодек для аудио aac. Также вы можете экспортировать несжатый WAV или AIFF, и доверить перекодировку звука в правильный формат FFmpeg-у. В этом случае на этапе объединения файлов надо писать не -с copy (это скопирует и видео и аудио потоки без изменений в выходной файл), а -c:v copy (это скопирует только видео поток без изменений, а аудио автоматически сконвертируется в подходящий формат).

Перейдём к основным действиям. Есть два способа: один лёгкий для запоминания, но в два прохода, а второй — сложнее понять и запомнить, но соответственно в один проход)

Способ 1

Итак, у нас есть файла: “видео+косячный_звук” и “правильный звук”. Первым делом удалим* из первого файла аудио-дорожку (*из исходного файла ничего не удалится, будет создан новый файл без аудио):

ffmpeg -i <input_wrongsound.mp4> -c:v copy -an <output_nosound.mp4>

Параметр -c:v copy скопирует исходное видео, а -an удалит аудио. Теперь нам надо объединить видео без звука и правильную аудио-дорожку.

ffmpeg -i <output_nosound.mp4> -i <goodsound.aac> -c copy <output_good.mp4>

-c copy скопирует и видео и аудио потоки из исходных файлов в финальный файл.

В иллюстрации я использую -c:v copy и -c:a copy для наглядности, в реальной жизни их обычно заменяют просто на -c copy.

Если у нас звук в WAV/AIFF/другом неподходящем формате, то строка будет такая:

ffmpeg -i <output_nosound.mp4> -i <goodsound.wav> -c:v copy <output_good.mp4>

-c:v copy скопирует видеопоток, а аудиопоток из wav будет перекодирован в aac.

Способ 2

Воспользуемся параметром map

ffmpeg -i <input_wrongsound.mp4> -i <goodsound.aac> -map 0:0 -map 1:0 -c copy <output_good.mp4>

Тут мы на вход FFmpeg подаем сразу два файла, и чтобы он понял, какие потоки видео и аудио откуда брать, мы используем параметр map. Как это работает? Рассмотрим наши файлы в этой команде.

В выводе ffmpeg можно увидеть подобные строки:

Input #0, ..., from 'C:\temp\input_wrongsound.mp4':
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661)...
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D)...
...
Input #1, aac, from 'C:\temp\goodsound.aac':
Stream #1:0: Audio: aac (LC)

Упрощенно, input_wrongsound.mp4 имеет два потока:

Stream #0:0 - видео
Stream #0:1 - аудио

goodsound.aac имеет только один поток:

Stream #1:0 - аудио

map x:y берёт из файла x поток y и пробрасывает его на дальнейшую обработку. Так как большинство нумераций объектов в мире программистов начинаются с нуля, то -map 0:0 возьмёт из первого файла (map 0:0) input_wrongsound.mp4 первый поток (map 0:0) — в нашем случае это видео, а -map 1:0 возьмёт из второго файла (map 1:0) первый поток (map 1:0) — правильное аудио. Дальнейшая обработка у нас отсутствует, и видео и аудио поток будут скопированы в выходной файл (-c copy).

Если у нас звук в WAV/AIFF, то строка будет такая:

ffmpeg -i <input_wrongsound.mp4> -i <goodsound.wav> -map 0:0 -map 1:0 -c:v copy <output_good.mp4>

Таким образом мы можем быстро заменить аудио в готовом медиа файле, не занимаясь долгим экспортом из монтажки. Ох, сколько бы мне это времени бы сэкономило, узнай я об этой функции ffmpeg лет 5 назад)

Есть вопросы? Вступайте в наш чат: https://t.me/ru_montage

--

--