Making ffmpeg process first audio stream differently than all others
I'm trying to write a command such that ffmpeg executes a given instruction for the first audio stream in a file and a different instruction for any and all others. In the test case below, for example, I want the first stream copied to the output file and all others converted to mono. If I write it this way
ffmpeg -i INPUT -map 0 -c copy -map 0:a:0 -c:a:0 copy -map -0:a:0? -c:a libfdk_aac -ac 1 OUTPUT
the first audio stream is ignored when the mapping is overridden later in the command line. But if I move the instruction for that stream to after the others'
ffmpeg -i INPUT -map 0 -c copy -map -0:a:0? -c:a libfdk_aac -ac 1 -map 0:a:0 -c:a:0 copy OUTPUT
it's no longer ignored, but becomes the last audio stream in the file. I know I'm close here; I just can't see what I'm doing wrong.
Use
ffmpeg -i INPUT -map 0 -c copy -c:a libfdk_aac -c:a:0 copy -ac 1 OUTPUT
You only need to map a stream once. It's the order of the codec options that has to be correctly set. First set to copy all streams. Then override the audio setting with the encoder but then reset the first audio to copy again.
Here's the generic logic that applies to options which take stream specifiers e.g. -b:v, -c:a -map 0:s:1
..etc
Let's say you have three video streams and three audio streams, mapped in the order of the first column. The table below shows what happen when you apply options in the order of the first row:
(stream) -c copy -c:a:0 aac -c:a libfdk_aac -c:4 mp3
0:v:0 copy copy copy copy
0:v:1 copy copy copy copy
0:v:2 copy copy copy copy
0:a:0 copy aac libfdk_aac libfdk_aac
0:a:1 copy copy libfdk_aac mp3
0:a:2 copy copy libfdk_aac libfdk_aac