Packaging for MPEG-DASH

Unified Packager generates all files required for MPEG-DASH streaming using fragmented MP4 audio/video files as input. To enable the MPEG-DASH packaging mode, the first option on the command-line must be --package-mpd.

The following is a list of all options specific to MPEG-DASH packaging.

Options for MPEG-DASH packaging

--package_mpd

Enable MP4Split's MPEG-DASH packaging mode.

--fragment_duration

The duration of each fragment (in milliseconds). Defaults to using the GOP size.

MPEG-DASH profile

ISOBMFF On Demand

The MPEG-DASH profile supported by the packager is the ISO Base media file format On Demand profile: urn:mpeg:dash:profile:isoff-on-demand:2011.

This is the most basic profile for On-Demand content and thus generates the best compatibility among DASH players and DASH capable devices.

The requirements imposed by this profile are:

  • A single segment for each representation (one audio or video track per file).
  • Subsegments are aligned across representations (GOP aligned fragments).
  • Subsegments must begin with a Stream Access Point (IDR/keyframe).
  • The segment is indexed using the Segment Index ('sidx').

ISOBMFF Main

When the above requirements are not met (for instance when having audio and video in one file), the packager uses the Main profile: urn:mpeg:dash:profile:isoff-main:2011.

This might or might not fit the player used.

Creating the media files (.mp4)

First we have to package the audio and video tracks so that it fulfills the requirements listed above. Note that the extension used for MP4 video files (.mp4) does not necessarily tell you the exact format is used interally for storing the sample data. Packaging the content specificly for DASH makes sure that the requirements are met and all the information is stored in the resulting MP4 file.

The mp4split commands for packaging the audio and video files:

#!/bin/bash

mp4split --package_mpd -o audio.mp4 \
  oceans-64k.mp4

mp4split --package_mpd -o video-1.mp4 \
  oceans-250k.mp4

mp4split --package_mpd -o video-2.mp4 \
  oceans-380k.mp4

Creating the media files with Common Encryption

Next to preparing content in-the-clear, you can Common Encrypt the audio and video files.

The following example encrypts the files using a single pair of Key ID (KID) and Content Encryption Key (CEK).

The signaling of the content protection is different depending on the DRM systems used. PlayReady signaling requires the License Acquisition URL (LAURL). Widevine requires the "pssh" as drm_specific_data.

#!/bin/bash

KID=10000000100010001000100000000001
CEK=3a2a1b68dd2bd9b2eeb25e84c4776668
LAURL="http://playready.directtaps.net/pr/svc/rightsmanager.asmx?PlayRight=1&UseSimpleNonPersistentLicense=1"
PSSH=YOUR_PSSH

mp4split --package_mpd -o audio.mp4 \
  --iss.key=${KID}:${CEK} --iss.license_server_url=${LAURL} \
  --widevine.key=${KID}:${CEK} --widevine.drm_specific_data=${PSSH} \
  oceans-64k.mp4

mp4split --package_mpd -o video-1.mp4 \
  --iss.key=${KID}:${CEK} --iss.license_server_url=${LAURL} \
  --widevine.key=${KID}:${CEK} --widevine.drm_specific_data=${PSSH} \
  oceans-250k.mp4

mp4split --package_mpd -o video-2.mp4 \
  --iss.key=${KID}:${CEK} --iss.license_server_url=${LAURL} \
  --widevine.key=${KID}:${CEK} --widevine.drm_specific_data=${PSSH} \
  oceans-380k.mp4

Creating the Media Presentation Description file (.mpd)

Step two is creating the Media Presentation Description (MPD) using the packaged audio and two video files.

#!/bin/bash

mp4split --package_mpd -o oceans.mpd \
  audio.mp4 \
  video-1.mp4 \
  video-2.mp4

Content protection signaling is automatically added to the MPD using the protection information stored in the media files. When PlayReady and/or Widevine information is present, then these schemes are added to the MPD. Marlin has no explicit signaling in the media files, and is always added to the MPD.

#!/bin/bash

mp4split --package_mpd -o oceans.mpd \
  audio.mp4 \
  video-1.mp4 \
  video-2.mp4

Please download the mpeg-dash-cenc.sh sample script which creates the various server manifest as discussed above. The sample content is Tears of Steel.

Dolby Vision Support

New in version 1.7.18.

Packaging MPEG-DASH with Dolby Vision Profile 5, aka Single Layer Non Backwards Compatible (NBC) is supported.

First take the input files containing Dolby Vison NBC to create a fragmented mp4.

Then use the fragmented mp4 output to create an MPD.

#!/bin/bash

mp4split --package_mpd -o video-out.ismv \
  video-in-dolby.mp4

mp4split --package_mpd -o video.mpd \
  video-out.ismv

Playback

Playback is supported by at least the following sample players:

  • dash-as, an open source ActionScript project.
  • YouTube, javascript.
  • dash.js. the DASH IF Reference Player using Javascript.

See Which devices support DASH playback? and Which browsers support DASH playback? for more information.

Javascript / HTML5 based players

The Cross-Origin Resource Sharing (CORS) HTTP headers are necessary when the (javascript) player and content are hosted on different domains.

The are set like the following in the (Apache) virtual host configuration:

# Necessary for Media Source Extensions (MSE)
Header always set Access-Control-Allow-Headers "origin, range"
Header always set Access-Control-Allow-Methods "GET, HEAD, OPTIONS"
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Expose-Headers "Server,range"

Action Script / Flash based players

For Action Script (Flash) based players the webserver needs to be setup to support Byte-Range requests through a query parameter. This is achieved by rewriting the byte range in the query parameter to the appropriate Range HTTP header in the request. The dash.as player appends '?bytes=' and the dash.js player appends '?range=' to the URL. The two rewrite rules are given in the configuration below.

  <IfModule headers_module>
    <IfModule rewrite_module>
      # dash.as
      # ^(.*) if .htaccess in a root; ^/(.*) otherwise
      RewriteEngine On
      RewriteCond %{QUERY_STRING} ^(.*)bytes=(.*)$
      RewriteRule ^(.*) - [L,E=range:%2]
      RequestHeader set Range "bytes=%{range}e" env=range

      # dash.js
      # ^(.*) if .htaccess in a root; ^/(.*) otherwise
      RewriteEngine On
      RewriteCond %{QUERY_STRING} ^(.*)range=(.*)$
      RewriteRule ^(.*) - [L,E=range:%2]
      RequestHeader set Range "bytes=%{range}e" env=range
  </IfModule>
</IfModule>

Important

When prepackaging files for MPEG-DASH playout, please make sure that the MP4 files are hosted on a location that doesn't have a running Unified Origin handling the MP4 files. Otherwise the progressive MP4 download feature will take over and it'll reformat the prepackaged MP4 files to progressive MP4 instead. This may prevent playout and cause SIDX errors to be displayed by the player.

Advanced recipes

Tuning Common Encryption

--disable_selective_nal_encryption

For NAL structured video samples, only video data in slice NALs should be encrypted. Other NAL types are kept in the clear.

Specifying this option overrides the (selective) encryption and encrypts all NAL units with a fixed number of bytes in the clear.