Table of Contents

The Nginx module is built from source, the following sections outline how to setup dependencies, build the module and configure it.



See OS Specific Installation for how to install libfmp4 and it’s dependencies.

Download Nginx (replace the ‘x’ with the correct version):


cd ~


Download the Nginx webserver module and unpack the tarball:


cd ~
tar -zxvf nginx_mod_smooth_streaming-1.x.y.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-1.x.y
sudo make install

Prior to calling make you should setup the development environment for your distribution:


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. These can be found in the so-called ‘devel’ package from the download page:


rpm -i mp4split-devel-x.y.z-1.x86_64.rpm


The Ubuntu build environment is setup as follows:


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


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)$ {

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 now, otherwise streaming will not work!

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


The options apply to the Server Block directive.

Options related to content generation:

Option Description
usp_license_key Context: http. See Nginx License Key.
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.