ngx_http_mp4_module

Pseudo-streaming and seeking for MP4, M4V and M4A files

compiled inBSD-2-Clausesource docs

Overview

ngx_http_mp4_module provides server-side pseudo-streaming for MP4 files, typically with the .mp4, .m4v or .m4a extension. A compatible player sends the desired start time in seconds as the start query argument, and nginx answers with a stream whose beginning matches that time, so playback can start or seek anywhere in the timeline.

The end argument (1.5.13) sets the end of playback and can be combined with start. For a request with a non-zero start or end, nginx reads the moov atom metadata, builds a new stream for the requested range and sends it, which costs CPU, memory and disk I/O, especially when the metadata sits at the end of the file. Without start and end the file is sent as a plain static resource with no overhead. If start lands on a non-key frame, mp4_start_key_frame (1.21.4) hides the leading frames with an edit list.

It is an official nginx module that upstream does not build by default; it needs the --with-http_mp4_module configure parameter. A typical use is serving video files to HTML5 or Flash players that seek by time rather than by byte range.

Key directives

mp4Turns on module processing in the surrounding location; location context only.
mp4_buffer_sizeSets the initial size of the buffer used for processing MP4 files, default 512K.
mp4_max_buffer_sizeUpper limit for the metadata buffer, default 10M; a larger moov atom yields a 500 error and a log message.
mp4_start_key_frameForces output to start with a key frame, hiding earlier frames via an edit list (1.21.4), default off.
start and end argumentsQuery arguments in seconds that select the playback range; end appeared in 1.5.13.

Example

nginx.conf
location /video/ { root /srv/media; # enable time-based seeking via ?start= and ?end= mp4; mp4_buffer_size 1m; mp4_max_buffer_size 5m; # hide frames before the nearest key frame (1.21.4) mp4_start_key_frame on; }

Availability

Compiled into every n.wtf nginx binary. Install nginx-extras and the directives above work out of the box, no load_module line needed.