Skip to content


Subversion checkout URL

You can clone with
Download ZIP
NGINX-based Media Streaming Server
C XSLT Other
branch: vod-http

This branch is 533 commits behind master

Failed to load latest commit information.
doc implemented encrypted handshake
hls fixed pts assignment while synchronizing hls
test changed capture codecs to h264/speex
AUTHORS improved frame timing & added meta files
LICENSE improved frame timing & added meta files updated README
ngx_rtmp.h added 'busy' directive
ngx_rtmp_access_module.c fixed compilation
ngx_rtmp_amf.c Merge remote branch 'origin/safe-amf-parser' into video-on-demand
ngx_rtmp_auto_push_module.c fixed push & pull in auto-push mode
ngx_rtmp_bandwidth.h implemented http/xml/xsl RTMP stats
ngx_rtmp_cmd_module.h merged pause into video-on-demand
ngx_rtmp_codec_module.c fixed AAC header parser
ngx_rtmp_control_module.c implemented connection dropped in control module
ngx_rtmp_enotify_module.c added closing descriptors in enotify module
ngx_rtmp_eval.h added all required arguments to old-style & new-style exec
ngx_rtmp_flv_module.c implemented common base for video-on-demand: added flv & mp4 modules …
ngx_rtmp_handler.c added 'busy' directive
ngx_rtmp_init.c fixed bad-looking unix socket client name
ngx_rtmp_mp4_module.c fixed mp4 b-frame delay
ngx_rtmp_netcall_module.c vod-http is now working
ngx_rtmp_notify_module.c vod-http is now working
ngx_rtmp_play_module.c fixed uri in vod-http
ngx_rtmp_play_module.h vod-http is now working
ngx_rtmp_record_module.c Merge branch 'control'
ngx_rtmp_record_module.h Merge branch 'control'
ngx_rtmp_relay_module.c fixed push & pull in auto-push mode
ngx_rtmp_relay_module.h fully tunable auto-push feature
ngx_rtmp_send.c fixed vod stopping: added NetStream.Play.Complete meta message
ngx_rtmp_shared.c implemenmted several optimizations
ngx_rtmp_stat_module.c added pid to stat
ngx_rtmp_streams.h added AMF shortcuts & project-wide stream numbers; updated mp4 streamer
stat.xsl added pid to stat

NGINX-based RTMP server


Project blog:

