Optional HLS cleanup

Today I’ve added a new directive hls_cleanup toggling HLS fragment and playlist cleanup from nginx cache manager process. By default cleanup is on. Now you can turn it off and have plain MPEG-TS chunked recorder.

application myapp {
    live on;
    hls on;
    hls_path /tmp/hsls;
    hls_cleanup off;



Simple pull/push DNS load-balancing in 0.9.19

Simple DNS load-balancing is implemented in 0.9.19. When remote host name is resolved to multiple addresses then stream is pulled or pushed sequentially from all those addresses.

application myapp {
    live on;
    pull rtmp://video.example.com/someapp;

Suppose video.example is resolved to and When the first server is unavailable the next connection attempt will be made to the second server.

1 Comment

Dynamic pull and push in 0.9.19

Since 0.9.19 version of nginx-rtmp-module you can dynamically pull or push streams with on_play and on_publish. 3xx HTTP result code used to redirect current stream. Now if the new stream name is started with rtmp:// then it’s supposed to be RTMP URL and relay (pull/push) is created for the current client.

http {
    location /local_redirect {
        rewrite ^.*$ newname? permanent;
    location /remote_redirect {
        # no domain name here, only ip
        rewrite ^.*$ rtmp:// permanent;

rtmp {
    application myapp1 {
        live on;
        # stream will be redirected to 'newname'
        on_play http://localhost:8080/local_redirect;
    application myapp2 {
        live on;
        # stream will be pulled from remote location
        # requires nginx >= 1.3.10
        on_play http://localhost:8080/remote_redirect;

In the example above myapp1 uses old redirect behavior, myapp2 shows the new feature.

In myapp2 application source stream name is not changed and pull is created for the source stream name. Later clients connecting to this stream will see the video pulled by the first client. That’s identical to usual pull behavior. You can change it however by specifying notify_relay_redirect on. This will redirect pulled stream to a new (long url-like) local name. So the streams will be grouped on rtmp url.

on_publish does the same for push operation.

The feature has 2 limitations

  • RTMP URL should not contain domains names, only IP addresses
  • nginx version>=1.3.10 is required


Time argument in on_update

New time argument has been added to on_update handler. It’s the number of second since play/publish call. With this you can limit client playback or publish time.

Leave a comment

Updated HLS in 0.9.18

New HLS in 0.9.18 includes the following updates

  • Directory-per-stream mode: hls_nested on
  • Automatic asynchronous fragment erasing. Fragments and playlists are erased automatically after timeout has expired from nginx cache manager process
  • Fixed iPhone playback
  • Introduced HLS discontinuities on stream restart
  • Three fragment naming modes: hls_fragment_naming sequential|timestamp|system
  • Two fragment slicing modes: hls_fragment_slicing plain|aligned. Aligned mode creates ts fragments aligned to incoming timestamp boundaries.
  • Max fragment size limitation to escape giant fragments
  • Smaller fragment size
  • Fractional durations described in HLSv3 specs for better seeking
  • Fragment duration and discontinuity recovery on stream restart
  • Always new fragment files, no fragment reuse


Setting file name pattern in recorder

In the latest master it’s possible to set strftime-compliant pattern when specifying record_suffix value.

recorder rec1 {
    record all;
    record_interval 5s;
    record_suffix -%d-%b-%y-%T.flv;
    record_path /tmp/rec;

This config will produce files of the form mystream-24-Apr-13-18:23:38.flv. Full list of supported strftime format options you can find on strftime man page.

Leave a comment

Shell-style exec redirects in 0.9.17

The new feature is shell-style redirects in exec-family directives. Now you can save ffmpeg (or any other executed child) output in file and pass input to it (makes no sense with ffmpeg however).

    application myapp {
        live on;
        exec ffmpeg -i rtmp://localhost/myapp/$name -c copy 
                    -f flv rtmp://example.com/myapp/$name 2>>/var/log/ffmpeg-$name.log;

Now you have a single log file like /var/log/ffmpeg-mystream.log for each stream where you can find all ffmpeg output including errors. You can redirect stdout (1>/var/log/ffmpeg-$name.out) and any other stream (1>&2) as well. Both truncate > and append >> modes are supported as well as usual variable substitutions .