Search The Hostwinds Guides Knowledge Base

Live Streaming from a VPS with Nginx + RTMP

Share This Article [TheChamp-Sharing]

Whether you simply want a server to act as a relay for you to be able to stream to multiple services at once, re-encode your video stream into different formats, resolutions, or bitrates, or to just stream from pre-recorded videos, a good method to do so is with a server running Nginx compiled with the RTMP module.

What is RTMP?

RTMP stands for Real-Time Messaging Protocol and is a common, standardized way many services (such as YouTube, Twitch, etc.) use, or at least offer, to broadcast video online.

Installation

Install Dependencies

  1. Update your system
    yum update -y
  2. Install CentOS development tools
    yum groupinstall -y 'Development Tools'
  3. Install EPEL repository
    yum install -y epel-release
  4. Install dependencies
    yum install -y wget git unzip perl perl-devel perl-ExtUtils-Embed libxslt libxslt-devel libxml2 libxml2-devel gd gd-devel pcre-devel GeoIP GeoIP-devel
  5. Add ffmpeg GPG key, and install ffmpeg
    rpm -v --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
    rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
    yum install -y ffmpeg ffmpeg-devel

Download Software

  1. Create or go to a working directory
    cd /usr/local/src/
  2. Get the latest version of Nginx from here
    wget https://nginx.org/download/nginx-1.17.0.tar.gz

    tar -xzvf nginx-1.17.0.tar.gz
  3. Clone the Nginx RTMP Module from here
    git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
  4. Remove unneeded tar files
    rm -f *.tar.gz

Compile Software

  1. Move into your downloaded Nginx folder
    cd nginx-1.17.0/
  2. Run the configuration script to add SSL and the RTMP module
    Update the --add-module file path as necessary to point to where you cloned the nginx-rtmp-module
    ./configure --with-http_ssl_module --add-module=../nginx-rtmp-module
  3. Compile Nginx
    make
  4. Install Nginx
    make install
  5. Start and enable Nginx
    systemctl start nginx
    systemctl enable nginx

Configuration

To configure the RTMP service, you need to add an RTMP section to your Nginx configuration file, which should be /etc/nginx/nginx.conf by default.

Add an RTMP section to the conf file as follows:

rtmp {
    server {
        listen 1935; # Listen on standard RTMP port
        chunk_size 4096;

        # Sample RTMP Application
        application live {
            live on;    # Enable listening for live streams to this application
            record off; # Do not record the stream
            meta copy;  # Copy the incoming metadata for the outgoing metadata
        }
    }
} 

In that configuration, we are simply telling the server to listen for any requests on port 1935 (the default port for RTMP), and specified an application called “live” to accept our streams.

This configuration is enough to have the server accept a stream, but there are further configurations you can set for additional functionality.

Then when you stream, you will set your destination as rtmp://server_address/application, where server_address is the IP or domain address of your server, and application is the name of the application you configured in the Nginx configuration (“live” in this example).

Example: rtmp://127.0.0.1/live

Multiple Applications

Within the server { } block, you can configure as many applications as you want. The only restriction in place is that each application must have a unique name.

Permissions

You can specify permissions for what IPs are able to stream to the server, as well as what IPs are allowed to play the stream from this server.

To add a permissions rule, add a line either within the server { } or a application { } block in the following format:

  

Using “allow” or “deny” specifies whether the rule is to allow or deny the connection from the specified source.

Using “publish” specifies that the source location is able to stream to this server. Using “play” specifies that the source location can playback a stream from this server.

Using “all” as the location acts as a catch-all for any address that connects to this server. Otherwise, you can set a specific IP address.

Putting the permission rule in the server { } block makes the rule global across all applications. Putting the permission rule in a application { } block applies the rule to only that application.

Examples:

  • Allow 127.0.0.1 to stream to this server, but deny any other sources:
    allow publish 127.0.0.1;
    deny publish all;
  • Allow playback to all sources except 127.0.0.1:
    allow play all;
    deny play 127.0.0.1;

Re-Encoding

You can use an exec statement from within an application { } block to execute a command. Using this method, you can pass the received RTMP stream to a video processor, such as ffmpeg, for encoding.

Example: Encode the received stream to a mp4 format and save it as a file

