Hostwinds Tutorials
Search results for:
Table of Contents
Tags: VPS
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.
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.
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.
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
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
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
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
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.
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;
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;
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, 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
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
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.
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.
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