user2513268 user2513268 - 5 months ago 98
Linux Question

FFmpeg not copying all audio streams

I'm having trouble getting ffmpeg to copy all audio streams from a .mp4 file. After hours of searching online, it appears this should copy all streams (as shown in example 4 here):

ffmpeg -i in.mp4 -map 0 -c copy out.mp4


in.mp4
contains 3 streams:


  • Video

  • Audio track 1

  • Audio track 2



out.mp4
(which should be identical to
in.mp4
) contains only 2 streams:


  • Video

  • Audio track 1



FFmpeg does appear to correctly identify all 3 streams, but doesn't copy all of them over. Output from FFmpeg:

Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Stream #0:2 -> #0:2 (copy)


Edit: Output from
ffmpeg -v 9 -loglevel 99 -i in.mp4
:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from in.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.36.100
Duration: 00:00:06.03, start: 0.000000, bitrate: 5582 kb/s
Stream #0:0(und), 1, 1/15360: Video: h264 (Main), 1 reference frame (avc1 /
0x31637661), yuv420p(tv, bt470bg/unknown/unknown, left), 1920x1080 (0x0) [SAR 1:
1 DAR 16:9], 0/1, 5317 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und), 1, 1/48000: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz,
stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream #0:2(und), 1, 1/48000: Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz,
stereo, fltp, 128 kb/s
Metadata:
handler_name : SoundHandler
Successfully opened the file.
At least one output file must be specified
[AVIOContext @ 0000000001c2b9e0] Statistics: 153350 bytes read, 2 seeks


Edit 2 (solved): I managed to find the correct syntax from this ticket. For any others that are interested, the correct syntax is:

ffmpeg -i in.mp4 -vcodec copy -c:a copy -map 0 out.mp4


This will copy all streams.

Answer

OK, I read pretty deep into the ffmpeg man page and found this which should be useful:

Note that currently each output stream can only contain channels from a single input stream; you can't for example use "-map_channel" to pick multiple input audio channels contained in different streams (from the same or different files) and merge them into a single output stream. It is therefore not currently possible, for example, to turn two separate mono streams into a single stereo stream. However splitting a stereo stream into two single channel mono streams is possible.

If you need this feature, a possible workaround is to use the amerge filter. For example, if you need to merge a media (here input.mkv) with 2 mono audio streams into one single stereo channel audio stream (and keep the video stream), you can use the following command:

ffmpeg -i input.mkv -filter_complex "[0:1] [0:2] amerge" -c:a pcm_s16le -c:v copy output.mkv

You may want to read through and experiment with the man page instructions on man ffmpeg-filters to understand just what level of complexity you're getting into for naming channels and expected output.