Making a H.264 stream instantly with progressive download

Here’s a tip people has asked me about quite a few time concerning playback of H.264 videos using progressive download:
Why do I have to download the whole video file before I can start playback or skip in the video file?

Well, when you serve videos on a site using plain HTTP – known as progressive download – the position of the header becomes very important.
Either the header is placed in the beginning of the file or it’s places in the end of the file. In case of the latter, you’ll have to download the whole thing before you can begin playback – because without the header, the player can’t start decoding.
When you transcode H.264 files in a MP4 container using FFmpeg, the header will be placed in the end and needs to be moved.
So, how do we move the header from the end of the file to the beginning of the file?

Well, I always transcode the video part with FFmpeg and the audio part with NeroAAC and mux the two parts together using Mp4Box. Mp4Box places the header in the beginning of the file – and all is good. If you have files that needs the header moved, you can use the small tool Qt-faststart. You can find Qt-faststart for Windows here.
Recent developement in FFmpeg makes it possible to have FFmpeg move the header to the front of the file using the -movflags faststart option, but it can be a rather slow choice. Here’s how you would do it:

ffmpeg -i input.mp4 -c:a copy -c:v copy -movflags +faststart output.mp4

For further reading, including how to check if your header is placed correctly in regards to progressive download –  you can read this article from Adobe.

 

If you stream using a streaming server or using HTTP Live Streaming (HLS), the position of the header shouldn’t matter. There might be a performance boost in having the header in the front of the file – but this I haven’t tested, but if any of you readers has further info, please don’t be shy – let us know by leaving a comment…

/Fred

7 Comments

  1. i make a stream using ffmpeg. raw h264 stream. it can receive successfully by ffmpeg. but when i try to receive it in vlc plaer i can see only a black screen. I use
    -movflags faststart option. but it did not work. i assume that vlc cannot start play because of missing headers. can you help me with this?

  2. hi
    i do it in c# using ffmpeg wrapper.
    ms = new MemoryStream();
    //Create video encoding task and set main parameters for the video encode
    ffMpegTask = ffmpegConverter.ConvertLiveMedia(
    “rawvideo”,
    ms,
    “h264”,
    new ConvertSettings()
    {
    CustomInputArgs = “-pix_fmt bgr24 -video_size ” + frameWidth + “x” + frameHeight + ” -framerate ” + FrameRate + ” “, // windows bitmap pixel format
    CustomOutputArgs = ” -profile:v baseline -pix_fmt yuv420p -g 10 -b:v 4000k -maxrate 4000k -bufsize 8000k -s ” + outPutFrameSize + ” -r ” + FrameRate + ” -threads 7 ”
    //VideoFrameSize = FrameSize.hd1080,
    //VideoFrameRate = 30
    });
    ffMpegTask.Start();
    ffMpegTask.Write(buf, 0, buf.Length);// raw data byte array
    ffMpegTask.Stop();

    byte[] streamBytes = null;
    streamBytes = ms.ToArray(); // get the encoded data as byte array. i send this through udp.

    now i can receive the stream using vlc. to receive the stream in vlc the url should be
    udp/h264://@224.1.1.1:1234. But if i use udp://@224.1.1.1:1234 then i cannot receive the stream. but if we stream using vlc we can use this url to receive the stream.
    thank you for the help.

  3. Ok. But for live-streaming, you need some kind of streaming server like Adobe FMS, Wowza, Red5 – or VLC – not just a regular webserver. What server are you using?

  4. i dont use any server

  5. how can I give output frame size for CustomOutputArgs , as an integer value

Leave a Reply

Your email address will not be published.

*