Join the list of organizations using this video packager project.
On-the-fly repackaging of MP4 files to DASH, HDS, HLS, MSS
Working modes:
Adaptive bitrate support
Playlist support (playing several different media files one after the other) - mapped mode only
Simulated live support (generating a live stream from MP4 files) - mapped mode only
Fallback support for file not found in local/mapped modes (useful in multi-datacenter environments)
Video codecs: H264, H265 (DASH/HLS), VP9 (DASH)
Audio codecs: AAC, MP3 (HLS/HDS/MSS), AC-3 (DASH/HLS), E-AC-3 (DASH/HLS), OPUS (DASH)
Captions support -
Input:
Output:
Audio only/video only files
Alternative audio renditions - supporting both:
Track selection for multi audio/video MP4 files
Playback rate change - 0.5x up to 2x (requires libavcodec and libavfilter)
Source file clipping (only from I-Frame to P-frame)
Support for variable segment lengths - enabling the player to select the optimal bitrate fast, without the overhead of short segments for the whole duration of the video
Clipping of MP4 files for progressive download playback
Thumbnail capture (requires libavcodec) and resize (requires libswscale)
Volume map (requires libavcodec) - returns a CSV containing the volume level in each interval
Decryption of CENC-encrypted MP4 files (it is possible to create such files with MP4Box)
DASH: common encryption (CENC) support
MSS: PlayReady encryption support
HLS: Generation of I-frames playlist (EXT-X-I-FRAMES-ONLY)
HLS: support for AES-128 / SAMPLE-AES encryption
Track selection and playback rate change are not supported in progressive download
I-frames playlist generation is not supported when encryption is enabled
Tested on Linux only
In general, if you have the dependencies that are required to build nginx, you should be able to build nginx-vod-module.
However, some optional features of this module depend on additional packages. The module detects these packages
during configure - if a package is missing, the respective feature will be disabled.
The optional features are:
To link statically against nginx, cd to nginx source directory and execute:
./configure --add-module=/path/to/nginx-vod-module
make
make install
To compile as a dynamic module (nginx 1.9.11+), use:
./configure --add-dynamic-module=/path/to/nginx-vod-module
In this case, the load_module directive should be used in nginx.conf in order to load the module.
Optional recommended settings:
--with-file-aio - enable asynchronous I/O support, highly recommended, relevant only to local and mapped modes--with-threads (nginx 1.7.11+) - enable asynchronous file open using thread pool (also requires vod_open_file_thread_pool in nginx.conf), relevant only to local and mapped modes--with-cc-opt="-O3" - enable additional compiler optimizations (we saw about 8% reduction in the mp4 parse time
and frame processing time compared to the nginx default -O)Debug settings:
--with-debug - enable debug messages (also requires passing debug in the error_log directive in nginx.conf).--with-cc-opt="-O0" - disable compiler optimizations (for debugging with gdb)# rpm -ihv http://installrepo.kaltura.org/releases/kaltura-release.noarch.rpm
# yum install kaltura-nginx
Ubuntu NOTE: before trying to install kaltura-nginx, you must also make sure the multiverse repo is enabled
For Debian Wheezy [7], Debian Jessie [8], Ubuntu 14.04 and 14.10, add this repo:
# wget -O - http://installrepo.kaltura.org/repo/apt/debian/kaltura-deb.gpg.key|apt-key add -
# echo "deb [arch=amd64] http://installrepo.kaltura.org/repo/apt/debian orion main" > /etc/apt/sources.list.d/kaltura.list
For Ubuntu 16.04, 16.10 add this repo:
# wget -O - http://installrepo.kaltura.org/repo/apt/xenial/kaltura-deb-256.gpg.key|apt-key add -
# echo "deb [arch=amd64] http://installrepo.kaltura.org/repo/apt/xenial orion main" > /etc/apt/sources.list.d/kaltura.list
Then install the kaltura-nginx package:
# apt-get update
# apt-get install kaltura-nginx
If you wish to make use of the following features:
You will also need to install the kaltura-ffmpeg (>= 3.1) package.
The basic structure of an nginx-vod-module URL is:
http://<domain>/<location>/<fileuri>/<filename>
Where:
http://<upstream>/<location>/<fileuri>?<extraargs>
(extraargs is determined by the vod_upstream_extra_args parameter)Multi URLs are used to encode several URLs on a single URL. A multi URL can be used to specify the URLs of several different MP4 files that should be included together in a DASH MPD for example.
The structure of a multi URL is:
http://<domain>/<location>/<prefix>,<middle1>,<middle2>,<middle3>,<postfix>.urlset/<filename>
The sample URL above represents 3 URLs:
http://<domain>/<location>/<prefix><middle1><postfix>/<filename>http://<domain>/<location>/<prefix><middle2><postfix>/<filename>http://<domain>/<location>/<prefix><middle3><postfix>/<filename>The suffix .urlset (can be changed using vod_multi_uri_suffix) indicates that the URL should be treated as a multi URL.
For example - the URL http://example.com/hls/videos/big_buck_bunny_,6,9,15,00k.mp4.urlset/master.m3u8 will return a manifest containing:
The following parameters are supported on the URL path:
.../clipFrom/10000/... will generate a stream that starts 10 seconds into the video..../clipTo/60000/... will generate a stream truncated to 60 seconds.v<id1>-v<id2>-a<id1>-a<id2>...
For example, .../tracks/v1-a1/... will select the first video track and first audio track.
The default is to include all tracks.v<vshift>-a<ashift>-s<sshift>
For example, .../shift/v100/... will apply a forward shift of 100ms to the video timestamps.The structure of filename is:
<basename>[<seqparams>][<fileparams>][<trackparams>][<langparams>].<extension>
Where:
thumb-<offset>[<resizeparams>].jpg (offset is the thumbnail video offset in milliseconds)volume_map.csvWhen configured to run in mapped mode, nginx-vod-module issues an HTTP request to a configured upstream server in order to receive the layout of media streams it should generate. The response has to be in JSON format.
This section contains a few simple examples followed by a reference of the supported objects and fields. But first, a couple of definitions:
Source Clip - a set of audio and/or video frames (tracks) extracted from a single media fileGenerator - a component that can generate audio/video frames. Currently, the only supported generator is the silence generator.Filter - a manipulation that can be applied on audio/video frames. The following filters are supported:Clip - the result of applying zero or more filters on a set of source clipsDynamic Clip - a clip whose contents is not known in advance, e.g. targeted ad contentSequence - a set of clips that should be played one after the other.Set - several sequences that play together as an adaptive set, each sequence must have the same number of clips.The JSON below maps the request URI to a single MP4 file:
{
"sequences": [
{
"clips": [
{
"type": "source",
"path": "/path/to/video.mp4"
}
]
}
]
}
When using multi URLs, this is the only allowed JSON pattern. In other words, it is not possible to combine more complex JSONs using multi URL.
As an alternative to using multi URL, an adaptive set can be defined via JSON:
{
"sequences": [
{
"clips": [
{
"type": "source",
"path": "/path/to/bitrate1.mp4"
}
]
},
{
"clips": [
{
"type": "source",
"path": "/path/to/bitrate2.mp4"
}
]
}
]
}
The JSON below will play 35 seconds of video1 followed by 22 seconds of video2:
{
"durations": [ 35000, 22000 ],
"sequences": [
{
"clips": [
{
"type": "source",
"path": "/path/to/video1.mp4"
},
{
"type": "source",
"path": "/path/to/video2.mp4"
}
]
}
]
}
The JSON below takes video1, plays it at x1.5 and mixes the audio of the result with the audio of video2, after reducing it to 50% volume:
{
"sequences": [
{
"clips": [
{
"type": "mixFilter",
"sources": [
{
"type": "rateFilter",
"rate": 1.5,
"source": {
"type": "source",
"path": "/path/to/video1.mp4"
}
},
{
"type": "gainFilter",
"gain": 0.5,
"source": {
"type": "source",
"path": "/path/to/video2.mp4",
"tracks": "a1"
}
}
]
}
]
}
]
}
The JSON below is a sample of a continuous live stream (=a live stream in which all videos have exactly the same encoding parameters). In practice, this JSON will have to be generated by some script, since it is time dependent. (see test/playlist.php for a sample implementation)
{
"playlistType": "live",
"discontinuity": false,
"segmentBaseTime": 1451904060000,
"firstClipTime": 1451917506000,
"durations": [83000, 83000],
"sequences": [
{
"clips": [
{
"type": "source",
"path": "/path/to/video1.mp4"
},
{
"type": "source",
"path": "/path/to/video2.mp4"
}
]
}
]
}
The JSON below is a sample of a non-continuous live stream (=a live stream in which the videos have different encoding parameters). In practice, this JSON will have to be generated by some script, since it is time dependent (see test/playlist.php for a sample implementation)
{
"playlistType": "live",
"discontinuity": true,
"initialClipIndex": 171,
"initialSegmentIndex": 153,
"firstClipTime": 1451918170000,
"durations": [83000, 83000],
"sequences": [
{
"clips": [
{
"type": "source",
"path": "/path/to/video1.mp4"
},
{
"type": "source",
"path": "/path/to/video2.mp4"
}
]
}
]
}
Mandatory fields:
sequences - array of Sequence objects.
The mapping has to contain at least one sequence and up to 32 sequences.Optional fields:
id - a string that identifies the set. The id can be retrieved by $vod_set_id.playlistType - string, can be set to live or vod, default is vod.durations - an array of integers representing clip durations in milliseconds.
This field is mandatory if the mapping contains more than a single clip per sequence.
If specified, this array must contain at least one element and up to 128 elements.discontinuity - boolean, indicates whether the different clips in each sequence have
different media parameters. This field has different manifestations according to the
delivery protocol - a value of true will generate #EXT-X-DISCONTINUITY in HLS,
and a multi period MPD in DASH. The default value is true, set to false only if the media
files were transcoded with exactly the same parameters (in AVC for example,
the clips should have exactly the same SPS/PPS).segmentDuration - integer, sets the segment duration in milliseconds. This field,
if specified, takes priority over the value set in vod_segment_duration.consistentSequenceMediaInfo - boolean, currently affects only DASH. When set to true (default)
the MPD will report the same media parameters in each period element. Setting to false
can have severe performance implications for long sequences (nginx-vod-module has
to read the media info of all clips included in the mapping in order to generate the MPD)referenceClipIndex - integer, sets the (1-based) index of the clip that should be used
to retrieve the video metadata for manifest requests (codec, width, height etc.)
If consistentSequenceMediaInfo is set to false, this parameter has no effect -
all clips are parsed. If this parameter is not specified, nginx-vod-module uses the last clip
by default.notifications - array of notification objects (see below), when a segment is requested,
all the notifications that fall between the start/end times of the segment are fired.
the notifications must be ordered in an increasing offset order.clipFrom - integer, contains a timestamp indicating where the returned stream should start.
Setting this parameter is equivalent to passing /clipFrom/ on the URL.clipTo - integer, contains a timestamp indicating where the returned stream should end.
Setting this parameter is equivalent to passing /clipTo/ on the URL.Live fields:
firstClipTime - integer, mandatory for all live playlists unless clipTimes is specified.
Contains the absolute time of the first clip in the playlist, in milliseconds since the epoch (unixtime x 1000)clipTimes - array of integers, sets the absolute time of all the clips in the playlist,
in milliseconds since the epoch (unixtime x 1000). This field can be used only when
discontinuity is set to true. The timestamps may contain gaps, but they are not allowed to overlap
(clipTimes[n + 1] >= clipTimes[n] + durations[n])segmentBaseTime - integer, mandatory for continuous live streams, contains the absolute
time of the first segment of the stream, in milliseconds since the epoch (unixtime x 1000).
This value must not change during playback.
For discontinuous live streams, this field is optional:
vod_segment_duration.firstClipStartOffset - integer, optional, measured in milliseconds. This field contains the
difference between first clip time, and the original start time of the first clip -
the time it had when it was initially added (before the live window shifted)initialClipIndex - integer, mandatory for non-continuous live streams that mix videos having
different encoding parameters (SPS/PPS), contains the index of the first clip in the playlist.
Whenever a clip is pushed out of the head of the playlist, this value must be incremented by one.initialSegmentIndex - integer, mandatory for live streams that do not set segmentBaseTime,
contains the index of the first segment in the playlist. Whenever a clip is pushed out of the head of
the playlist, this value must be incremented by the number of segments in the clip.presentationEndTime - integer, optional, measured in milliseconds since the epoch.
when supplied, the module will compare the current time to the supplied value,
and signal the end of the live presentation if presentationEndTime has passed.
In HLS, for example, this parameter controls whether an #EXT-X-ENDLIST tag should be
included in the media playlist.
When the parameter is not supplied, the module will not signal live presentation end.expirationTime - integer, optional, measured in milliseconds since the epoch.
when supplied, the module will compare the current time to the supplied value,
and if expirationTime has passed, the module will return a 404 error for manifest requests
(segment requests will continue to be served).
when both presentationEndTime and expirationTime have passed, presentationEndTime takes
priority, i.e. manifest requests will be served and signal presentation end.liveWindowDuration - integer, optional, provides a way to override vod_live_window_duration
specified in the configuration. If the value exceeds the absolute value specified in
vod_live_window_duration, it is ignored.Mandatory fields:
clips - array of Clip objects (mandatory). The number of elements must match the number
the durations array specified on the set. If the durations array is not specified,
the clips array must contain a single element.Optional fields:
id - a string that identifies the sequence. The id can be retrieved by $vod_sequence_id.language - a 3-letter (ISO-639-2) language code, this field takes priority over any language
specified on the media file (MP4 mdhd atom)label - a friendly string that identifies the sequence. If a language is specified,
a default label will be automatically derived by it - e.g. if language is ita,
by default italiano will be used as the label.bitrate - an object that can be used to set the bitrate for the different media types,
in bits per second. For example, {"v": 900000, "a": 64000}. If the bitrate is not supplied,
nginx-vod-module will estimate it based on the last clip in the sequence.Mandatory fields:
type - a string that defines the type of the clip. Allowed values are:
Optional fields:
keyFrameDurations - array of integers, containing the durations in milliseconds of the video key frames
in the clip. This property can only be supplied on the top level clips of each sequence,
supplying this property on nested clips has no effect.
Supplying the key frame durations enables the module to both:
vod_manifest_segment_durations_mode to accurate, which is not supported for multi clip
media sets (for performance reasons).firstKeyFrameOffset - integer, offset of the first video key frame in the clip,
measured in milliseconds relative to firstClipTime. Defaults to 0 if not supplied.Mandatory fields:
type - a string with the value sourcepath - a string containing the path of the MP4 file. The string "empty" can be used to represent
an empty captions file (useful in case only some videos in a playlist have captions)Optional fields:
tracks - a string that specifies the tracks that should be used, the default is "v1-a1",
which means the first video track and the first audio trackclipFrom - an integer that specifies an offset in milliseconds, from the beginning of the
media file, from which to start loading framesencryptionKey - a base64 encoded string containing the key (128 bit) that should be used
to decrypt the media file.Mandatory fields:
type - a string with the value rateFilterrate - a float that specified the acceleration factor, e.g. a value of 2 means double speed.
Allowed values are in the range 0.5 - 2 with up to two decimal pointssource - a clip object on which to perform the rate filteringMandatory fields:
type - a string with the value gainFiltergain - a float that specified the amplification factor, e.g. a value of 2 means twice as loud.
The gain must be positive with up to two decimal pointssource - a clip object on which to perform the gain filteringMandatory fields:
type - a string with the value mixFiltersources - an array of Clip objects to mix. This array must contain at least one clip and
up to 32 clips.Mandatory fields:
type - a string with the value concatdurations - an array of integers representing MP4 durations in milliseconds,
this array must match the paths array in count and order.Optional fields:
paths - an array of strings, containing the paths of the MP4 files. Either paths or clipIds must be specified.clipIds - an array of strings, containing the ids of source clips.
The ids are translated to paths by issuing a request to the uri specified in vod_source_clip_map_uri.
Either paths or clipIds must be specified.tracks - a string that specifies the tracks that should be used, the default is "v1-a1",
which means the first video track and the first audio trackoffset - an integer in milliseconds that indicates the timestamp offset oContent type
Image
Digest
Size
82.5 MB
Last updated
over 6 years ago
docker pull mediacloudai/nginx_vod_module