Пакетное добавление или замена дорожек в AVI с помощью FFMPEG

Недавно возникла задача заменить в некотором количестве видео файлов (формат контейнера AVI) вторую звуковую дорожку. Изначально имеем AVI файл с одной видео и двумя звуковыми дорожками. Нужно извлечь второю дорожку и заменить её другой без перекодирований. Всё довольно просто, если бы видюшек не было более сотни))

Понятно, что «руками» менять всё это — большое извращение)
На помощь придёт известная консольная утилита FFMPEG. Однако, как её правильно использовать не всегда понятно. В сети много описаний, но работающего примера для поставленной цели найти мне не удалось.
Путём экспериментов, решение нашлось.

Итак, создадим пакетный файл (bat) и пропишем несколько строк)

c:\tmp\ffmpeg.exe -i c:\tmp\01.avi -map 0.0 -vcodec copy -map 0.1 -acodec copy c:\tmp\avi\01.avi
c:\tmp\ffmpeg.exe -i c:\tmp\01.avi -vn -map 0.2 -acodec copy c:\tmp\mp3_old\01.mp3
c:\tmp\ffmpeg.exe -i c:\tmp\avi\01.avi -map 0.0 -vcodec copy -map 0.1 -acodec copy -i c:\tmp\mp3\01.mp3 c:\tmp\01.remux.avi -map 1.0 -acodec copy -newaudio

Первая строка удаляет из исходного файла «c:\tmp\01.avi» вторую звуковую дорожку и сохраняет временные файл «c:\tmp\avi\01.avi».
Вторая строчка извлекает из исходного файла «c:\tmp\01.avi» вторую звуковую дорожку (она мне нужна для дальнейшей работы, поэтому я её сохранил, но это не обязательно)
Третья строчка добавляет новую звуковую дорожку «c:\tmp\mp3\01.mp3» во временные файл «c:\tmp\avi\01.avi».

А теперь то, что я нигде найти не смог.
Нужно обратить внимание, что опция -map указывает на номер потока в файле. Нумерация в видео файлах и звуковых разная.

В примере:
-map 0.0 — это видео поток в файле «c:\tmp\avi\01.avi»,
-map 0.1 — это аудио поток в файле «c:\tmp\avi\01.avi»,
т.е. в видео файлах нумерация потоков идёт в виде «0.номер потока».

А вот в звуковом файле нумерация иная:
-map 1.0 — это собственно поток звука в файле «c:\tmp\mp3\01.mp3».

Далее, опция -map указывает с каким потоком мы работаем, а вот последовательность её вывозов в строке
определяет последовательность добавления потоков в итоговый файл.
т.е. у нас сначала вызывается в строке -map 0.0, потом -map 0.1 и только потом -map 1.0 …
именно это и опредяляет то, в какой последовательности потоки пойдут в итоговый файл

— первый будет исходное видео,
— второй звук из исходного видео,
— третий звук из внешнего mp3 файла.

Командная строка ffmpeg является не комулятивной, т.е. последовательность указания команд ВАЖНА!

И именно поэтому нужно записывать именно так:
«-i c:\tmp\mp3\01.mp3 c:\tmp\01.remux.avi -map 1.0 -acodec copy -newaudio»

т.е. сначала указывам файл новой дорожки, потом имя итогового файла и только потом, как ни странно,
опции для добавляемой новой дорожки.
Почему сделано так, не знаю. На мой взгляд не логично, но так уж есть.
Если указать иначе, например так, как выглядело бы логичнее:

«-i c:\tmp\mp3\01.mp3 -map 1.0 -acodec copy -newaudio c:\tmp\01.remux.avi»

получите ошибку «не указан итоговый файл» …

Пример работает на версии FFMPEG:
FFmpeg version SVN-r22716, Copyright (c) 2000-2010 the FFmpeg developers built on Mar 29 2010 06:05:44 with gcc 4.4.2

About the Author