The CentOS build environment is setup as follows:


yum groupinstall "Development Tools"

yum install \
  zlib-devel.x86_64 \
  glib2-devel.x86_64 \

Next to the build environment, the headers for libfmp4 need to be installed, set THEVERSION to the US version you want to install (e.g. 1.9.6):



yum install mp4split-devel-$usp_version-1.x86_64.rpm

Then download the Nginx webserver module and unpack the tarball:



cd ~
curl$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=nginx-NGINX_VERSION line to the Nginx version you downloaded. You may also remove the 'debug' settings. Then use make to build and install:



cd ~/nginx_mod_smooth_streaming-$usp_version
sudo make install


The Ubuntu build environment is setup as follows:


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

The Nginx weberver is built as on CentOS, 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 CentOS section outlines.


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/";

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?/.*$ {

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;

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

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


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

location ~ \.(mp4)$ {

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.


Please install your License Key Information now, otherwise streaming will not work!

After restarting your web server, you can continue with Verify Your Setup.


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).
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 HTTP Proxy

Options releated 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/ {

Status code mapping can be done with Lua in Nginx:

header_filter_by_lua "
  if ngx.status == FMP4_FRAGMENT_MISSING then
    ngx.status = 204

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.


The 'usp_dynamic_time_shift_buffer_depth' option is deprecated.



For Nginx the directive looks like the following:

location ^~ /example/ {
  root /var/www/usp_test;

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/;


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;

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 !~ "^(|$") {
    return 403;