Creating MP4 videos ready for HTTP streaming
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.
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.
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.