Open-source project
kaltura/nginx-vod-module avatar
kaltura/nginx-vod-module

nginx-vod-module: on-the-fly MP4 repackaging to DASH, HLS, HDS and MSS in nginx

NGINX-based MP4 Repackager

2,121 stars476 forksCAGPL-3.0

At a glance

What is it?
nginx-vod-module is a Kaltura-built nginx module that repackages MP4 files into DASH, HLS, HDS and MSS on request, with 3 working modes, DRM support and optional ffmpeg integration for thumbnails and playback rate change. It requires compiling against an nginx source tree and is tested on Linux only.
Who is it for?
nginx-vod-module fits operators who already have MP4 archives and want to serve DASH, HLS, HDS or MSS without a separate transcoding pipeline. Before compiling, check whether playback rate change is needed: it requires libfdk_aac, which the Kaltura pre-built packages exclude for licensing reasons, so it calls for a custom ffmpeg build.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 110 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 6, 2026, and from our analysis. They are not legal advice.

Editorial analysis

On-the-fly repackaging of MP4 files into 4 streaming formats without pre-processing

Operators who have an MP4 video archive but need to serve DASH, HLS, HDS or MSS to players face a choice: pre-package every file into every format at ingest time, or repackage on demand at serve time. nginx-vod-module takes the second path. It runs inside nginx and generates the target format segment by segment as each request arrives, leaving the source MP4 on disk untouched.

The 4 output formats cover most player environments in practice. DASH and HLS are the two standards with broad current support. HDS (HTTP Dynamic Streaming) is Adobe's format, now largely legacy. MSS (Microsoft Smooth Streaming) still appears in Azure Media Services and older Microsoft player implementations. Having all 4 available from one source file avoids maintaining separate transcoded copies per format.

The module does not transcode, upload or encode anything. Input must already be in MP4 format, and the module's job begins at the point where a player requests a specific segment or manifest.

Three working modes: which one to choose depends on where the MP4 files live

The mode to choose depends on where the MP4 files live and how complex the serving requirements are. For files on local storage or NFS, local mode handles path resolution directly without any network round-trip to fetch the source. When the MP4 files are on a remote server, remote mode fetches each segment's data via HTTP range requests, adding network latency in exchange for removing the requirement for shared storage on the nginx host.

Mapped mode is the option for everything else: nginx retrieves a JSON specification that describes what to serve, either by pulling it from a remote server or reading a local file, and that spec drives the response. Only mapped mode supports playlists (playing multiple MP4 files in sequence) and simulated live (presenting VOD content as a live stream to the player). Both features require the JSON spec to describe the file list and timing.

Fallback support for file-not-found responses is available in local and mapped modes but not in remote mode. That gap matters in multi-datacenter setups: an operator who wants nginx to try a secondary origin when the primary file is absent needs to use one of the two modes that support fallback.

Building the module: static link or dynamic load, with optional compiler optimizations

To compile nginx-vod-module as a static module, cd into the nginx source directory and run:

bash
./configure --add-module=/path/to/nginx-vod-module
make
make install

For a dynamic module on nginx 1.9.11 or newer, substitute --add-dynamic-module:

bash
./configure --add-dynamic-module=/path/to/nginx-vod-module

With a dynamic build, the load_module directive in nginx.conf is required to activate it.

Three optional configure flags improve specific use cases. Passing --with-file-aio enables asynchronous I/O, which the README describes as highly recommended for local and mapped modes. Passing --with-threads (nginx 1.7.11 or newer) enables asynchronous file open through a thread pool, also relevant only to local and mapped modes. A third option, --with-cc-opt="-O3 -mpopcnt", activates additional compiler optimizations; the README notes about an 8% reduction in MP4 parse time and frame processing time compared to nginx's default -O optimization level.

Alternatively, pre-built packages are available. For RHEL/CentOS:

sh
rpm -ihv http://installrepo.kaltura.org/releases/kaltura-release.noarch.rpm
yum install kaltura-nginx

For thumbnail capture and playback rate change features, the kaltura-ffmpeg package at version 3.1 or newer must also be installed.

libfdk_aac is required for playback rate change but excluded from Kaltura's pre-built ffmpeg packages

The feature list says playback rate change (0.5x to 2x) requires libavcodec and libavfilter. The compilation dependencies section in the same README goes further: audio filtering, which covers playback rate change, also depends on libfdk_aac. Then comes a clarification that, due to licensing issues, libfdk_aac is not built into the Kaltura ffmpeg packages.

The implication is that installing kaltura-nginx and kaltura-ffmpeg from the Kaltura repositories gives you an ffmpeg without libfdk_aac, which means playback rate change will not work despite the installed kaltura-ffmpeg satisfying the stated >= 3.1 requirement. Enabling this feature requires building ffmpeg manually with libfdk_aac included.

This inconsistency appears between two sections of the same documentation. An operator relying on the pre-built package path should treat playback rate change as unavailable unless they verify the libfdk_aac situation in their specific build.

DRM paths differ by format: CENC for DASH, PlayReady for MSS, two HLS options and a trick-play constraint

DRM coverage is not uniform across the 4 output formats, and the available encryption scheme depends on which format you are serving. DASH uses CENC (Common Encryption), the industry standard for interoperability with multiple DRM systems. MSS uses PlayReady specifically, which is Microsoft's proprietary DRM scheme. HLS offers 2 options: AES-128, which encrypts entire segments, and SAMPLE-AES, which encrypts individual samples. HDS has no encryption support in the feature list.

