Thursday, July 25, 2013

MPEG DASH Adaptive Streaming

MPEG DASH Adaptive Streaming

Specifications

MPEG DASH is MPEG's standardized Adaptive Streaming over HTTP. It is specified in the following international standards:

ISO/IEC 23009-1 specifies the overall DASH architecture and the XML syntax for the MPD (Media Presentation Document)
ISO/IEC 23001-7 specifies the Common Encryption for MP4 fragments
ISO/IEC 14496-12/AMD 3 specifies the extensions to 14496-12 that are necessary to support DASH with fragmented MP4 media
Fragmenting MP4 files

To create DASH MP4 content, you need to start with fragmented MP4 files.
The command line tool mp4info can tell you if an MP4 file is fragmented or not: here's an example of what you will see in the 'Movie:' part of the mp4info output for a non-fragmented MP4 file (the line "fragments: no")

...
Movie:
  duration:   147188 ms
  time scale: 2997
  fragments:  no

Found 2 Tracks
...
If you have non-fragmented MP4 files, you can use mp4fragment to fragment them.

Example

mp4fragment somefile.mp4 somefile-fragmented.mp4

Generating the MPD

Once you have fragmented MP4 files, you need to create an MPD. For single-bitrate streaming, a single MP4 file is required. For multi-bitrate streaming, you will need a set of MP4 files that have been encoded with closed GOPs (Group Of Pictures) with equal durations. Also, the audio track in all the files should be encoded with the same parameters. Once you have your input files, you can use the python script mp4-dash.py (located under Source/Python/utils) to automatically generate the DASH MPD and optionally split the MP4 file into individual file segments. This script needs to invoke the Bento4 command line binaries mp4dump, mp4encrypt, mp4info, and mp4split compiled from the source, so you'll need to use the '--exec-dir' option to specify the directory where your built binaries reside (platform dependent).

If you just run the 'mp4-dash.py' script by itself, it will print out the options that are supported:

Usage: mp4-dash.py [options] <media-file> [<media-file> ...]

Each <media-file> is the path to a fragmented MP4 file, optionally prefixed
with a stream selector delimited by [ and ]. The same input MP4 file may be
repeated, provided that the stream selector prefixes select different streams.
Version 1.4.0 r557

Options:
  -h, --help            show this help message and exit
  --verbose             Be verbose
  --debug               Print out debugging information
  -o <output-dir>, --output-dir=<output-dir>
                        Output directory
  -f, --force           Allow output to an existing directory
  --init-segment=<filename>
                        Initialization segment name
  -m <filename>, --mpd-name=<filename>
                        MPD file name
  --no-media            Do not output media files (MPD/Manifests only)
  --rename-media        Use a file name pattern instead of the base name of
                        input files for output media files.
  --no-split            Do not split the file into individual segment files
  --use-segment-list    Use segment lists instead of segment templates
  --use-segment-template-number-padding
                        Use padded numbers in segment URL/filename templates
  --use-segment-timeline
                        Use segment timelines (necessary if segment durations
                        vary)
  --min-buffer-time=<duration>
                        Minimum buffer time (in seconds)
  --max-playout-rate=<strategy>
                        Max Playout Rate setting strategy for trick-play
                        support. Supported strategies: lowest:X
  --language-map=<lang_from>:<lang_to>[,...]
                        Remap language code <lang_from> to <lang_to>. Multiple
                        mappings can be specified, separated by ','
  --smooth              Produce an output compatible with Smooth Streaming
  --smooth-client-manifest-name=<filename>
                        Smooth Streaming Client Manifest file name
  --smooth-server-manifest-name=<filename>
                        Smooth Streaming Server Manifest file name
  --hippo               Produce an output compatible with the Hippo Media
                        Server
  --hippo-server-manifest-name=<filename>
                        Hippo Media Server Manifest file name
  --encryption-key=<KID>:<key>
                        Encrypt all audio and video tracks with AES key <key>
                        (in hex) and KID <KID> (in hex). Alternatively, the
                        <key> can be specified as the character '#' followed
                        by a base64-encoded key seed.
  --encryption-args=<cmdline-arguments>
                        Pass additional command line arguments to mp4encrypt
                        (separated by spaces)
  --use-compat-namespace
                        Use the original DASH MPD namespace as it was
                        specified in the first published specification
  --marlin              Add Marlin signaling to the MPD (requires an encrypted
                        input, or the --encryption-key option)
  --playready           Add PlayReady signaling to the MPD (requires an
                        encrypted input, or the --encryption-key option)
  --playready-header=<playready-header>
                        Add a PlayReady PRO element in the MPD. The use of
                        this option implied the --playready option.The
                        <playready-header> argument can be either: (1) the
                        name of a file containing a PlayReady XML Rights
                        Management Header (<WRMHEADER>) or a PlayReady Header
                        Object (PRO) in binary form,  or (2) the character '#'
                        followed by a PlayReady Header Object encoded in
                        Base64, or (3) one or more <name>:<value> pair(s)
                        (separated by '#' if more than one) specifying fields
                        of a PlayReady Header Object (field names include
                        LA_URL, LUI_URL and DS_ID)
  --playready-add-pssh  Store the PlayReady header in a 'pssh' box in the init
                        segment(s)
  --exec-dir=<exec_dir>
                        Directory where the Bento4 executables are located