FFmpeg – the swiss army knife of Internet Streaming – part V

[Index]

PART I – Introduction (revised 02-jul-2012)
PART II – Parameters and recipes (revised 02-jul-2012)
PART III – Encoding in H.264 (revised 02-jul-2012)
PART IV – FFmpeg for streaming (revised 02-jul-2012)
PART V – Advanced usage (revised, 19-oct-2012)
PART VI – Filtering (new, 19-oct-2012)

Introduction

After almost one year from the starting post of this series dedicated to FFmpeg I have found some time to catch-up with this topic and revise/refresh the series. In this year a lot of things happened on the FFmpeg side (and not only), so I have corrected a lot of small errors and changes in syntax of commonly used commands. So this is also a good opportunity for you to refresh your knowledge about FFmpeg and the current state-of-the-art. Above you find the Index of the articles.

The most important changes are around parameters like -vcodec, -b, -ab, -vframes, etc… to avoid misunderstandings now a stream_identifier has been added to specify if the parameter is related to the audio or video track. In case of multiple AV tracks there also an optiona parameter to specify the track number. Take a look at the updates of PART II to have more informations about new syntax and obsolete parameters.

Another important change is realated to libfaac library which is now external. Read point 2 below to know about alternatives.

Last but not least, FFmpeg introduced the possibility to control directly the parameters of x264lib using the -x264opts command. Not for everyone but very useful when you want the control and performance of x264 and all the input and output options of FFmpeg.

Fifth Part – Advanced Usage

This fifth article wants to add more advanced use cases and usages to what was presented and discussed in the previous 4 parts. This article will be enriched in the next weeks and months to include even more advanced examples and use cases that can be solved with a smart use of FFmpeg. Good reading!

1. Optimize multi-pass multi-bitrates encoding

You know that encoding for dynamic streaming techniques (HDS, HLS, Silverlight) requires the renditions to have aligned keyframes and be CBR or capped VBR.
A neat trick to avoid the limit of fixed length GOPs is to assure a consistent alignment of keyframes across renditions reusing the same first pass statfile across renditions.

ffmpeg –i IN –pass 1 –an –vcodec libx264 –r 30 –b 1500k –bufsize 1500k –keyint_min 60 –g 120 –s 1280×720 –vpre slower_fastfirstpass OUT_1500.mp4

This command line is the first pass of the first rendition. The first pass generates a stat file for the second pass.

ffmpeg –i IN –pass 2 –an –vcodec libx264 –r 30 –b 1500k –bufsize 1500k –keyint_min 60 –g 120 –s 1280×720 –vpre slower OUT_1500.mp4

Instead of recreating a first pass stat file for the next renditions, you can use the previous simply launching the second passes of the next renditions

ffmpeg –i IN –pass 2 –an –vcodec libx264 –r 30 –b 1000k –bufsize 1000k –keyint_min 60 –g 120 –s 854×480 –vpre slower O_1000.mp4
ffmpeg –i IN –pass 2 –an –vcodec libx264 –r 30 –b 500k –bufsize 500k –keyint_min 60 –g 120 –s 640×360 –vpre slower O_500.mp4

Since the second pass is less accurate if it use a stat file generated with a too much different resolution and bitrate, may be better to use a rendition in the middle to generate the first pass and not the highest rendition.

2. AAC encoding

libfaac has been extracted from ffmpeg and is now an external library. There are two alternatives yet embedded inside ffmpeg: libvo_aacenc or the standard aac library.

ffmpeg input.mp3 -c:a libvo_aacenc -b:a 96k -ac 2 -ar 44100 output.aac

ffmpeg input.mp3 -c:a aac -strict experimental -b:a 96k -ac 2 -ar 44100 output.aac

I have tested both and it seems to me that libvo is the best alternative. It produces a sufficiently good AAC LC.
In a future article I’ll explore some alternative like encoding audio track externally and remux then with ffmpeg or mp4box.
This is a must go if you need the higher efficiency of HE AAC or HE AAC v2.

3. Joining video

Joining video is strangely a complex task with FFmpeg. A reader suggested this solution (via Steven’s Blog):

ffmpeg -ss 100 -t 10 -i in.mp4 -c copy -bsf h264_mp4toannexb 100.h264
ffmpeg -ss 200 -t 10 -i in.mp4 -c copy -bsf h264_mp4toannexb 200.h264
ffmpeg -i concat:”100.h264|200.h264″ -i in.mp3 -c copy out.mp4
The first two lines generate two h.264 elementary streams. The h264_mp4toannexb option is mandatory to be able to concatenate efficiently elementary streams at binary level.
The third line use the concat option to cancatenate the ES segments to form a new input.
I usually use mp4box for this kind of purpose and not FFmpeg.