Wiki manual:


  • Live streaming of video/audio

  • Video on demand FLV/MP4

  • Stream relay support for distributed streaming: push & pull models

  • Recording streams in multiple FLVs

  • H264/AAC support

  • Online transcoding with FFmpeg

  • HLS (HTTP Live Streaming) support; requires recent libavformat (>= 53.31.100) from ffmpeg (

  • HTTP callbacks (publish/play/record etc)

  • Running external programs on certain events (exec)

  • Advanced buffering techniques to keep memory allocations at a minimum level for faster streaming and low memory footprint

  • Proved to work with Wirecast,FMS,Wowza, JWPlayer,FlowPlayer,StrobeMediaPlayback, ffmpeg,avconv,rtmpdump,flvstreamer and many more

  • Statistics in XML/XSL in machine- & human- readable form

  • Linux/FreeBSD/MacOS


cd to NGINX source directory & run this:

./configure --add-module=<path-to-nginx-rtmp-module>
make install

RTMP URL format:


app - should match one of application {} blocks in config

name - interpreted by each application can be empty

Multi-worker live streaming

Module supports multi-worker live streaming through automatic stream pushing to nginx workers. This option is toggled with rtmp_auto_push directive.

Example nginx.conf:

rtmp {

    server {

        listen 1935;

        chunk_size 4000;

        # TV mode: one publisher, many subscribers
        application mytv {

            # enable live streaming
            live on;

            # record first 1K of stream
            record all;
            record_path /tmp/av;
            record_max_size 1K;

            # append current timestamp to each flv
            record_unique on;

            # publish only from localhost
            allow publish;
            deny publish all;

            #allow play all;

        # Transcoding (ffmpeg needed)
        application big {
            live on;

            # On every pusblished stream run this command (ffmpeg)
            # with substitutions: $app/${app}, $name/${name} for application & stream name.
            # This ffmpeg call receives stream from this application &
            # reduces the resolution down to 32x32. The stream is the published to
            # 'small' application (see below) under the same name.
            # ffmpeg can do anything with the stream like video/audio
            # transcoding, resizing, altering container/codec params etc
            # Multiple exec lines can be specified.

            exec /usr/bin/ffmpeg -re -i rtmp://localhost:1935/$app/$name -vcodec flv -acodec copy -s 32x32 -f flv rtmp://localhost:1935/small/${name};

        application small {
            live on;
            # Video with reduced resolution comes here from ffmpeg

        application mypush {
            live on;

            # Every stream published here
            # is automatically pushed to 
            # these two machines

        application mypull {
            live on;

            # Pull all streams from remote machine
            # and play locally
            pull rtmp://;

        # video on demand
        application vod {
            play /var/flvs;

        application vod2 {
            play /var/mp4s;

        # Many publishers, many subscribers
        # no checks, no recording
        application videochat {

            live on;

            # The following notifications receive all 
            # the session variables as well as 
            # particular call arguments in HTTP POST
            # request

            # Make HTTP request & use HTTP retcode
            # to decide whether to allow publishing
            # from this connection or not
            on_publish http://localhost:8080/publish;

            # Same with playing
            on_play http://localhost:8080/play;

            # Publish/play end (repeats on disconnect)
            on_done http://localhost:8080/done;

            # All above mentioned notifications receive
            # standard connect() arguments as well as 
            # play/publish ones. If any arguments are sent
            # with GET-style syntax to play & publish
            # these are also included.
            # Example URL:
            #   rtmp://localhost/myapp/mystream?a=b&c=d

            # record 10 video keyframes (no audio) every 2 minutes
            record keyframes;
            record_path /tmp/vc;
            record_max_frames 10;
            record_interval 2m;

            # Async notify about an flv recorded
            on_record_done http://localhost:8080/record_done;


        # HLS

        # HLS requires libavformat & should be configured as a separate
        # NGINX module in addition to nginx-rtmp-module:
        # ./configure ... --add-module=/path/to/nginx-rtmp-module/hls ...

        # For HLS to work please create a directory in tmpfs (/tmp/app here)
        # for the fragments. The directory contents is served via HTTP (see
        # http{} section in config)
        # Incoming stream must be in H264/AAC/MP3. For iPhones use baseline H264
        # profile (see ffmpeg example).
        # This example creates RTMP stream from movie ready for HLS:
        # ffmpeg -loglevel verbose -re -i movie.avi  -vcodec libx264 
        #    -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1 
        #    -f flv rtmp://localhost:1935/hls/movie
        # If you need to transcode live stream use 'exec' feature.
        application hls {
            hls on;
            hls_path /tmp/app;
            hls_fragment 5s;


# HTTP can be used for accessing RTMP stats
http {

    server {

        listen      8080;

        # This URL provides RTMP statistics in XML
        location /stat {
            rtmp_stat all;

            # Use this stylesheet to view XML as web page
            # in browser
            rtmp_stat_stylesheet stat.xsl;

        location /stat.xsl {
            # XML stylesheet to view RTMP stats.
            # Copy stat.xsl wherever you want
            # and put the full directory path here
            root /path/to/stat.xsl/;

        location /hls {
            # Serve HLS fragments
            alias /tmp/app;


# Multi-worker streaming
rtmp_auto_push on;

rtmp {

    server {

        listen 1935;

        chunk_size 4000;

        # TV mode: one publisher, many subscribers
        application mytv {
            live on;
Something went wrong with that request. Please try again.