If you are looking for a tutorial that guides you to build a VoD Server using Nginx with the Adaptive Bitrate feature, you come to the right place. In this tutorial, we will build Nginx from source and then put in the Kaltura Nginx VoD module to enable the HLS protocol that supports Adaptive Bitrate Capability.
Check Prerequisite
You need an Ubuntu Server. I tried to build this VoD server in Ubuntu 20.04, but I believe that you can also build this in Ubuntu 18.04 with no problem.
Get Sudo Privileges
Before starting, make sure that we have no permission issue on the installation & configuration.
sudo su
Install Nginx Dependencies
To build Nginx and Kaltura VoD module, we need some dependencies to install. Run this command to install them
apt update && apt install build-essential git libpcre3-dev libssl-dev zlib1g-dev ffmpeg libxml2-dev
Download Nginx Source Code
Before you download the Nginx source code, you can visit http://nginx.org/en/download.html to see the Nginx version available now. After that you can download them by running this command:
wget http://nginx.org/download/nginx-<version>.tar.gz
Now, the latest stable version is 1.20.2
, so for me, I will download the nginx-1.20.2
version
wget http://nginx.org/download/nginx-1.20.2.tar.gz
Extract the downloaded file
tar -zxvf nginx-1.20.2.tar.gz
You will get a folder named nginx-1.20.2
Download Kaltura Module
We need an Nginx vod module to build this VoD server, you can visit the Github here: https://github.com/kaltura/nginx-vod-module. Now, the latest version is 1.29
, run this command to download the latest version of the module.
wget https://github.com/kaltura/nginx-vod-module/archive/refs/tags/1.29.tar.gz
Extract the downloaded file
tar -zxvf 1.29.tar.gz
You will get a folder named nginx-vod-module-1.29
. Make sure this folder is at the same location as the nginx-1.20.2
folder.
Build & Install Nginx
Go to the nginx-1.20.2
folder
cd nginx-1.20.2
After that, we configure the nginx and put in the nginx-vod-module
and --with-cc-opt="-O3 -mpopcnt"
to nginx config options. According to Nginx VoD Module Documentation, it is said that adding --with-cc-opt="-O3 -mpopcnt"
will have 8% reduction in the mp4 parse time and frame processing time.
./configure \ --prefix=/etc/nginx \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --pid-path=/run/nginx.pid \ --sbin-path=/usr/sbin/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_stub_status_module \ --with-http_realip_module \ --with-file-aio \ --with-threads \ --with-stream \ --with-cc-opt="-O3 -mpopcnt" \ --add-module=../nginx-vod-module-1.29
After that, run this command to build & install the Nginx
make && make install
To verify the installation, you can check the Nginx version
nginx -V
Make sure there is --add-module=../nginx-vod-module-1.29
on the output
VoD Server Configuration
First, move our work directory to the Nginx configuration folder
cd /etc/nginx
Backup the default Nginx configuration file
mv nginx.conf nginx.conf.old
Create a new configuration file
nano nginx.conf
Add this configuration to the config file
user www-data;
worker_processes auto;
worker_rlimit_nofile 8192;
pid /run/nginx.pid;
events {
worker_connections 4096;
}
http {
server {
listen 80;
# vod mode
vod_mode mapped;
# vod caches
vod_metadata_cache metadata_cache 512m;
vod_response_cache response_cache 128m;
vod_mapping_cache mapping_cache 5m;
# gzip manifests
gzip on;
gzip_types application/vnd.apple.mpegurl;
# file handle caching
open_file_cache max=1000 inactive=5m;
open_file_cache_valid 2m;
open_file_cache_min_uses 1;
open_file_cache_errors on;
location ^~ /video/ {
alias /etc/nginx/json/;
vod hls;
add_header Access-Control-Allow-Headers '*';
add_header Access-Control-Expose-Headers 'Server,range,Content-Length,Content-Range';
add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
add_header Access-Control-Allow-Origin '*';
expires 100d;
}
}
}
With this configuration, we can make a request like this:
http://<server-ip-address>/video/<video-configuration-file>/master.m3u8
This request will be handled by location ^~ /video/
block. Inside this location block there is vod hls
directive, this directive make the Nginx do a sub-request to /json/video/<json-file>
to read the video-configuration-file
. The sub-request will be handled by location ^~ /json/video/
block. This is where the nginx will read the video-configuration-file
on the /etc/nginx/json
folder.
After that, we must put the video-configuration-file
to the /etc/nginx/json
folder. In this tutorial, I will use transformers video to demonstrate this video server.
First, create the folder
mkdir /etc/nginx/json
Create video-configuration-file
with transformers.json
name inside the folder
nano /etc/nginx/json/transformers.json
Add this json code to the file
{
"sequences": [
{
"clips": [
{
"type": "source",
"path": "/etc/nginx/vod/transformers_720p.mp4"
}
]
},
{
"clips": [
{
"type": "source",
"path": "/etc/nginx/vod/transformers_360p.mp4"
}
]
}
]
}
In this video configuration, we tell the Nginx that this transformers video will have 2 stream. One is 720p
video and one is 360p
video. Each of them is located in /etc/nginx/vod
folder. Note that these are 2 identical videos with different resolutions.
With these 2 stream, the vod module will automatically generate a master playlist that will adapt to the user bandwidth when the video is requested. If the bandwidth is good, it will serve the 720p
version, and if the bandwidth is bad, it will serve the 360p
version.
If you want to add more streams, feel free to add a new object under "sequences"
array.
After that, don’t forget to create /etc/nginx/vod
folder
mkdir /etc/nginx/vod
And then put the video inside it with the name described on the transformers.json file. In my case, the video is transformers_720p.mp4
and transformers_360p.mp4
.
root@facsiaginsa:/etc/nginx# ll /etc/nginx/vod/
total 154624
drwxr-xr-x 2 root root 4096 Mar 8 14:00 ./
drwxr-xr-x 5 root root 4096 Mar 8 13:59 ../
-rw-r--r-- 1 root root 29849139 Mar 8 14:00 transformers_360p.mp4
-rw-r--r-- 1 root root 128472680 Mar 8 14:00 transformers_720p.mp4
After the configuration is done, make sure that there is no error in the configuration by running this command
nginx -t
To summarize, this is the structure of our configuration file so far
/etc/nginx/
|- nginx.conf
|- json/
| |- transformers.json
|- vod/
|- transformers_720p.mp4
|- transformers_360p.mp4
Create Systemd File
To make Nginx easier to manage, we can build a systemd file. First, create a new file in the systemd folder:
nano /lib/systemd/system/nginx.service
And then copy & paste this config to the file
[Unit]
Description=Nginx VoD Server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Reload the systemd
systemctl daemon-reload
Enable Nginx service so it will auto start when the server boot
systemctl enable Nginx
Now you can control Nginx service using systemd, just like this:
service nginx start
service nginx reload
service nginx stop
service nginx restart
Start your Nginx
service nginx start
If it is failed, please make sure that no other process is running on port 80
.
Create Logrotate File
Logrotate is useful for rotating the Nginx log so it will not write on a single file continuously. First, create a new file on the logrotate folder
nano /etc/logrotate.d/nginx
Copy & Paste this code
/var/log/nginx/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 0640 root root
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
Test the Vod Server
You can test the VoD server using VLC on your laptop by pointing the network URL to http://<your-server-ip>/video/<video-configuration-file>/master.m3u8
just like image below.
Congratulation! Now you can build a VoD server using Nginx with Adaptive Bitrate feature.
Lastly, if you want to know how to make you VoD Server stateless by adding Minio integration, I advice you to check my other tutorial: Nginx VoD Server Configuration: Minio Integration.