Hostwinds Tutorials

Search results for:


Table of Contents


What is RTMP?
Installation
Install Dependencies
Download Software
Compile Software
Configuration
Multiple Applications
Permissions
Re-Encoding
Pushing to Other Services
HLS
HLS Playback
SSL
Other Configurations
Streaming

Live Streaming from a VPS with Nginx + RTMP

Tags: VPS 

What is RTMP?
Installation
Install Dependencies
Download Software
Compile Software
Configuration
Multiple Applications
Permissions
Re-Encoding
Pushing to Other Services
HLS
HLS Playback
SSL
Other Configurations
Streaming

Whether you 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 stream from pre-recorded videos, a good method to do so is with a server running Nginx compiled with the RTMP module.

Live streaming uses a lot of bandwidth. The exact bandwidth uses on the number of streams, as well as their bitrate.

Reducing the bitrate of the video encoding can reduce your bandwidth usage at the cost of video quality.

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

This guide uses CentOS 7 as the operating system of the server.

Nginx + RTMP can be configured on other Linux distributions and follows the same instructions, using the other distributions' package manager and default file paths.

Install Dependencies

Update your system

yum update -y

Install CentOS development tools

yum groupinstall -y 'Development Tools

Install EPEL repository

yum install -y epel-release

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

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

Create or go to a working directory

cd /usr/local/src/

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

Clone the Nginx RTMP Module from here

git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git

Remove unneeded tar files

rm -f *.tar.gz

Compile Software

Move into your downloaded Nginx folder

cd nginx-1.17.0/

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

Compile Nginx

make

Install Nginx

make install

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 told 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 your server's IP or domain address, 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 can stream to the server and what IPs can play the stream from this server.

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

Using "allow" or "deny" specifies whether the rule allows or denies the connection from the specified source.

Using "publish" specifies that the source location can 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 connecting to this server. Otherwise, you can set a specific IP address.

Putting the permission rule in the server { } block makes the ruling global across all applications. Putting the permission rule in an 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 allow streaming to multiple platforms at once essentially.

HLS

HLS, or HTTP Live Streaming, is a fairly popular format 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 make sure the hls_path directory exists by running the command:

mkdir -p /mnt/has/live

You can change /mnt/hls/$app to any folder path that you want. $app will be replaced with the application's name (in this case, "live").
This will be the location the HLS .m3u8 files will be saved to.

You may also adjust the hls_fragement and hls_playlist_length values to suit your needs.
2s and 4s are the values we found to work the best when streaming with a 2-second keyframe interval.

Then you also need to add an 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;
    }
}
}

You can change the ports listed in the listening to statements to any port you want to serve the video from. If you do change the port away from the standard HTTP/S ports (80 & 443), then you will need to specify the port after the server address in the following format: HTTP://{server_address}:{port}.

Example: http://example.com:8080/

Afterward, saving those changes to your Nginx configuration file, 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 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 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 to 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

If you do not have an SSL certificate for your domain, you can use Let's Encrypt to receive a free certificate.

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 supporting streaming to an RTMP address. You may consider using OBS as very powerful, has plugin support, is popular with a large community, and is open.

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."

Providing a unique secret key will ensure that the stream 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.

Written by Hostwinds Team  /  June 18, 2019