In this post I’m going to show you how to use Nginx’s RTMP module to stream a live video (over RTMP) from your desktop and then play it back with HLS. I’ll also cover how to encrypt the video.
RTMP was initially a proprietary protocol by Adobe for streaming video and audio between a Flash player and a server but is still widely used today for broadcasting video despite the demise of Flash.
I built the RTMP module on Ubuntu 18.04 but the installation instructions should work for any Debian-based Linux distribution.
The first thing to do is install Nginx if you haven’t already. You can install it from your distribution’s default package repositories but the provided version is usually outdated. A better option is to install it from the official Nginx repository. The current stable version is 1.18.
To install Nginx, run the following command:
$ sudo apt install nginx
To build the RTMP module, first install the required dependencies then check out the source code of the module. We also need the source code of the version of Nginx that is installed. To build the module, run the following commands:
$ sudo apt install build-essential dpkg-dev libpcre3 libpcre3-dev libssl-dev zlib1g zlib1g-dev
$ git clone https://github.com/arut/nginx-rtmp-module.git
$ apt-get source nginx
$ cd nginx-1.18.0/
$ ./configure --with-compat --add-dynamic-module=../nginx-rtmp-module
$ make modules
$ sudo cp objs/ngx_rtmp_module.so /etc/nginx/modules/
This will build the RTMP module as a dynamic module. To load the module at runtime, add the following line to the Nginx configuration file (
Now that Nginx has been installed and the RTMP module has been built, we need to configure it.
The first thing we need to do is define an RTMP section in the Nginx configuration file:
The server will listen for connections on port 1935. Within the server block, we define an application called
live. (You can call it whatever you like, I just happened to called it
live.) We’ll refer back to this later on when we start streaming. To enable HLS, set
on. The next two parameters determine the location where the playlist and the segments will be written and the segment duration. In this instance, the playlist and segments are written to the
/srv/www directory and the segment duration is set to 6 seconds.
To enable encryption (optional) set
on. The next two values specify the directory where the keys will be written, and the base URL of the keys. Finally, we specify the key rotation period. This determines how many segments are encrypted with a key before a new key is generated. For example, if
hls_fragments_per_key is set to 10 and the segment duration is 6 seconds, the encryption key will be rotated every minute.
The next step is to configure Nginx to serve the HLS playlist and segments. We do that by defining an http block in the configuration file:
The root location is set to
/srv/www, which you’ll recall is the same location where the playlist and segments are written to. The
expires parameter (line 48) specifies how long the playlist and the segments can be cached for, which is determined by looking up the value from a map based on the content type (line 38). In this case, the expiry time of the playlist (
application/vnd.apple.mpegurl) is set to some time in the past (
epoch) so it won’t be cached. Segments can be cached for 24 hours.
Note: Everything is served over HTTP. If you are encrypting the video then you should serve the keys over HTTPS. This is left as an exercise for the reader.
To start Nginx, run the following:
$ sudo nginx
The next step is to prepare the live stream.
Preparing the Live Stream
If you want to stream the output of a webcam, I suggest downloading and installing OBS Studio. Alternatively, you can use
ffmpeg to “live” stream a video.
However you decide to set-up your live stream, the format of the RTMP URL is the same. It must be in the following format:
rtmp://<host>/<application name>/<stream key>
The host is either the IP address or the name of the server. As we are running it locally, it will be
localhost.The application name must match the name in the Nginx configuration file, which in this example is
live. The stream key can be anything – we’ll use
test – and is used by the RTMP module to name the playlist and the segments. For example, if the stream key is
test the playlist will be called
test.m3u8 and the segments will be
test-2.ts, and so on.
Here’s an example of how to use
ffmpeg to stream a video over RTMP:
$ ffmpeg -re -i big_buck_bunny_720p_h264.mov -c copy -f flv rtmp://localhost/live/test
Start the live stream. After a few seconds you should see some files in
Next, copy the following HTML and save it as
index.html in the
(If you are using a different stream key, you’ll need to change the name of the playlist in the HTML.)
To play the live video, open up a browser and navigate to http://localhost/.
If you have any questions, feel free to leave a comment.
finally! someone that shows it’s possible for nginx-rtmp-module to be configured as a dynamic module and not just copy-pasting the same old crap being passed around that has everyone compiling and installing nginx by source?@ imagine!
so thank you, really!
It’s a great tutorial, everything worked like a charm
Is there a way to make the player autostart, immediately after loading or after a short predefined delay.
Note the word autoplay when creating the element
Thank you for this!
This is a great tutorial I have been searching for, thank you very much.
Please my question is, how do I separate the Html file from the root directory? I’m asking this question because am using django as my backend so I want to connect the backend to the streaming server. Thank you.
Create the HTML page in your Django application and then change the URL to the location of the playlist on your streaming server, e.g.
<source src="https://<your streaming server>/test.m3u8" type="application/vnd.apple.mpegurl"/>.
how do we generate the keys or do we not need to isit automatic?