FFmpeg not copying all audio streams - linux

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.

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.

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.

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.]

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.

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

Related

Multichannel AAC mp4 encoding using libav (avconv) or ffmpeg

I am trying to create a four-channel mp4 file with AAC encoding for ambisonics use. I am trying to encode a 4-channel first-order ambisonic wav file into AAC like so:
avconv -i four_channel_input.wav -c:a libfaac -ac 4 four_channel_output.mp4
This gives me the error
[libfaac # 0x7f938885a000] Specified channel_layout is not supported
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Removing the -ac 4 option gives me a 5 channel file
Duration: 00:01:21.09, start: 0.021333, bitrate: 218 kb/s
Stream #0:0(und): Audio: aac (LC) [mp4a / 0x6134706D]
48000 Hz, 5.0, fltp, 215 kb/s (default)
with a blank first channel, which is obviously suboptimal. In order to create compressed ambisonics files, should I be using a separate format like AmbiX (even though I believe this is uncompressed)?
With ffmpeg, you can run
ffmpeg -i input.wav -c:a aac -ac 4 -channel_layout 4.0 four_channel_output.mp4

How to merge mp4 audio dash fragment with another audio

I have 1 audio file from dash stream
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'file_191282-377206_header.mp4': Metadata:
major_brand : iso6
minor_version : 1
compatible_brands: mp42dashmsdhmsixiso6avc1isom
creation_time : 2016-04-29T11:04:26.000000Z Duration: 00:00:30.02, start: 14.997333, bitrate: 49 kb/s
Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 48 kb/s (default)
Also in exiftool output:
Movie Data Size : 180193
Movie Data Offset : 6388
I try to merge with another audio and save metadata info like Movie Data Size/Offset and start/duration time.
I try with ffmpeg/MP4Box commands like:
MP4Box -new -add file_191282-377206_header.mp4 -add out000.mp4
ffmpeg -i file_191282-377206_header.mp4 -i out000.mp4 -codec copy -shortest output.mp4
ffmpeg -i file_191282-377206_header.mp4 -i out000.mp4 -filter_complex amerge -ac 2 -c:a aac output.mp4
All the time information erased or changed.
So question is how to merge 2 audio files inside mp4 and not change Movie Size/Offset and start/duration time?
Try to merge the actual audio (AAC) not the media container (MP4).
So extract the AAC from each media file, then merge those audios.
Finalise by putting the merged audio back into a new MP4 output.

FFMPEG convert FLV to MP4 and reduce filesize

i have a system that is recording live stream via Wowza. I get from Wowza a .flv file with the record. The problem is, 5 minutes file is near to 50mb big. But when i look at some TV-Series that you can download from the net, they are 20 minutes, in mp4 and just like 150mb big. Whatever... Look, the stream input is like:
Input #0, flv, from 'rtmp://127.0.0.1/stream/test.stream':
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0.0: Video: h264 (Constrained Baseline), yuv420p, 720x404 [PAR 1:1 DAR 180:101], 25 tbr, 1k tbn, 50 tbc
Stream #0.1: Audio: aac, 48000 Hz, stereo, s16
FFmpeg shows me something like this at the "session":
frame= 2721 fps= 27 q=-1.0 Lsize= 17188kB time=111.21 bitrate=1266.1kbits/s
Have you any idea how to use FFmpeg to convert the .FLV file in MP4 in same near to Quality but smaller filesize?
btw. i'm operating in linux ^^
Thanks
This is based on a linux mashine using the latest ffmpeg
using the following code and changing only the -crf value you are able to create various video clip sizes.lower number is higher quality.
The final video is compatible with all modern devices/services like native web players, ios devices , android devices, microsoft devices, ps3, xbox and more.
ffmpeg
-y //overwrite the file if it exists
-i INPUTFILE // replace with the input file
-metadata title=THETITLE // set a nice title, visible on modern devices
-metadata date=THEDATE // set a nice title, visible on modern devices
-c:v libx264 // use the h264 codec
-crf 21 // try different numbers between 18-26
-preset veryslow // placebo,slow,fast,ultrafast==big file
-tune film // tune it a little
-pix_fmt yuv420p // preferred on most modern devices
-profile:v main // preferred on most modern devices
-level 3.1 // preferred on most modern devices
-refs 4 // preferred on most modern devices
-c:a libfdk_aac // use aac
-metadata:s:a language=eng // set a language, visible on modern devices
-b:a 128k // audio bitrate 128k is like mp3 192k
-ar 48000 // 44100 ... whatever
-ac 2 // audiochannels
-movflags +faststart //move the metadata in the front of the video so it loads faster
OUTPUTFILE

Convert a video to MP4 (H.264/AAC) with ffmpeg

If I don't make a mistake, Safari currently need MP4 (H.264/AAC) video encoded for the HTML5 <video> element.
So I tried to convert a video to this format with ffmpeg. However when I enter the shell command ffmpeg -i video.flv video.mp4, the returned error is :
Seems stream 0 codec frame rate
differs from container frame rate:
2000.00 (2000/1) -> 29.92 (359/12) Input #0, flv, from 'video.flv':
Duration: 00:05:01.20, start:
0.000000, bitrate: 66 kb/s
Stream #0.0: Video: h264, yuv420p, 320x240 [PAR 1:1 DAR 4:3], 66 kb/s,
29.92 tbr, 1k tbn, 2k tbc
Stream #0.1: Audio: aac, 22050 Hz, stereo, s16 Output #0, mp4, to
'video.mp4':
Stream #0.0: Video: mpeg4, yuv420p, 320x240 [PAR 1:1 DAR 4:3],
q=2-31, 200 kb/s, 90k tbn, 29.92 tbc
Stream #0.1: Audio: 0x0000, 22050 Hz, stereo, s16, 64 kb/s Stream
mapping: Stream #0.0 -> #0.0
Stream #0.1 -> #0.1 Unsupported codec
for output stream #0.1
An AAC codec is required but I'm quite newbie with ubuntu and I dont really now how to fix this problem. I'm using Ubuntu 9.10 Karmik Koala (for amd64).
Thank you very much. :)
http://handbrake.fr is a nice high level tool with a lot of useful presets for mp4 for iPod, PS3, ... with both GUI and CLI interfaces for Linux, Windows and Mac OS X.
It comes with its own dependencies as a single statically linked fat binary so you have all the x264 / aac codecs included.
$ HandBrakeCLI -Z Universal -i myinputfile.mov -o myoutputfile.mp4
To list all the available presets:
$ HandBrakeCLI -z
Software patents led Debian/Ubuntu to disable the H.264 and AAC encoders in ffmpeg. See /usr/share/doc/ffmpeg/README.Debian.gz.
So go install x264, mplayer/mencoder, and Nero's AAC encoder. (Or, if you want to use all Free software, and don't care so much about audio quality, then sudo aptitude install faac.)
I don't remember if the medibuntu package of mencoder includes x264 vid encoding, since I build my own from git x264 and svn mplayer sources. (x264 is very actively developed, with significant quality and speed improvements frequently added.)
http://git.videolan.org/?p=x264.git;a=summary
x264 is also packaged, but you should check that it's up to date enough to include weightp with recent bugfixes, and even more recent speed improvements...
Or if you're already willing to convert from .flv, instead of going from the high-quality source the flv was made from, then probably whatever recent version of x264 you can find will be fine.
You're trying to convert a (rather rare) .flv file that (already) contains H.264 video and AAC audio.
Formatting your console's output as FFmpeg brings out these details.
Input #0, flv, from 'video.flv':
Duration: 00:05:01.20, start: 0.000000, bitrate: 66 kb/s
Stream #0.0: Video: h264, yuv420p, 320x240 [PAR 1:1 DAR 4:3], 66 kb/s, 29.92 tbr, 1k tbn, 2k tbc
Stream #0.1: Audio: aac, 22050 Hz, stereo, s16
The original flv is converted to an .mp4 file with H.264 video and AAC audio (just like the original .flv):
Output #0, mp4, to 'video.mp4':
Stream #0.0: Video: mpeg4, yuv420p, 320x240 [PAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 90k tbn, 29.92 tbc
Stream #0.1: Audio: 0x0000, 22050 Hz, stereo, s16, 64 kb/s
Because the audio and video data in the .flv are already in the format/codecs you need for the .mp4, you can just copy everything to the new .mp4 container. This process will be massively faster than decoding and reencoding everything:
ffmpeg -i video.flv -vcodec copy -acodec copy video.mp4
or more simply:
ffmpeg -i video.flv -codec copy video.mp4
##The real error you're getting is:##
Unsupported codec for output stream #0.1
Which means FFmpeg can't convert audio (stream #0.1) to AAC.
You can skip the error by:
copying the audio data since it's already AAC encoded (use the copy command above)
or you can solve the error by:
using a FFmpeg build with AAC decode/encode support. FFmpeg currently supports 4 AAC libraries (see FFmpeg and AAC Encoding Guide).
For more details you should also read Converting FLV to MP4 With FFmpeg The Ultimate Guide
You need to recompile ffmpeg (from source) so that it supports x264. If you follow the instructions in this page, then you will be able to peform any kind of conversion you want.
You can also try adding the Motumedia PPA to your apt sources and update your ffmpeg packages.
Had this problem recently with converting nasty WMV into Final Cut Pro X for editing. Flow player can do it but it leaves a water mark, so I fiddled a bit with ffmpeg till I got something going.
First install ffmpeg - I used
brew install ffmpeg
Obviously you need brew installed first, google that bit.
Next I wrote a simple command line script with the following content - you can substitute the $1 for an input / output file or just create a shell script file...
vi convert.sh
Paste.
echo "Pass one"
ffmpeg -y -i "$1" -c:v libx264 -preset medium -b:v 1555k -pass 1 -c:a libfaac -b:a 256k -f mp4 /dev/null &&
echo "Pass two"
ffmpeg -i "$1" -c:v libx264 -preset medium -b:v 1555k -pass 2 -c:a libfaac -b:a 256k "$1.mp4"
Then to convert your video...
sh convert.sh myvideofile.wmv
If all went well you should see a new file called myvideofile.wmv.mp4.
Hope that works for you.
You need to compile ffmpeg with an AAC encoder. You can find one at AudioCoding.
Try This one:: Libav in Linux
Installation: run command
sudo apt-get install libav-tools
Video conversion command::Go to folder contains the video and run in terminal
avconv -i oldvideo.flv -ar 22050 convertedvideo.mp4

RTMP: Is there such a linux command line tool?

I have looked everywhere to find a linux utility that will allow me to download rtmp streams. Not flv video but MP3 streams. The location of the streams I want to download are in this format.
rtmp://live.site.com/loc/45/std_fc74a6b7f79c70a5f60.mp3
Anyone know of such a command line tool? Or even anything close to what I am asking for?
I do not want full software applications and it would be great if it worked on Linux via Shell or something.
Thanks all
One of the following should do, if you have mplayer or vlc compiled with RTMP access.
mplayer -dumpstream rtmp://live.site.com/loc/45/std_fc74a6b7f79c70a5f60.mp3
This will generate a ./stream.dump.
vlc -I dummy rtmp://live.site.com/loc/45/std_fc74a6b7f79c70a5f60.mp3 \
--sout file/ts:output.mpg vlc://quit
This will generate a ./output.mpg. You'll have to demux it to extract just the audio stream out.
This question is old but this can help to another users with this doubt.
To download directly, without any conversion, there is two options (the author of both programs is the same and the behavior is the same):
RTMPDump. Example: rtmpdump -r "rtmp://host.com/dir/file.flv" -o filename.flv
flvstreamer. Example: flvstreamer -r "rtmp://od.flash.plus.es/ondemand/14314/plus/plustv/PO770632.flv" -o salida.flv
And if you want download and convert the video at same time, the best way is use ffmpeg:
ffmpeg -i rtmp://server/live/streamName -acodec copy -vcodec copy dump.mp4
I think the landscape has changed a bit since the time of some of the previous answers. At least according to the rtmp wikipedia page. It would appear that the rtmp protocol specification is open for public use. To that end you can use 2 tools to accomplish what the original poster was asking, rtmpdump and ffmpeg. Here's what I did to download a rtmp stream that was sending an audio podcast.
step #1 - download the stream
I used the tool rtmpdump to accomplish this. Like so:
% rtmpdump -r rtmp://url/to/some/file.mp3 -o /path/to/file.flv
RTMPDump v2.3
(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL
Connecting ...
INFO: Connected...
Starting download at: 0.000 kB
28358.553 kB / 3561.61 sec
Download complete
step #2 - convert the flv file to mp3
OK, so now you've got a local copy of the stream, file.flv. You can use ffmpeg to interrogate the file further and also to extract just the audio portion.
% ffmpeg -i file.flv
....
[flv # 0x25f6670]max_analyze_duration reached
[flv # 0x25f6670]Estimating duration from bitrate, this may be inaccurate
Input #0, flv, from 'file.flv':
Duration: 00:59:21.61, start: 0.000000, bitrate: 64 kb/s
Stream #0.0: Audio: mp3, 44100 Hz, 1 channels, s16, 64 kb/s
From the above output we can see that the file.flv contains a single stream, just audio, and it's in mp3 format, and it's a single channel. To extract it to a proper mp3 file you can use ffmpeg again:
% ffmpeg -i file.flv -vn -acodec copy file.mp3
....
[flv # 0x22a6670]max_analyze_duration reached
[flv # 0x22a6670]Estimating duration from bitrate, this may be inaccurate
Input #0, flv, from 'file.flv':
Duration: 00:59:21.61, start: 0.000000, bitrate: 64 kb/s
Stream #0.0: Audio: mp3, 44100 Hz, 1 channels, s16, 64 kb/s
Output #0, mp3, to 'file.mp3':
Metadata:
TSSE : Lavf52.64.2
Stream #0.0: Audio: libmp3lame, 44100 Hz, 1 channels, 64 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Press [q] to stop encoding
size= 27826kB time=3561.66 bitrate= 64.0kbits/s
video:0kB audio:27826kB global headers:0kB muxing overhead 0.000116%
The above command will copy the audio stream into a file, file.mp3. You could also have extracted it to a wav file like so:
ffmpeg -i file.flv -vn -acodec pcm_s16le -ar 44100 -ac 2 file.wav
This page was useful in determining how to convert the flv file to other formats.

Resources