FFmpeg not copying all audio streams

40,631

Solution 1

Apparently this is a popular question, so I'm posting my solution as an answer (was previously a comment reply) so that others can see.

I managed to find the correct syntax from this ticket. The correct syntax is:

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

This will copy all 3 streams.

Solution 2

FFmpeg have option to map all streams to output, you have to use option -map 0 to map all streams from input to output.

In full line it might look like:

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

For more info see the documentation on stream selection and the -map option.

Solution 3

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.

[Edit: As Mulvya noted, this answers a question, but it was not quite the original poster's question.]

Share:
40,631
Dotl
Author by

Dotl

Updated on December 04, 2021

Comments

  • Dotl
    Dotl over 2 years

    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.

  • Dotl
    Dotl about 8 years
    Excellent, I'll do some experimenting. Thanks.
  • Dotl
    Dotl about 8 years
    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:0 -map 0:1 -map 0:2 out.mp4, this will copy all 3 streams.
  • Gyan
    Gyan about 8 years
    This answer has nothing to do with the OP's query. They want to copy tracks over, not merge or split them. The OP's original command should work, as the stream mapping code shows. It is a mystery why it doesn't but the separate stream codec syntax does. Can the OP share the console output for the original copy command?
  • Arunas Bartisius
    Arunas Bartisius over 6 years
    I give +1 for answer, but it would be very helpful to amend it with: To select all video and the third audio stream from an input file: ffmpeg -i INPUT -map 0:v -map 0:a:2 OUTPUT Same is fo all audio streams, which could be noted as 0:a
  • 2xj
    2xj over 5 years
    This was super helpful. You interested in adding a full command to make it easier? ffmpeg -i IN.mp4 -c copy -map 0:? OUT.mp4
  • radioxoma
    radioxoma about 5 years
    For multiple sources like -i in0.mp4 -i in1.aac one need to add -map 0 -map 1 to mux all input streams.
  • radioxoma
    radioxoma about 5 years
    You can replace -map 0:? with just -map 0.
  • ScipioAfricanus
    ScipioAfricanus over 3 years
    Is there a way to do this but ignore subs? I am trying to -ss clip videos and if the subs are not certain format, they throw errors. Ideally I would like to just convert subs to a usable format and preserve them.