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

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

Ярослав Семёнов

Иногда случаются ситуации, когда ты экспортнул длиииинный видос, но накосячил со звуком. Ну или же у нас есть готовый файл с черновым звуком, а звукорежиссёр прислал сведённое аудио. Как заменить аудио в уже готовом файле? Ответ, как обычно - 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 скопирует и видео и аудио потоки из исходных файлов в финальный файл.

Обратите внимание! Вместо <input_wrongsound.mp4>, <output_nosound.mp4>, <goodsound.aac> надо прописывать полный путь до файлов на вашем диске! Команда должна выглядеть примерно так, только с вашими путями:
ffmpeg -i D:\Source\input_wrongsound.mp4 -c:v copy -an
D:\Source\output_nosound.mp4
Так как бывают пути с пробелами, я рекомендую перетаскивать файлы в окошко командной строки, чтобы сразу вставились правильные пути с экранированием пробелов и других спецсимволов.

В иллюстрации ниже я использую -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 (ffmpeg кодирует по умолчанию видео в H.264 и AAC, если не указаны параметры кодирования).


Если звук надо перекодировать в определенный кодек, то строка будет такая:

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

Соответственно, после -c:a надо прописать необходимый аудиокодек.


Способ 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>

Так же можно использовать -map 0:v и -map 1:a для вытаскивания потоков видео и аудио соответственно.

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


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


Report Page