exec ffmpeg -i rtmp://localhost/$app/$name -c copy -f mp4 /path/to/file/$name.mp4;

Pushing to Other Services

You can push the stream from an application to another receiver simply by using the push statement.

For example, you can add the following statement to any application { } block to push the received stream to Twitch, using one of their ingest addresses (in this case the Seattle address). Just replace {stream_key} with your Twitch stream key.

push rtmp://live-sea.twitch.tv/app/{stream_key};

You can do the same for any other platform that offers RTMP ingest addresses you can stream to, and can even list multiple push statements to essentially allow streaming to multiple platforms at once.

HLS

HLS, or HTTP Live Streaming, is a fairly popular format to be able to stream video over the HTTP and HTTPS protocols, making it significantly easier to embed the stream into a web page.

To enable HLS, simply add the following statements to any of your application { } blocks.

hls on;
hls_path /mnt/hls/$app;
hls_fragment 2s;
hls_playlist_length 4s;

Then simply make sure the hls_path directory exists by running the command:

mkdir -p /mnt/hls/live

Then you also need to add a http { } block to your Nginx configuration. This block should be a top level block, on the same level as the existing rtmp { } block. This new block should be as follows:

http {
    # Disable server tokens
    server_tokens off;

    # Include MIME types
    include mime.types;

    # Set timeout limit
    keepalive_timeout 65;

    server {
        listen 80;      # HTTP IPv4
        listen [::]:80; # HTTP IPv6
        server_name example.com www.example.com # Your domain (RECOMMENDED BUT OPTIONAL)
        
        location / {
            # Disable cache
            add_header Cache-Control no-cache;

            # Enable CORS
            add_header 'Access-Control-Allow-Origin' '*' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length';

            # Allow CORS preflight requests
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }

            # Specify file type to be served (.m3u8)
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t;
            }

            # File location
            # Set to the same hls_path specified in the rtmp application
            root /mnt/hls;
        }
    }
}

Afterward saving those changes to your Nginx configuration file, simply restart Nginx by running the command:

systemctl restart nginx

HLS Playback

With HLS enabled, you can now embed the stream into your web pages using any video player that supports HLS playback, such as Video.JS or PlayerJS.

You will just provide your player with the source address in the following format:

http://{server_address}/{app_name}/{secret_key}.m3u8

{server_address} will be your IP or domain of your server, {app_name} will be the name of the application { } block you are streaming to, and {secret_key} will be the secret key you set in your streaming software (such as OBS).

Example:

http://example.com/live/secret_key.m3u8

SSL

You can serve HLS over HTTPS as well. To do so, you simply need to provide an SSL certificate and private key within the server { } block with the following statements:

ssl_certificate /path/to/certificate.pem;
ssl_certificate_key /path/to/privkey.pem;

The certificate must be for the domain that you have specified in the server_name statement.

You will then also need to edit/add the listen statements to listen on port 443 (the https port), and optionally force usage of SSL. The listen statements for that should be as follows:

listen 80 ssl;       # HTTP IPv4; force SSL
listen [::]:80 ssl;  # HTTP IPv6; force SSL
listen 443 ssl;      # HTTPS IPv4; force SSL
listen [::]:443 ssl; # HTTPS IPv6; force SSL

Other Configurations

There are plenty of other configuration statements you can add to expand the functionality of the RTMP module of the Nginx configuration.

The full documentation for what you can add and configure can be found here.

Streaming

After you’ve configured your server, you can stream from any video streaming software that supports streaming to an RTMP address. You may consider using OBS as it is very powerful, has plugin support, popular with a large community, and open source.

To stream to your server, all you have to do is set the stream destination as your server’s address, with the application name, and set a private key. The format for the server address should be as follows:

rtmp://{server_address}/{app_name}

{server_address} is your IP or a domain you have set to point to this server. {app_name} is the name of the application { } block that you set in the Nginx configuration. Following our example configuration from above, that application name would be “live”.

OBS stream settings

Providing a secret key that is unique will ensure that the stream itself is unique, even if other sources are streaming to the same application.

Following the example above, the stream will then be live at rtmp://example.com/live/secret_key, which you can pick up using any video playing that can open an RTMP stream, such as VLC.

Related Articles