Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am the maintainer of a software which use ffmpeg to automatically mix & transcode two input stream into a single output with a video & audio track. I am currently facing some portability issues and would like to improve my use of ffmpeg to be ensure that my application will be as portable as possible:

  • Will work on almost all OS & distro
  • Will work with old ffmpeg releases (debian squeeze still use ffmpeg 0.5.10)

My first source is an FLV or mp4 file. It contains two streams: audio & video. I don't care about the video, it not included in the final file.

The second source is a list of PNG or JPG images. They will be used to create the video stream using image2.

The output must be a file with two streams: audio & video. I have no strong requirement regarding the container, the audio codec and the video codec. They only need to be easily available on any OS/device. I want to preserve the audio quality as much as possible. The video stream is only a set of static slides. It would be great to minimize the size of the output file.

According to this description, which flags/container/codecs would you use?

The description of the current process follows:

  1. Extract the audio track from the first source

    ffmpeg -v error -i source_1_path -vn -acodec libvorbis audio_track.ogg
  2. Create the final file

    ffmpeg -v error -f image2 -r 1 -i frame_pattern.jpg -i audio_track.ogg output.avi

I was thinking that ffmpeg would automatically use the most suitable audio/video codecs & settings. Unfortunately it fails on some Linux distributions ([ac3 @ 0x1e60380] invalid bit rate with 0.8.6-6:0.8.6-0ubuntu0.12.10.1 for example).

It would obviously be better to do it in a single pass rather than creating a temporary audio track.

share|improve this question
up vote 2 down vote accepted

ffmpeg versions and packaging ffmpeg yourself

If someone's using ffmpeg 0.5.10, then you're really not to blame if something doesn't work. The number one cause of problems with ffmpeg commands (at least from my experience) is an outdated version. Between 0.5 and recent 1.2, there are literally thousands of fixed bugs and hundreds of new features. Most notably, they've changed (and removed) a few command line options, which break some workflows.

Note that Ubuntu, due to some circumstances, doesn't really use ffmpeg from the FFmpeg project, but actually uses Libav's avconv. In newer versions of Ubuntu, that is. Old versions of Ubuntu still supplied a binary called ffmpeg that came from Libav, which is broken and outdated, but people still think it comes from FFmpeg. Bottom line: You can't and shouldn't trust your user to have a working ffmpeg binary on their system.

There are many projects that include part of the FFmpeg tools, and you could incorporate a static build with your software if that's not a legal issue (IANAL, so please check). The only downside I see here is that older kernels might not run all static builds.

That all being said, here's what should work everywhere, under the assumption that ffmpeg was compiled with libx264 and libmp3lame enabled. The original command you had wouldn't work reliably because Vorbis audio is problematic in AVI, and the AC3 encoder that is auto-selected for AVI might chocke on some inputs. Plus, you'd re-encode your audio from Vorbis to AC3, which deteriorates the quality.

Extract audio to MP3

Rather export to MP3 audio, e.g. with 320 kBit/s CBR or VBR of 4 (LAME's -V equivalent). The latter might not work on old versions because of the :a suffix.

ffmpeg -v error -i source_1_path -vn -acodec libmp3lame -ab 320k audio_track.mp3
ffmpeg -v error -i source_1_path -vn -acodec libmp3lame -q:a 4 audio_track.mp3

Combine with H.264 video

For combining, we'll use x264 video (an H.264 encoder):

ffmpeg -v error -f image2 -r 1 -i frame_pattern.jpg -i audio_track.mp3 \
-acodec copy -vcodec libx264 output.mp4

Here you simply copy the audio stream instead of having ffmpeg re-encode it. This will help you retain the original quality.

As for video, note that not all devices can play H.264 out of the box. Some might only play H.264 with the baseline profile, which you set with -profile:v baseline in newer ffmpeg, or -vprofile baseline in some versions around 0.7 (not sure which… it was undocumented back then), or -vpre baseline for really old versions that used internal presets instead of relying on the x264 encoder library.

Alternative: Combine with MPEG-4 video

If H.264 is not an option you could try MPEG-4 Part II video—here with 2 MBit/s bitrate set through -vb:

ffmpeg -v error -f image2 -r 1 -i frame_pattern.jpg -i audio_track.mp3 \
-acodec copy -vcodec mpeg4 -vb 2M output.mp4

The option should be -b:v now, but the old alias still works.

share|improve this answer
Thanks for your rational and valuable answer. I will use it as a foundation. Sadly it confirms my feeling that portability is not so easy to achieve. Regarding old versions in the wild, it is part of the game. You can't blame users for using stable distributions, but you can blame projects which don't care about (back|for)ward compatibility ;) – Clément MATHIEU Apr 18 '13 at 15:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .