Creating MP4 videos ready for HTTP streaming

79,923

Solution 1

This is an answer to last comment by you @abrahab.

You don't need to mp4box a file to be able to pseudo stream it via nginx. The MP4 streaming module takes care of it irrespective of positioning of moov atoms (mp4box shifts the moov atom to beginning of file).


Now for the 500 server error, are you using "-frag" option with mp4box? MP4 streaming module can't read fragmented MP4 files. Good use of mp4box for pseudo streaming is to interleave the videos for better seeking. Moov atom shifting is an added advantage.

I always do this to mp4box an FFmpeg-encoded file

MP4Box -add MyVideo.mp4 -isma Myvideo-box.mp4

This will also interleave the MP4 file in 500 milliseconds of chunks by default.

Solution 2

H.264 in MP4

Generally, you want to create x264 video within an MP4 container. This option is supported by basically any device and browser.

The following should be enough. Make sure to replace input name and CRF options. The latter sets the quality, where sane values range from 19 to 25 – lower means better quality, but also higher bitrate:

ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac -movflags faststart output.mp4

You can also use Handbrake for encoding if you like the GUI way.

Using the faststart option

Now, what you need to do is move the MP4 container's MOOV atom to the beginning. This atom (in essence, a unit of data in the MP4 container) will contains important metadata about the video/audio streams themselves. -movflags faststart should do exactly that.

If your FFmpeg version doesn't have this option, consider upgrading. If you cannot upgrade, you can achieve the same thing with any of the below tools:

  • QTIndexSwapper, an Adobe AIR application

  • MP4Box, free and open source, running a command similar to the following, where you can change the interval (here, 500):

    mp4box -inter 500 input.mp4

  • qt-faststart in Python, which works everywhere where Python is installed.

    qtfaststart input.mp4

That's about it.

Controlling bitrate / quality

Now, of course, for streaming you may actually want to constrain the bitrate to stay within certain bounds. You can read more about that in my blog post on rate control methods.

For example, by adding -maxrate 2M -bufsize 2M to the encoding options, you cap the encoding to 2 Mbit/s, which may be sufficient for 720p video. The required bitrate will depend, of course, on how complex the content is. This takes some trial and error.

Solution 3

You can simply convert a non-streamable AVI or MP4, also without re-encoding everything, by doing this:

ffmpeg -i INPUT.mp4 -c copy -movflags faststart STREAMABLE_OUTPUT.mp4

There's no need to re-encode anything, because just the moov atom has to be moved.

Share:
79,923

Related videos on Youtube

abrahab
Author by

abrahab

Updated on September 18, 2022

Comments

  • abrahab
    abrahab over 1 year

    How can I convert some.flv or some.avi or some.wmv with FFmpeg to be sure that this video will be playable and seekable in JW Player?

  • abrahab
    abrahab almost 12 years
    thanks, I do all the same way, but seems the problem still with the video :( I do ffmpeg -i 1.flv -vcodec libx264 -f mp4 -an -g 1 -f mp4 -g 30 -level 3 new.mp4 then mp4box and mp4 can not seek and nginx report 500 internal server error for start parameter more that 0. when video coded without -vcoded libx264 (default mp4 coder) all work file (but quality! sick!) :( (sorry, now, not allowed to upvote you answer)
  • slhck
    slhck almost 12 years
    This seems like a h.264 plugin issue with NginX rather than any video conversion problem. I'm not the expert in web video streaming per se, but I see you already asked about this on Stack Overflow? stackoverflow.com/questions/11079748/…
  • abrahab
    abrahab almost 12 years
    I am also thinking that maybe nginx can not read this video format properly. video from youtube is also played well. yes, I am asked on stack about nginx issue, but seems no answers. :(
  • slhck
    slhck over 11 years
    22 kHz PCM Stereo audio for internet streaming video? Doesn't sound too efficient. And why would you set the audio bitrate to 128k then?
  • Vineet
    Vineet over 11 years
    To do "in-place" file interleaving without having to create a new file, directly use MP4Box -isma -inter 500 Myvideo.mp4
  • Searush
    Searush over 11 years
    @slhck , you can change 22k to 44k replacing "-ar 22050" with "ar 44100"
  • slhck
    slhck over 11 years
    @SEARAS The problem isn't the sampling rate. It's the fact that the audio is uncompressed PCM stereo. For internet streaming. That doesn't figure.
  • andrew
    andrew over 10 years
    +1 for -movflags faststart exactly what I needed
  • malat
    malat about 9 years
  • slhck
    slhck about 9 years
    @malat Thanks for the info. I removed that part though, as it should be fairly well documented with JW Player anyway, and probably out of scope of this question.
  • LiveWireBT
    LiveWireBT over 8 years
    This answer is of very low quality and should be removed. The parameters may change the framerate, video resolution and audio sampling rate of the content and produce inefficient or low quality results (ffmpeg can choose safer or better parameters itself). The performance is also crippled by limitation to fewer threads and doesn't even work with the -acodec pcm_s16le (error: Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument). A good reason like an IETF draft why to choose exactly these parameters appears to be also missing.