4. Use an HLS stream as source
 

FFmpeg now supports also Apple HTTP Live Streaming as an input protocol. So it is really simple to acquire or repurpose an HLS streaming, simply specify the path to .m3u8 manifest.

ES: Do you want to stream an existing .m3u8 stream to Flash on the desktop using FMS (now AMS) ? Try this:

ffmpeg -re -i http://server/path/stream.m3u8 -c copy -f flv "rtmp://FMSserver/app/streamName live=1"

5. Record a stream endlessly rotating target file
 

Segmenting feature of FFmpeg can also be useful to create an endless recorder with rotating buffer. It can be done using the segment_wrap parameter that wraps around segment index once it reached a limit.

ffmpeg -i rtmp://INPUT -codec copy -f segment -segment_list out.list -segment_time 3600 -segment_wrap 24 out%03d.mp4
The previous commandline records endlessly the INPUT stream in a ring buffer formed by 24 chunk of 1hr video.Conclusionfollow me on twitter to know more about FFmpeg and video related topics (@sonnati).

[Index]

PART I – Introduction (revised 02-jul-2012)
PART II – Parameters and recipes (revised 02-jul-2012)
PART III – Encoding in H.264 (revised 02-jul-2012)
PART IV – FFmpeg for streaming (revised 02-jul-2012)
PART V – Advanced usage (revised, 19-oct-2012)
PART VI – Filtering (new, 19-oct-2012)

 

