Search code examples
ffmpegaudio-streamingaudio-processing

FFMPEG Recode all audio streams while keeping originals


I am trying to add a additional set of audio tracks into some video files, as part of a automated process. I would like to keep all the original audio tracks and have a second re-coded copy.

What I have been using is:

ffmpeg -i file
-map 0:v -codec:v copy
-map 0:a -codec:a copy
-map 0:a:0 -codec:a:0 aac -strict experimental ...(Bitrate, filters etc all with :a:0)
-map 0:s -codec:s copy
output file

However I can't work out how to change this to handle input files that have multiple audio tracks as it will only convert the first.

If I change the :a:0 to :a on the codec line it produces the extra copy I need but overrides the copy codec for the original copy.

Any ideas anyone?


Solution

  • Two ways to do this.

    First uses a single command but can get long. Idea is to conditionally map audio streams upto the maximum possible streams a file may have. Not elegant but will get the job done.

    ffmpeg -i in.mp4
              -c copy
              -map 0:v
              -map 0:a:0? -c:a:0 copy
              -map 0:a:0? -c:a:1 aac
              -map 0:a:1? -c:a:2 copy
              -map 0:a:1? -c:a:3 aac
              -map 0:a:2? -c:a:4 copy
              -map 0:a:2? -c:a:5 aac
              -map 0:a:3? -c:a:6 copy
              -map 0:a:3? -c:a:7 aac
    out.mp4
    

    Second method transcodes all audio tracks and pipes it to another ffmpeg execution for copying. With this method, you have less flexibility with stream order in the final output.

    ffmpeg -i in.mp4 -c:a aac -map 0:a -f nut - |
      ffmpeg -i - -i in.mp4 -c copy -map 1 -map 0 out.mp4