<p>
Nginx is a web server with interesting modules to extend its functionality.<br />
The Real Time Messaging Protocol (RTMP) is used to send video (& audio) streams<br />
over the internet. Nginx offers a RTMP media streaming module.
</p>
<p>
Many action cams and drones support sending their video streams via RTMP.
</p>
<p>
This page is focused on the configuration of RTMP on Nginx.
</p>
<h3>Contents</h3>
<ul>
<li><a href="#install">Installation</a></li>
<li><a href="#config">RTMP configuration example</a>
<li><a href="#publish">Publishing a stream with FFmpeg</a></li>
<li><a href="#hls">HTTP Live Streaming (HLS)</a></li>
<li><a href="#links">External links</a></li>
</ul>
<h3 id="install">Installation</h3>
<pre><code class="language-bash">sudo apt install nginx libnginx-mod-rtmp
</code></pre>
<h3 id="config">RTMP configuration example</h3>
<dl class="file">
<dt><code class="filename">/etc/nginx/nginx.conf</code></dt>
<dd><pre class="file"><code class="language-nginx">#...
# For rtmp, worker_processes needs to be 1, which is the default.
#worker_processes auto;
#...
rtmp {
server {
listen 1935;
# Who is allowed to connect can be handled with
# HTTP response status codes.
#on_connect http://example.net/rtmp_auth;
application live {
live on;
hls on;
hls_path /tmp/hls;
dash on;
dash_path /tmp/dash;
}
}
}
http {
#...
server {
listen 8080;
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
}
root /tmp;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
location /dash {
types {
application/dash+xml mpd;
}
root /tmp;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
}
}
#...
</code></pre>
</dd>
</dl>
<p>
Reload the configuration:
</p>
<pre><code class="language-bash">sudo systemctl reload nginx
</code></pre>
<h3 id="publish">Publishing a stream with FFmpeg</h3>
<p>
The following command creates a stream named <code>stream</code> in<br />
the configured application <code>live</code>:
</p>
<pre><code class="language-bash">ffmpeg -re -i input.mp4 \
-c:v libx264 -c:a aac \
-f flv rtmp://example.net/live/stream
</code></pre>
<p>
Receive the stream from the RTMP server and show it on screen:
</p>
<pre><code class="language-bash">ffplay -fflags nobuffer rtmp://example.net/live/stream
</code></pre>
<h3 id="hls">HTTP Live Streaming (HLS)</h3>
<dl class="file">
<dt><code class="filename">hls.html</code></dt>
<dd><pre class="file"><code class="language-xml"><!DOCTYPE html>
<html lang="en">
<head>
<title>HTTP Live Streaming</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>
<video id="video" controls></video>
<script>
var video = document.getElementById('video');
var videoSrc = 'http://example.net:8080/hls/stream.m3u8';
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(videoSrc);
hls.on(Hls.Events.MEDIA_ATTACHED, function () {
video.muted = true;
video.play();
});
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = videoSrc;
}
</script>
</body>
</html>
</code></pre>
</dd>
</dl>
<p>
HTTP Live Streaming (HLS) adds a delay / latency of approx. 10 to 60 seconds<br />
to the live input stream.
</p>
<h3 id="links">External links</h3>
<ul>
<li><a href="https://www.nginx.com/products/nginx/modules/rtmp-media-streaming/" target="_blank">
https://www.nginx.com/products/nginx/modules/rtmp-media-streaming/</a></li>
<li><a href="https://github.com/arut/nginx-rtmp-module/wiki/Directives" target="_blank">
https://github.com/arut/nginx-rtmp-module/wiki/Directives</a></li>
<li><a href="https://trac.ffmpeg.org/wiki/StreamingGuide" target="_blank">
https://trac.ffmpeg.org/wiki/StreamingGuide</a></li>
<li><a href="https://github.com/video-dev/hls.js/#embedding-hlsjs" target="_blank">
https://github.com/video-dev/hls.js/#embedding-hlsjs</a></li>
<li><a href="https://github.com/Dash-Industry-Forum/dash.js#standard-setup" target="_blank">
https://github.com/Dash-Industry-Forum/dash.js#standard-setup</a></li>
</ul>