40 thoughts on “FFmpeg – the swiss army knife of Internet Streaming – part V

  1. Sonnati, is possible add to ffmpeg external library like MainConcept AAC+ codec or Fraunhofer? we have the SDK of this codecs… or the new libvo_aacenc is very good? we need improve our MP3 quality into audio files, for this reason we think to use HE-AAC+ in replace to MP3 codec

  2. Hi,
    This streaming to rtmp doesnt work on my pc running win 7 64 bit.. Do we need to have some server or some streamers installed to output the result of the stream to rtmp?
    What ever port i give it gives
    RTMP_Connect0, failed to connect socket. 10061 (Unknown error)
    rtmp://localhost:1212/app/streamName live=1: Unknown error occurred

  3. george, yes you need to have a publishing point where ffmpeg will push the video to. there are a few soltuions available out there, free and for sale. eg. FMS, Wowza or Red5.. for a start, i recommend Wowza. download it and use a free developper licence to learn the platform.

    to Mr Sonnati:

    First of all, id like to thank you for the usefull post. i learned much more than reading the ffmpeg website for hours.

    One issue that you didnt discuss, is how to monitor ffmpeg because it crashes when the connection to the stream drops out.

    Can ffmpeg write the console output to a log file? if yes, then i can run a script to tail it, and restart it when an error message our download complete msg comes up in log? will the log file grow too big? do you recommend a better solution?

    Regards,
    M J

    1. the best would be to create a control process that can kill and restart ffmpeg if it crashes.
      A coarser solution is to write an infinite loop in sh or dos so that if an istance (an iteration) of ffmpeg crashes, there’s always new one ready to start

      1. hi, i forgot to mention that im using rtmpdmp with ffmpeg. Normally, rtmpdump is the process that crashes. i managed to create simple sh scripts to monitor the processes.
        script 1: loop.sh
        period=${1:-60}
        while :
        do
        sleep $period &
        sh rtmpdump.sh
        wait
        done

        (this is infinite loop that launches rtmpdump check script every 60 seconds)
        script 2: rtmpdump.sh
        pgrep rtmpdump
        if [ $? -ne 0]
        then killall ffmpeg
        rtmpdump …………… | ffmpeg -i – …………
        fi

        also, i can make a third script called ffmpeg.sh that also runs and kills rtmpdump if ffmpeg is dead and restarts the whole proces

  4. Hi Sonnati… I just want to say thanks for this…:) I have one question for you if you have time.
    I used some of yours methods above to transcode live stream. I’m transcoding just the sound, but after some time on a console a get invalid droping msg in yelow. After that the stream is late for about 8 seconds…I use this to transcode stream to phone, and phone has a buufering that i can change for 5 sec and when we add this it get to a 10 sec delay…this is not acceptable for a live coverage, don’t you agree?! 🙂 Can you help me??? I use this command: ffmpeg -i rtmp://xxx.xxx.xxx.xxx:1935/live/name -c:a libvo_aacenc -b:a 96k -ar 44100 -vcodec copy -f flv rtmp://xxx.xxx.xxx.xxx:1935/live/name

  5. Hi
    In your article – Item 3 entitled ‘Joining Video’ has the 3rd line as:
    ffmpeg -i concat:”100.h264|200.h264″ -i in.mp3 -c copy out.mp4

    Where does the file “in.mp3” come from – is this an error?

    I have a need to often simply delete say three 1 minute segments from a 20 minute video
    like removing adverts (could be mp4,avi wmv etc) but I can’t find an easy way to do it

    What would be your best suggestion?

    Thanks for your efforts, your site is really useful
    cheers
    Stuart

    1. You’ll have to use option -ss of ffmpeg to skip some parts of the world input. Like this:

      ffmpeg -ss 9 -i input.m4v -codec copy output.m4v

      Will skip 9 seconds of input and then copy the rest of the content to output. This might not be very precise because of key frames but it works.

      1. in the last versions of FFmpeg even -ss before -i is mostly frame accurate (seeks fast via keyframe and then decode frame by frame up to the desired).
        The oldf behavioud can still be obtained using -noaccurate_seek

      2. The -ss is accurate if you are transcoding (reencoding). If you are simply copying the streams (as my example) it will cut on key frames only.

  6. Nice article. I have a question if i may, i need to place some unique piece of info inside a video and then parse the streaming of that video and locate this piece of info. What is the best approach according to your experience?

  7. Hey sonnati,
    ~
    I read your very good tutorial hoping that by the “Advanced” chapters I would learn about how to extract the timing metadata necessary to synch a text transcript file to the target video/audio
    ~
    Could you tutor us or suggest related readings on those topics?
    ~
    thanks
    lbrtchx

  8. I am receiving a live rtmp stream from a fms server which switches input streams now and then from different sources. I guess each time it switches this is treated as a new stream; the time code of the stream is reset and starts from 0 or something. What happens is that when ffmpeg receives this stream it simply stops when this switch happens. Does anyone know if there is a way to keep ffmpeg just listening and receiving indefinitely, even if there are such interruptions/switches?

  9. Any way to implement reconnect if the rtmp goes down for couple of seconds.Ffmpeg terminates the stream and stops itself. There is no retry option.. I learned a lot from ur blogs.thanks…

  10. Copy/paste for some ffmpeg commands is not working very well..
    In fact the “-” sign seems to be different, it is not a “normal” – sign used for specifying parameters to command line. It makes ffmpeg error in very very strange ways. Took me a lot of time to figure it out 🙂
    In any case thank you for a brilliant tutorial!

    1. Quote
      “FFmpeg support the generation of HDS and SmoothStreaming compliant file and manifes but not HLS files and Manifest”

      Can you post an example?

      Is it possible create HDS files ( .f4m, .f4x, .f4m ) from an mp4 format?

  11. libfaac was not “extracted” from the FFmpeg code, but is and was always a third party library. libfaad on the other hand has been dropped (starting from release 0.8) in favor of the native decoder.

    The internal aac encoder is marked as experimental, as it provides a worse quality than that that you can achieve with libfaac or other external libraries.

  12. if I grep ffmpeg for -segment_wrap this doesn’t seem to be an option. Do I need a specific build of ffmpeg?

    Learning loads from this blog, thank you sonnati.

  13. Nice tutorial, I want to publish the live stream from webcam using h264 codec with mulitibitrate, can any one provide me the sample command? any help is appreciated, thanks in advance

  14. Hi Fabio

    I run an FMS server that takes Live RTMP streams ( originated in FMLE) from various wild life cameras and sends them out as HDS and HLS streams to Highwinds CDN for distribution. We have been getting a lot of requests to support RTSP based IP cameras as well as some MxPEG cameras from Mobotix and was wondering if FFMpeg would be able to run on the same server as the FMS and feed take in the RTSP and output an RTMP stream to the FMS? I would like to avoid having to use Evostream as all our customers are charities and very price sensitive. In an ideal world we would have used Wowza instead of FMS but at the time Highwinds could not handle the Wowza manifests. I would be grateful for any pointers. Great tutorial by the way, very informative.

    Cheers

    Peter

  15. Great article!!

    How could you run the FFmpeg.exe as a background process without a window? Can you run upwards of 50 of these processes with the most CPU and memory efficiency?

  16. ” ffmpeg -i udp://INPUT -codec copy -f segment -segment_list out.list -segment_time 3600 -segment_wrap 24 out%03d.mp4 ”

    i tried this command line(and various other approaches) to record the live udp stream in chunks of 60 sec, but every time i am getting the same error
    ” Output file #0 does not contain any stream ”

    Any assistance from your side will be appreciated. Thanking you in advance.

  17. Nice artical, while recording HLS stream using ffmpeg I am getting error “unable to open key file” is there any way to record HLS encrypted stream by passing address of key file and posting credentials

  18. Hi,
    The article looks good. However, my requirement is different. As you all know Android 4.1 does not support Flash, I want to stream live video from Android mobile to other Android mobiles. These days many Android phones have Android 4.1 or greater. So how to send live streams from Android 4.1 video camera and allow other Android phones to see live video streams?

    I want to use FMS 4.5 for this feature. Please help me.

  19. Only you can help me !!! My scenario is that i’ve a rtsp video stream from a DVR and i want combine audio coming from a “mic in” of audio card of pc running ffmpeg and publish audio and video on web, possibly compatible with everything ….(quicktime?)
    Thanks

  20. Hello Fabio

    I’m transmitting live streaming whith the following code:
    ffmpeg -video_size 320×240,”-f “dshow -i “video=”namecam”:audio=”nameMic” -map 0 -c:a libvo_aacenc -r:a 22050 -b:a 48k -c:v libx264 -b:v 200k -r:v 29.97 -s 480×360 -f flv rtmp://server/……
    When the transmission is from a dinamic source like a tv channel, the transmission is perfect.
    When I’m streaming a video that show’s an empty room (static) and at some point many people start entering the room (dinamic), the streaming become desynchronized and show’s delayed frames.
    The transmition become unstable and the video looses quality to all user’s.

    Can you help me solve this issue?

    Thank’s for your time.

  21. Hello Sonnati,

    How can I do HLS stream monitoring using ffmpeg ? please advise.

    Thank’s for your time.

  22. Hi,

    how can we resume streaming after a live input is lost, for example, due to temporary network failure and then resumes after a few seconds?
    Currently we get “Delay between the first and the last packet in the muxing queue is 10100000 > 10000000: forcing output” message repeated all over and the sound is “scratchy” although the input stream is available again.
    Thanks for any ideas.

  23. sorry I would like to tell you the truth that point (4. Use an HLS stream as source ) doesn’t executed . and it gives me an error:

    “[flv @ 00000000058b76c0] Malformed AAC bitstream detected: use the audio bitstr
    am filter ‘aac_adtstoasc’ to fix it (‘-bsf:a aac_adtstoasc’ option with ffmpeg)
    av_interleaved_write_frame(): Invalid data found when processing input
    [flv @ 00000000058b76c0] Malformed AAC bitstream detected: use the audio bitstr
    am filter ‘aac_adtstoasc’ to fix it (‘-bsf:a aac_adtstoasc’ option with ffmpeg)
    frame= 2 fps=0.0 q=-1.0 Lsize= 25kB time=00:00:00.07 bitrate=2593.9kbit
    /s
    video:25kB audio:1kB subtitle:0kB other streams:0kB global headers:0kB muxing o
    erhead: unknown ”

    Could you help ?

  24. I am trying to start an FFMPEG recording of a live HLS stream with a DVR window at a particular start time. I can record from the beginning of the DVR window with this command:
    ffmpeg -i http://dev.myamsserver.com/hls-live/my-live-packager/turmeric/liveevent/turmeric_1000_live.m3u8 -y -r 29.97 -threads 0 -hls_list_size 0 -c:v copy -c:a copy out.m3u8
    However, if I add a -ss for either the input or the output, I get a steady stream of errors saying “non-existing PPS referenced” and “invalid stream index 1”
    Do you have any suggestions on how to get around this? Thanks!

  25. This is a great tutorial, and even though its a bit dated to the progress FFMPEG has undergone since 2012, it helped me more than anything else I have found on the web.

    However, I am wondering if you have kept up-to-date with what is going on with FFMPEG and closed captioning. We are a broadcaster, and we have heavy mandates to caption most anything we stream. We are currently streaming from a video source (1080i over SDI, with embedded 708 captions in the VANC), or from an UDP stream, to RTMP. I know that closed captioning support has been added to FFMPEG, but it is still in its infancy. Any light you can shed on this subject is much appreciated!

  26. Hello Fabio

    I am saving a file from a live HLS3 source using the following command line –

    ffmpeg.exe -report -v 9 -loglevel 99 -re -i http://admin:admin@10.0.0.236:8082/stre … /live.m3u8 -codec copy “astream200_20160302064045.566.mp3”

    We find that although it creates the output file it does not write anything to the file. It writes to the file only when we close the ffmpeg process.

    My assumption would be that it is buffering the data and writes only when we close the process.

    Is there anyway to specify a zero buffer size so that it writes to the file as it starts with the segment file.

    Thanks

  27. The best AAC encoder available on some builds of ffmpeg is the Fraunhofer one, extracted from Android source code. Use it like this:

    ffmpeg -i audio.wav -c:a libfdk_aac -vbr 5 output.m4a

Leave a reply to sonnati Cancel reply