Broadcast online video using nginx

    What is online video?


    By the term online video I understand the continuous broadcasting of some kind of live video signal (for example, from a television studio). Traditional means of video output (flv- and mp4-streaming) in this case do not work, simply because the file containing the entire video stream does not exist.

    This article will not focus on the organization of video hosting, but on the organization of live video broadcasting. These are two fundamentally different tasks, and usually the methods for solving them differ significantly from each other.

    RTMP protocol


    RTMP - Real Time Messaging Protocol ( Wiki ) - A protocol that is commonly used to distribute live video and audio content to clients. It is convenient because AS3 has its support out of the box, it does not require too many resources on the client, and it supports a lot of goodies (for example, broadcasting with variable bitrates and switching clients to higher quality if there is a free channel).

    NB: In addition to RTMP, there are a number of other protocols for broadcasting media streams (RTSP, Apple HTTP Live Streaming, etc.), but they are not considered in this article.


    The RTMP protocol is the brainchild of Adobe. The only official server that can broadcast an RTMP stream is Adobe Flash Media Server. Unfortunately, its price and performance leave much to be desired, so various developers have attempted to create more or less compatible alternative implementations of the protocol. Unfortunately, the RTMP protocol has known problems with licensing, for example, its official specification, if strictly followed, does not allow you to write a working RTMP server. However, there are several implementations:

    • Red5 - one of the first RTMP servers written in Java
    • Wowza is a proprietary RTMP server written in Java. In addition to RTMP, it also supports RTSP, Apple HLS, and Smoothstreaming (Silverlight).
    • erlyvideo is a free RTMP server with separately distributed proprietary modules written in Erlang. The project is written by Russian programmers and is actively developing.


    Java slows down


    In the tests I conducted, Red5 and Wowza showed indecently poor performance. With a megabit video stream, Wowza with 1000 viewers online consumed about 300% of the processor time (Intel Xeon E5607). If you want to broadcast at least 20,000 people online, you need to purchase 20 servers? It's too expensive.

    What to do?


    Use non-blocking operations. Brakes in Wowza and Red5 follow because of the far from the most optimal event handling scheme. To implement a really fast streaming server, you need to use an effective event processing method (for linux it is epoll). This is exactly the scheme of work that Roman Harutyunyan ( blog , github profile , rarutyunyan ) implemented in his RTMP server , implemented as a module for nginx.

    nginx-rtmp-module


    Advantages:
    • Unreal fast. On the same physical server that I used for Wowza tests, nginx withstood 2500 megabit connections per core, i.e. 10000 for the whole server.
    • Convenient configs :). After kilometers of Wowza XML configs, these look like a bailout.
    • Responsiveness of the author to feature quests.


    Disadvantages:
    • The project is young, there are bugs, which, however, are quickly corrected.
    • Little functionality. The server broadcasts only in RTMP, transcoding appeared just a few days ago, has experimental status and is actually a wrapper over ffmpeg. UNIX way in all its glory.
    • No multithreading. The module can only work if nginx is started with one worker. To dispose of all processor cores, you need to run several workers on different IP addresses and / or ports.


    Multithreading can be implemented using something like this crutch (Ubuntu):

        for ip in $(cat /etc/network/interfaces | grep address | awk '{print $2}') ; do
            touch /etc/nginx/nginx.$ip.conf
            cp /etc/nginx/nginx.conf.skel /etc/nginx/nginx.$ip.conf
            sed -i "s/%IPADDR%/${ip}/g" /etc/nginx/nginx.$ip.conf
            /usr/sbin/nginx -c /etc/nginx/nginx.$ip.conf
        done
    


    In this case, you should have written the skeleton of the config indicating% IPADDR% instead of the IP address. For example, this:
    worker_processes  1;
    error_log   logs/error.%IPADDR%.log debug;
    pid /var/run/nginx.%IPADDR%.pid;
    worker_rlimit_nofile 65536;
    events {
        worker_connections  16384;
    }
    rtmp {
            server {
                    listen %IPADDR%:1935;
                    chunk_size 4000;
                    application live {
                            live on;
                            pull live stream %masterIP%;
                    }
            }
    }
    http {
            server {
                    listen %IPADDR%:8080;
                    location /stat {
                            rtmp_stat all;
                            rtmp_stat_stylesheet stat.xsl;
                    }
                    location /stat.xsl {
                            root /srv/nginx/html;
                    }
            }
    }
    


    However, the author promises to implement normal multithreading in future releases.

    Using nginx-rtmp-module, I was able to completely utilize the 10 gigabit channel. At the same time, the main problem was not the gluttony of nginx itself, but the need for tuning the network card and kernel parameters so that software interrupts did not eat 100% of the CPU.

    Related links:


    RTMP on Wikipedia
    Wowza - official site
    Erlyvideo - official site
    Nginx-rtmp-module - project on GitHub

    Also popular now: