What ffmpeg command line produces video more compatible across all devices?

So I have users saying H264 videos MP4's don't play audio on Apple's iPad and I struggle to get MP4 videos to play properly on Android too.

There are two different command lines what command line is the one that I should be using.

-profile:v baseline -level 3.0

And :

-vpre baseline

What one should I use that will make it work across all devices?

I have also read it could be the audio bitrate my current audio bitrate is

-ab 192k

Perhaps I should lower it to

-ab 160k

Command line used to encode MP3 audio into MP4 files.

"C:/server/ffmpeg/bin/ffmpeg.exe" -y -i Z:/server/websites/ps/public_www/media/com_hwdmediashare/files/55/ac/fb/54bbf30bb11a0f6b9dc832114c26fd29.mp4 -strict experimental -acodec libmp3lame -ar 44100 -ac 2 -ab 192k -s 480x360 -aspect 16:9 -r 24000/1001 -vcodec libx264 -b:v 1000k -minrate 800k -maxrate 1000k -bufsize 800K -crf 18 -preset veryslow -f mp4 -threads 0 -movflags +faststart Z:/server/websites/ps/public_www/media/com_hwdmediashare/files/55/ac/fb/98382d43d31d4ff91ea44cb2aa1bbc49.mp4 2>&1

Solution 1:

First you should understand the difference between using FFmpeg profiles and the direct commandline options. -vpre uses an .ffpreset file located in /usr/share/ffmpeg/ or wherever ffmpeg was installed to. It's a series of option=value pairs, and in your case you would have had to define it yourself (at least I don't know a baseline preset shipped with ffmpeg).

I would recommend against using presets unless you created it yourself and know what the command line options are for. I've been using ffmpeg for years now, and I've never used presets—I've never really had to.

A typical command line for generating H.264 video compatible with most devices would be:

ffmpeg -i <input> \
  -c:v libx264 -crf 23 -profile:v baseline -level 3.0 -pix_fmt yuv420p \
  -c:a aac -ac 2 -b:a 128k \
  -movflags faststart \
  output.mp4

Some notes:

  • H.264/AAC is the best combination for a broad support in HTML5. Browsers that do not have H.264 decoders however will need a VP8/Vorbis video, too. For some command line examples, see this answer. See also the browser support page of Wikipedia for other codecs.

  • H.264 also works well across mobile devices.

  • The -profile:v baseline and -level 3.0 options are only needed for old mobile devices that cannot handle CPU-intensive features of H.264. You can typically leave these out or instead use -profile:v main.

  • The CRF sets the quality (18–28 is a reasonable range, lower means better quality). You can of course also use a fixed bitrate with -b:v 1000k or similar. Choose a bitrate that matches the resolution of the video. Some low-powered devices may not be able to handle unnecessarily high bitrates.

  • The -movflags faststart option is essential for streaming, since it moves the container metadata to the beginning of the file instead of leaving it at the end. This will allow the playback to immediately start instead of having to wait for the file to be loaded entirely.

However, it all comes down to finding the lowest common denominator for all devices you are targeting, which might not always exist. Certainly you wouldn't want to use any other (that is, worse) codec than H.264. In fact, it also wouldn't be wise to offer Baseline-encoded video to clients which can decode Main or High profile. You'd trade off quality against reduced decoding complexity.

From my experience, Android devices can play Baseline H.264 with AAC-LC audio in an MP4 container just fine. I've never had problems with it. In fact, some devices may play higher profiles too, although it's not officially supported. iOS generally also supports Baseline H.264, but you can certainly use Main profile on some devices too. See this post (which is a little outdated) for some guidelines.

If you have users with playback problems, you'd need to find out which video is causing issues, and get more details on what hardware and player software they're using. Then we could talk about troubleshooting that particular case.