Video delivery is still a live topic on the modern web. Most video traffic is carried by the large services, of course, but small specialized solutions still have their place. This article looks at what the Angie server offers for working with video streams.
Video version
A video version of this article is available on YouTube.
Video delivery on the web: the basics
At first glance, putting a video on a web page today is trivial: drop the video file on a server, put any player on the page and point it at that file.
In practice it is more complicated, and extra requirements appear:
- fast, convenient seeking within the video;
- watching a clip without downloading it in full;
- switching video quality based on available bandwidth;
- different formats and codecs for each device type;
- broadcasting a live stream;
- keeping server load under control (bandwidth, disks, CPU).
Video transport protocols and a range of codecs for compressing the video and audio streams exist to meet these requirements. At a minimum, we will use these protocols: RTMP, HLS, DASH.
Real-Time Messaging Protocol (RTMP) was one of the first protocols for delivering video on the web, written by Adobe for the Flash Video (FLV) format. Today it is mostly used to push a live stream to a server, where the stream is transcoded and distributed to clients. There are protected variants (RTMPS, RTMPE) that encrypt the stream.
HTTP Live Streaming (HLS) is a protocol from Apple for carrying video streams over HTTP. The source file is split into segments (.ts), and a playlist (.m3u8) is built for them. The client fetches the playlist and requests the segments it needs. HLS supports adaptive bitrate, works in browsers, and is widely used by video hosting services.
Dynamic Adaptive Streaming over HTTP (DASH) comes from MPEG (the Moving Picture Experts Group). It works like HLS: a playlist (.mpd) and a video split into fragments (.ts). It also supports adaptive bitrate, various video codecs (H264, H265, VP9, etc.), and delivers the fragments over HTTP.
Let's start with Angie's built-in video capabilities and its bundled modules.
What the built-in MP4 and FLV modules can do
The FLV module serves video starting from the timestamp given in the start parameter. As the name suggests, it works with the Flash Video (FLV) format. The flv directive can be enabled in a location context:
location /video/ {
flv;
}
The MP4 module offers more. Besides serving a selected fragment of a file (it supports both the start and end parameters), it can throttle video delivery relative to the file's bitrate. Here is an example that uses the MP4 module:
location ~ \.mp4$ {
mp4;
mp4_buffer_size 1M;
mp4_max_buffer_size 3M;
mp4_limit_rate 2;
mp4_limit_rate_after 10s;
}
The example creates a location based on a regular expression that matches files with the mp4 extension. The mp4 directive turns on processing of those files by the module, and we cap video delivery at two times the bitrate (mp4_limit_rate); the limit kicks in after the first 10 seconds of playback. The example also configures buffers for handling the files: initial (mp4_buffer_size) and maximum (mp4_max_buffer_size). In Angie all of these features are in the open-source version; in Nginx the rate limit is only available in the commercial one.
Next come the more capable video solutions, starting with the RTMP module.
The RTMP module
The third-party RTMP module probably has the widest feature set of them all. A look at its directive reference is enough to confirm that. It can serve video in RTMP, HLS and DASH formats, run live broadcasts, and record the stream.
The module installs from the Angie repository:
apt install angie-module-rtmp
As usual, the module load directive goes in the main context:
load_module modules/ngx_rtmp_module.so;
The simplest configuration is a live stream with no recording. First we create a configuration in Angie (the RTMP module has its own rtmp context):
rtmp {
server {
listen 1935;
application live {
live on;
}
}
}
Here we created a server for the live stream, set the socket (TCP 1935) and the application name (live). To test this config you need a video file and the ffmpeg tool.
Feed a looped file to the stream as input with ffmpeg:
ffmpeg -re -i "/video/mi2.mp4" -c:v copy -loop 1 -c:a aac -b:a 160k -ar 44100 -strict -2 -f flv rtmp://localhost/live/bbb
The command takes the input file and sends it without transcoding, wrapped in an flv container, to our RTMP server (rtmp://localhost/live/). To pull the stream from the server, use a player with RTMP support, such as mplayer:
mplayer rtmp://192.168.0.1/live/bbb
From here on the server address is 192.168.0.1. The output is a broadcast of the looped file that ffmpeg feeds to the server. Pure RTMP, though, has limited use on the web, so we extend the configuration with HLS:
rtmp {
server {
listen 1935;
application live {
live on;
hls on;
hls_path /var/www/html/stream/hls;
hls_fragment 3;
hls_playlist_length 60;
}
}
}
Here we enabled HLS for the stream fragments and the playlist that points at them. The configuration is not finished yet: we still need a regular server in the http context to serve the fragments and playlists.
server {
listen 8088;
location / {
add_header Access-Control-Allow-Origin *;
root /var/www/html/stream;
}
}
The server is up (remember to create the /var/www/html/stream directory beforehand as well). Now we can point at the broadcast playlist and open it in a compatible player (VLC, for example). The playlist URL is:
http://192.168.0.1:8088/hls/bbb.m3u8
Adding DASH support is just as easy. The full configuration now looks like this:
rtmp {
server {
listen 1935;
application live {
live on;
hls on;
hls_path /var/www/html/stream/hls;
hls_fragment 3;
hls_playlist_length 60;
dash on;
dash_path /var/www/html/stream/dash;
}
}
}
The DASH playlist URL is:
http://192.168.0.1:8088/dash/bbb.mpd
For the playlist to work, register its MIME type (usually in /etc/angie/mime.types):
application/dash+xml mpd;
We now have a working broadcast server. Time to turn on recording the stream to disk. A few more directives do that:
rtmp {
server {
listen 1935;
application live {
live on;
...
record all;
record_path /tmp/rec;
record_suffix _recorded.flv;
record_unique on;
}
}
}
For recording to work, create the directory in advance and give write permission to the user Angie runs as (let that be www-data):
mkdir /tmp/rec
chown -R www-data:www-data /tmp/rec
The broadcast is now saved to disk as flv. Keep in mind that these files pile up: you will need to delete or move them as the disk fills.
The RTMP module is a do-it-all tool for video work. For comparison, here is a quick look at the third-party VOD module, which overlaps with it in functionality.
The VOD module
The third-party VOD module (Video On Demand) serves video from files. It supports RTMP, HLS and DASH, adaptive video bitrate, and generating thumbnails from video.
The module has three operating modes:
- local: serving files from disk;
- remote: serving files available over HTTP;
- mapped: serving according to a JSON file.
Start by installing the module from the Angie repository:
apt install angie-module-vod
Load the module in the main context.
load_module modules/ngx_http_vod_module.so;
Here is an example server configuration with the VOD module:
http {
vod_mode local;
vod_metadata_cache metadata_cache 16m;
vod_response_cache response_cache 512m;
vod_last_modified_types *;
vod_segment_duration 9000;
vod_align_segments_to_key_frames on;
vod_dash_fragment_file_name_prefix "segment";
vod_hls_segment_file_name_prefix "segment";
vod_manifest_segment_durations_mode accurate;
server {
listen 8090;
server_name localhost;
root /var/www/html/vod;
add_header Access-Control-Allow-Headers '*';
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
location /hls/ {
vod hls;
alias /var/www/html/vod/;
}
location /thumb/ {
vod thumb;
alias /var/www/html/vod/;
}
location /dash/ {
vod dash;
alias /var/www/html/vod/;
}
}
}
In this example we serve local files over HLS and DASH, and also create a location for generating video thumbnails (/thumb/).
In the shared part of the configuration (http context) we set the local operating mode, cache sizes, and the settings for segmenting video files.
This module does not support live broadcasts; for those the authors recommend the Kaltura Media Framework product.
Summary
Angie covers the basics of video handling through its built-in modules. Connecting a third-party module (RTMP, for example) opens up the option of building a full video service on Angie and open-source software (ffmpeg, open video encoding libraries, etc.). Even when a full-scale video hosting platform is not the goal, video handling comes in handy for local corporate tasks.