Reputation: 1498
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:
out.mp4
(which should be identical to in.mp4
) contains only 2 streams:
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.
Upvotes: 49
Views: 61558
Reputation: 145
@Aquarius Power: [I couldn't comment, alas] Your answer is the only one that worked for me. Thanks a bunch!
My basic command is, to extract the first 40 seconds of a file with
ffmpeg -i infile -t 00:00:40 -c copy outfile
, including all audio streams.
Just -c copy
and -vcodec copy -acodec copy
produce the first audio stream only.
-c copy map 0
results in
[mpegts @ 0x55a014287e00] Timestamps are unset in a packet for stream 8. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly [mpegts @ 0x55a014287e00] Stream 8, codec epg, is muxed as a private data stream and may not be recognized upon reading. And worse, it doesn't respect the end time, but produces a complete file, at a speed below 1.
-vcodec copy -c:a copy -map 0
and
-vcodec copy -c:a copy -map 0:0 -map 0:1 -map 0:2
both fail with
Automatic encoder selection failed for output stream #0:0. Default encoder for format mpegts (codec none) is probably disabled. Please choose an encoder manually. Error selecting an encoder for stream 0:0
-c copy -map 0:a -map 0:v
Does exactly what the OP requested. Unfortunately, I can't vote your answer up, either. But I hope that anyone with the same question finds this!
Upvotes: 0
Reputation: 2718
It seems that specific ffmpeg versions ignore -c copy
option and skip audio stream copy, thus resulting in final file with no audio, e.g. does not copy audio tracks and produce video with no sound.
The ffmpeg affected is for example used on Synology Disk Station devices:
ffmpeg version 2.7.7 Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 4.9.3 (crosstool-NG 1.20.0) 20150311 (prerelease)
To resolve that, without analyzing file structure and manually mapping all audio streams with -map 0:1 -map 0:2 etc, I found very simple command to process it automatically:
ffmpeg -i INFILE -map 0 -c copy -c:a copy OUTFILE
This is different from -c:v -c:a
as preserves chapters and subtitles together with video and all audio tracks with different languages, like english, spanish, french, russian or chineese.
Also in case you have more hardly broken file, which simple copy does not fix, please try this command, which potentially fix more errors, which could crash video player, or stuck video or audio:
ffmpeg -err_detect ignore_err -i INFILE -map 0 -c copy -c:a copy OUTFILE
Upvotes: 0
Reputation: 1619
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.
Upvotes: 62
Reputation: 3985
First I tried this broader answer here: https://stackoverflow.com/a/54616353/1422630
But I had trouble with a not supported subtitle track so I ended having to use this command:
avconv -i INFILE -c copy -map 0:a -map 0:v OUTFILE
I understand that, after I asked to copy, it basically copied only what I mapped (and it mapped all audio of course), as I don't care for the subtitles being embedded at all. If you want to map the subtitles, just add this -map 0:s
.
Upvotes: 1
Reputation: 1498
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.
Upvotes: 24
Reputation:
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.]
Upvotes: 2