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?


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.

  • 1
    To do "in-place" file interleaving without having to create a new file, directly use MP4Box -isma -inter 500 Myvideo.mp4
    – Vineet
    Oct 3 '12 at 5:16

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.

  • 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)
    – abrahab
    Jun 18 '12 at 20:31
  • 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/…
    – slhck
    Jun 18 '12 at 20:36
  • 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. :(
    – abrahab
    Jun 18 '12 at 20:42
  • 3
    +1 for -movflags faststart exactly what I needed
    – andrew
    Dec 9 '13 at 1:26
  • link is dead, need to use web.archive.org: web.archive.org/web/20140201142344/http://www.longtailvideo.com/…
    – malat
    Feb 24 '15 at 20:02

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.


To add onto the other answers: if you have srt's this will convert them for you too:

ffmpeg \
    -i "$1.mp4" \
    -c:v libx264 \
    -crf 23 \
    -c:a aac \
    -movflags faststart \
    -maxrate 2M \
    -bufsize 2M \

curl \
    --form subrip_file=@"$1.srt" \
    -o "$dest/$1.vtt" \

You can try this with ffmpeg:

ffmpeg.exe -i "INPUT_FILE.AVI" -threads 2 -s 800x600 -r 25.00 -threads 1 -pix_fmt yuv420p -g 300 -qmin 3 -b 2048k -async 1 -acodec pcm_s16le -ar 22050 -ac 1 -ab 128k -y "OUTPUT_FILE.mp4"
  • 7
    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?
    – slhck
    Aug 26 '12 at 9:56
  • @slhck , you can change 22k to 44k replacing "-ar 22050" with "ar 44100"
    – Searush
    Nov 10 '12 at 10:41
  • 2
    @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.
    – slhck
    Nov 10 '12 at 10:42
  • 1
    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.
    – LiveWireBT
    Sep 24 '15 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.