Nginx

Note

Our software requires a license key. How to specify your license key for Nginx is explained on this page. For more info, see License Key.

Compilation

Rocky

The Rocky Linux build environment is setup as follows:

#!/bin/bash

yum groupinstall "Development Tools"

yum install \
  zlib-devel \
  glib2-devel \
  bzip2-devel

Next to the build environment, libfmp4 and the headers for libfmp4 need to be installed as well (for how to use the package manager to install a certain version, please see the generic installation documentation, How to Install):

#!/bin/bash

yum install mp4split
yum install mp4split-devel

Then download Nginx and the Nginx webserver module and unpack the module tarball:

#!/bin/bash

nginx_version=THEVERSION
usp_version=THEVERSION

cd ~
curl https://nginx.org/download/nginx-$nginx_version.tar.gz -O
curl https://stable.yum.unified-streaming.com/rocky/9/x86_64/nginx_mod_smooth_streaming-$usp_version.tar.gz -O

tar -zxvf nginx_mod_smooth_streaming-$usp_version.tar.gz

Edit the Makefile in the Nginx webserver module directory and set the NGINX_VERSION line to the Nginx version you downloaded (you can also pass this on the command line to as, e.g. make NGINX_VERSION=THEVERSION).

Then use make to build and install:

#!/bin/bash

usp_version=THEVERSION

cd ~/nginx_mod_smooth_streaming-$usp_version
make
sudo make install

Ubuntu

The Ubuntu build environment is setup as follows:

#!/bin/bash

sudo apt-get install build-essential \
  g++ \
  make \
  autoconf \
  automake \
  libtool

The Nginx webserver is built as on Rocky Linux, with the difference that the 'devel' package does not need to be installed: on Debian/Ubuntu headers are installed by default.

Unpack the tarball and run make/make install as the Rocky Linux section outlines.

Configuration

As we are using the dynamic module we need to tell Nginx to load it before it can be used. Add the following to the nginx configuration file /usr/local/nginx/conf/nginx.conf in the 'main' context:

load_module "modules/ngx_http_smooth_streaming_module.so";

The next step is to have file requests ending in '.ism' (VOD) handled by the usp_handle_ism command. Add the following lines in your server { ... } section:

location ~ \.[is]sm?/.*$ {
  usp_handle_ism;
}

The above location will match on any directory including a .ism file. It is also possible to map ingest to only a certain location on the filesystem:

server {
  listen 80;
  server_name vod.example.com;

  location ~ /channels/.*\.[is]sm?/.*$ {
    root /var/www;
    usp_handle_ism;
  }
}

The filesystem layout is the following (so '/var/www' is the root of the server):

/var
  /www
    /channels

If you also want to make progressive downloads available then you have to serve files ending in '.mp4' with the webserver module:

location ~ \.(mp4)$ {
  usp_handle_ism;
}

Nginx License Key

For Nginx, the usp_license_key server directive must be used which is placed in the http section of nginx.conf (before any server block):

http {
  usp_license_key /path/to/usp-license.key;

  # rest of config

}

Prevent the download of media files

In order to prevent the download of (source) mediafiles, add the following to your webserver config:

location ~ \.(ismv|isma|ismt)$ {
  deny all;
}

When the source content is MP4 then the rule can be adapted to mp4 as well. The same applies to CMAF as source (cmfv, cmfa and cmft).

Prevent the download of server manifests

In order to protect your server manifests (VOD and Live) you have to disable access to ism and isml files. This can be done with the so-called LocationMatch directive similar to preventing access to media:

# never serve files with the extension .ism or .isml (case insensitive)
location ~ \.isml?/?$ {
  deny all;
}

Options

The options apply to the Server Block directive.

Options related to content generation:

Option

Description

usp_license_key

Context: http.

usp_handle_ism

Context: Location (see above).

usp_iss_pass_through

Context: location. Pass through MP4 fragments directly to Smooth Streaming (see IIS passthrough).

usp_prefer_static

Context: location. Pass through MP4 fragments directly to Smooth Streaming (see IIS passthrough).

usp_skip_rewrite

Context: location. Skip the internal rewrite rules (see below).

usp_handle_f4f

Add to enable mod_f4fhttp functionality (See Ingest F4M (deprecated)).

usp_disable_mmap

Add to disable use of memory mapped I/O.

usp_dynamic_time_shift_buffer_depth

Set to 'on' to update the @timeShiftBufferDepth attribute dynamically (see below).

Option related to content location:

Option

Description

ism_proxy_pass

Context: location. Pass .ism to proxy (a virtual path and URL), see Dynamic Manifests

Options related to secure AWS S3 access:

Option

Description

s3_secret_key

The AWS secret key, see Using Webserver Directives for S3 authentication.

s3_access_key

The AWS access key, see Using Webserver Directives for S3 authentication.

s3_region

The AWS region of the bucket, see Using Webserver Directives for S3 authentication.

The directive 'usp_skip_rewrite controls whether the internal rewrite rules are skipped. By default this is off. This is an advanced setting and generally not recommended to turn on.

location ^~ /example/ {
  usp_skip_rewrite;
}

Status code mapping can be done with Lua in Nginx:

header_filter_by_lua "
  FMP4_FRAGMENT_MISSING = 404
  if ngx.status == FMP4_FRAGMENT_MISSING then
    ngx.status = 204
  end
";

The usp_dynamic_time_shift_buffer_depth option changes how the @timeShiftBufferDepth attribute is set in the MPEG-DASH manifest: the @timeShiftBufferDepth attribute is updated dynamically according to the available time window and capped at the dvr_window_length.

Warning

The 'usp_dynamic_time_shift_buffer_depth' option is deprecated.

Features

iis_pass_through

For Nginx the directive looks like the following:

location ^~ /example/ {
  root /var/www/usp_test;
  usp_iss_pass_through;
  usp_prefer_static;
  usp_handle_ism;
}

Both usp_iss_pass_through and usp_prefer_static are used in the location context. Multiple locations can be used a single virtual host, so this option can be -used on a per location basis.

Dynamic manifests

For Nginx the ism_proxy_pass configuration key is specified in a location:

location ^~ /video/proxy/ {
  ism_proxy_pass http://other-server/;
  usp_handle_ism;
}

Warning

Please note that when using Nginx, the 'other-server' may not be Nginx as well: Nginx will 'hang' waiting for the request to itself to finish - which never will happen. See What is the preferred webserver for media delivery? for further background.

Live API

Configuration when using Nginx:

location ~ \.isml {
  root /path/to/www/live;
  usp_handle_api;
}

By adding or usp_handle_api you can toggle the API on or off.

Live State and Statistics

API configuration for Nginx:

location ~ \.isml?\/(state|statistics|archive) {
  if ($remote_addr !~ "^(127.0.0.1|8.8.8.8)$") {
    return 403;
  }
  usp_handle_ism;
}

AWS S3 Access

Content in S3 cn be accessed securely by signing the request as outlined in Using S3 with Authentication. For Nginx this looks like the following:

location ^~ /your-location-name/ {
  s3_secret_key YOUR_SECRET_KEY;
  s3_access_key YOUR_ACCESS_KEY;
  s3_region your-region;
  ism_proxy_pass http://your-bucket.your-region.amazonaws.com/;
  usp_handle_ism;
}

Alternatively, signing S3 requests can be separated from the origin by using a separate Nginx instance as a proxy which in turn sign downstream requests to S3 using nginx-aws-auth.