On the input side, the module can decrypt CENC-encrypted MP4 source files, which the README mentions alongside a note that MP4Box is one tool for creating such files. This allows a workflow where encrypted source files are stored and decrypted at serve time.

One constraint cuts across the HLS encryption path: I-frames playlist generation (EXT-X-I-FRAMES-ONLY) is disabled when encryption is active. That playlist type is used for fast-forward and rewind trick play in HLS. An operator who needs both HLS encryption and trick play support will find the two features mutually exclusive in this module.

Three compile-time dependencies enable the optional features. openssl is required for all encryption and decryption. libxml2 is needed for DFXP caption input. iconv is needed for UTF-16 encoded SRT files. The configure step detects each dependency and silently disables the corresponding feature if it is absent.

Codec coverage: H264 reaches all formats while newer video codecs narrow to DASH and HLS

Codec support follows a clear pattern across video and audio: widely supported codecs reach all 4 output formats, while newer ones narrow down to DASH and HLS where those codecs have standardized container definitions. H264 is the exception that covers every format. H265 and AV1 are limited to DASH and HLS, reflecting where those codecs have packaging standards. VP8 and VP9 are confined to DASH only, with no HLS, HDS or MSS packaging available.

Audio coverage spreads differently. AAC is the broadest, covering all 4 formats. MP3 reaches HLS, HDS and MSS but is absent from DASH. AC-3 and E-AC-3 work with DASH and HLS. VORBIS and OPUS are DASH-only. FLAC and DTS work with HLS only, a pair worth noting for operators targeting HLS deployments with lossless or theatrical audio tracks.

Caption input comes from 4 formats: WebVTT, SRT, DFXP/TTML and CAP (Cheetah). Each output format delivers captions differently. DASH accepts either a single WebVTT file or SMPTE-TT segments, and the operator configures which form to use. HLS produces segmented WebVTT in an m3u8 manifest. MSS converts captions to TTML and wraps them in fragmented MP4, but caption styling is not preserved in that conversion.

Progressive download loses track selection and rate change; real-time live is out of scope

Progressive download is a delivery path where a video file is served as a single HTTP download rather than as adaptive streaming segments. Two features available in the adaptive formats are disabled for progressive download: track selection and playback rate change. An operator offering progressive download alongside HLS or DASH cannot assume all features will work in both paths.

Simulated live is different from real live. nginx-vod-module can present a sequence of VOD MP4 files as a continuous live stream to the player, generating segments from the files as if they were incoming live content. That feature belongs to mapped mode. Actual real-time live, where a camera or encoder sends a live signal that the server ingests and distributes, is outside what this module handles. The README points explicitly to Media-Framework, a separate Kaltura project, for live use cases.

The module is tested on Linux only, a boundary stated in the limitations section. AGPL-3.0 governs the code, meaning deployments that modify the module and run it as a network service must release those modifications.

Editorial conclusion

nginx-vod-module fits operators who already have MP4 archives and want to serve DASH, HLS, HDS or MSS without a separate transcoding pipeline. Before compiling, check whether playback rate change is needed: it requires libfdk_aac, which the Kaltura pre-built packages exclude for licensing reasons, so it calls for a custom ffmpeg build. Dynamic module loading requires nginx 1.9.11 or newer. Deployments that modify the module and serve it over a network fall under AGPL-3.0, which requires releasing those modifications. Real-time live streaming is not in scope here; the project documentation points to Media-Framework for that instead.

Frequently asked questions

What is nginx-vod-module?

nginx-vod-module is an nginx module from Kaltura that repackages MP4 files on the fly to DASH, HLS, HDS and MSS. It runs inside nginx and supports 3 working modes: local file access, HTTP range requests and JSON-mapped specifications.

How do I install nginx-vod-module?

On RHEL/CentOS, install the kaltura-release RPM and then run yum install kaltura-nginx. On Debian/Ubuntu, add the appropriate Kaltura apt repository for your version and run apt-get install kaltura-nginx. Building from source requires compiling against nginx source with --add-module or --add-dynamic-module.

Does nginx-vod-module support DRM?

Yes. DASH supports CENC encryption, MSS supports PlayReady, and HLS supports AES-128 and SAMPLE-AES encryption. The module can also decrypt CENC-encrypted MP4 files as input. I-frames playlist generation is not supported when HLS encryption is enabled.

Can nginx-vod-module handle live streaming?

nginx-vod-module includes simulated live support, which plays MP4 files as a live stream, available only in mapped mode. For real-time live ingest and streaming, the README points to a separate Kaltura project called Media-Framework.

What are the 3 working modes of nginx-vod-module?

Local mode serves files from locally accessible paths including NFS mounts. Remote mode fetches MP4 files via HTTP range requests. Mapped mode uses a JSON specification (from a remote server or local file) to describe which files to serve, and it is the only mode that supports playlists and simulated live.

Official sources

  1. Issues
  2. kaltura/nginx-vod-module on GitHub
  3. License: AGPL-3.0
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kaltura-nginx-vod-module.svg)](https://hysenlabs.com/projects/kaltura-nginx-vod-module)

Was this useful?