ExpressPlay Packager Guide
Introduction
ExpressPlay Packaging Tools are a set of recommended tools which provide you the ability to convert and encrypt audio/video content files into a Marlin-protected format suitable for playback using the ExpressPlay SDK or any Marlin compliant player device.
Three groups of command-line tools are part of the ExpressPlay Packaging Tools set, with the first 2 recommended for the majority of use cases:
- Bento4 Tools for DASH/Smooth/MP4 (tools and documentation available at www.bento4.com), for streaming and downloaded MP4 media
- Apple HLS Tools (tools and documentation available at Apple's developer web site) for streaming of TS media
- ExpressPlay TS Tools (available HERE, documentation is below), for packaging TS media into Marlin BBTS formatted media. This should be reserved for special use cases when the Apple HLS format is not suitable.
Collectively the ExpressPlay Packaging Tools can support standard MP4 and MPEG-2 TS files, as well as Marlin-protected files, such as DCF and PDCF files that can be created from MP4 files. The tools are capable of performing the following tasks:
- Converting between different file types. For example, the Ts2Encrypt tool encrypts and packages an MPEG-2 TS file into a Marlin BBTS file, and the Ts2Decrypt tool performs the opposite operation, decrypting a BBTS file to create an MPEG-2 TS file.
- Gathering information from files. For example, the mp4info tool returns detailed information about an MP4-based file, such as whether or not it is encrypted, what the encryption scheme used is, what the overall video/audio length is, and information about the tracks in the file (if any).
- Modifying file content. For example, mp4edit can be used to insert, remove, or replace atoms (a.k.a. boxes) in an MP4-based file.
- Processing MS3 (Marlin Simple Secure Streaming) compound URIs to obtain both the content URL and the Stream Access Statements (SASs) that define usage requirements and provide the decryption key(s).
This guide assumes you are already familiar with the Marlin and other concepts, content file formats, etc. that are referenced by the tools, other than providing a very brief overview below of the main Marlin-protected content formats.
Some tools, such as those for obtaining information from or converting existing files, do not require much prior knowledge. However, others do. For example, knowledge of the MP4 file format will be necessary if you want to use the mp4edit tool to insert, remove, or replace atoms in an MP4 file.
Marlin-Protected Content
Marlin-protected content is simply regular video and/or audio content provided in an encrypted form in a file whose format is based on an extension to a standard media file format. Here are the most common formats in which Marlin content is provided:
- PDCF and DCF. These are two formats for protected MP4 content. These formats are based on the ISO Base File Format (14496-12). They are used primarily for encrypted H.264 (AVC) + AAC content. They should be used for downloaded and progressively downloaded content only (note that in the case of progressive download, the application is responsible for the downloading). In the case of PDCF, each track can be individually encrypted, while with DCF, the entire in-the-clear content is encrypted in bulk. Consequently, with PDCF there can be one or more content IDs and corresponding content keys, while with DCF, there is a single content ID and content key.
- DASH and HLS. The DASH and HLS streaming formats are applicable to Marlin protected content. Playlists need to flag the content protection. For HLS in particular the master playlist must include either #EXT-X-KEY:METHOD=MARLIN-BBTS or #EXT-X-KEY:METHOD=AES-128 tag otherwise the content will be recognized as clear and the ExpressPlay SDK will exit with error. The encryption method #EXT-X-KEY:METHOD=NONE must be declared in the playlist(s) describing clear stream(s), for example subtitles. If the tag is omitted the default encryption method will be applied to the clear stream causing errors.
- Marlin BBTS. This is an encrypted format based on MPEG-2 TS. It is primarily used for streaming when DASH or HLS are not otherwise suitable.
Playing Marlin-protected content requires access to the content key(s) needed to decrypt the content. It also requires satisfaction of the conditions specified for content access. The content keys and the access rights specifications can be delivered in two different ways: via Marlin Broadband licenses or via MS3 (Marlin Simple Secure Streaming) Stream Access Statements (SAS).
MP4/DASH Tools
Full documentation of the MP4/DASH packaging tools is available at the Bento4 web site. Please visit the Bento4 site for a description of all MP4 and DASH-related tools.
HLS Tools
Full documentation of the HLS tools is available at Apple's HLS Streaming site. Please visit the HLS site for a description of all tools.
ExpressPlay TS Tools
Ts2AdaptiveAwareEncrypt |
Encrypts and packages an MPEG-2 TS file into a Marlin BBTS file, just like Ts2Encrypt, except that this also takes a “rotation point file” as input that is used to dictate where the Entitlement Control Messages (ECMs) are to be inserted. |
Ts2Decrypt |
Decrypts a Marlin BBTS file, producing essentially the same MPEG-2 TS file originally encrypted to create the BBTS file. |
Ts2Encrypt |
Encrypts and packages an MPEG-2 TS file into a Marlin BBTS file. |
Ts2FileEncrypterStitcher |
Creates a single encrypted file out of one or more cleartext TS2 files. |
Ts2Info |
Provides a small amount of information about an MPEG-2 TS file or a Marlin BBTS file. For the latter, the information includes the Marlin content ID and protection type. |
Ts2UdpProcessor |
Uses UDP (User Datagram Protocol) to read data from an input port, encrypt or decrypt that data, and then send the output to a specified host and port. |
Ts2UdpProcessorCommand |
Provides the ability for Ts2UdpProcessor to rotate keys while running. The Ts2UdpProcessorCommand tool sends commands to Ts2UdpProcessor while running. |
BBTS Content IDs
Several of the tools, such as Ts2Encrypt and Ts2Decrypt, have a parameter that must be a BBTS-formatted content ID. Consult the Marlin Broadband Transport Stream (BBTS) Specification for details. For your convenience, a brief summary is provided here.
The syntax for a content ID for a program is the following:
CID="cid:"||socID||"#P"||serviceBaseCID||"@"||hex(program_CID_extension)
and the syntax for a content ID for a service is the following:
CID="cid:"||socID||"#S"||serviceBaseCID||"@"||hex(service_CID_extension)
where
- || represents concatenation.
- socID equals “marlin” or is retrieved via an unspecified out-of-band mechanism.
- serviceBaseCID is the base part of the content ID of the programs and/or services contained in the BBTS. It must be a globally unique URI. It is recommended, but not required, that this service base content ID be composed as follows:
- program_CID_extension identifies a specific content item within the program.
- service_CID_extension identifies a specific content item within the service.
- The hex() function is an 8-character hexadecimal representation of its parameter (either program_CID_extension or service_CID_extension). It contains hexadecimal characters 0-9 and a-f (in lowercase), with possible preceding zeros.
serviceBaseCID=organization||"-"||service
where organization equals the organization identifier (registered with Marlin) for the organization providing the service, and service is an identifier for the service which is chosen by the organization providing the service.
Here is an example of a content ID for a program:
cid:marlin#Pvod:channel@0142cafd
Here is one for a service:
cid:marlin#Suniversal@21cafe34
TS Tools in Detail
Each of the following sections provides documentation for a single tool. Each contains a tool description, a usage statement, information about all the parameters, and one or more example calls.
How to interpret the usage statements:
- Items in angle brackets represent placeholders for actual values. For example, one of the options may be shown as
- Items in square brackets are optional.
- In many cases, the usage statement includes [options], indicating that one or more options are allowed at that position. The subsequent parameters subsection lists all the possible options.
- You can see the usage statement for each of the mp4* and Ts2* tools by calling the tool with no parameters.
- Many example calls are longer than can fit on a single line. For each of these, each line contains the maximum number of characters that will fit on the line, and the subsequent line(s) contain the rest of the call. All this should be concatenated together (without extra spaces) into a single “line” in order to make an actual call with the specified parameters.
--verbosity <n>
Here, <n> is a placeholder for a number between 0 and 3, so the option specified in an actual call would look something like the following:
--verbosity 2
Ts2AdaptiveAwareEncrypt
Description
Encrypts and packages an MPEG-2 TS file into a Marlin BBTS file (see the Marlin Broadband Transport Stream Specification), just like Ts2Encrypt, except that this also takes a “rotation point file” as input that is used to dictate where (in the Transport Stream Packets) the Entitlement Control Messages (ECMs) are to be inserted.
The format of the rotation file is the following:
- File ::= RotationPoints
- RotationPoints ::= [SwitchPoints] RotationPoint
- RotationPoint ::= PacketNum NewLine
- PacketNum ::= Decimal Integer
The rotation file is a simple text file with one line per ECM location. For example, the first several lines of the file might be something like the following:
7
2137
4666
6836
9172
11500
13868
16037
18358
20688
22994
25529
27520
30107
32211
34683
Usage
Ts2AdaptiveAwareEncrypt [options] <input> <output>
Parameters
[options]:
--protection {bbts-1.1|bbts-2.0}
MANDATORY: You must specify the BBTS protection option. The bbts-1.1 option is provided only for backward compatibility. New development should use the bbts-2.0 option value. There is no default value.
--key <cid>::<k>
MANDATORY: <cid> is a BBTS-formatted content ID (see §3), and <k> is a 128-bit key in hex.
--traffic-seed <s>
MANDATORY: traffic seed in hex.
--ksm-pid <pid>
MANDATORY: PID of the KSM (ECM).
--traffic-key-lifetime <secs>
MANDATORY: traffic key lifetime in seconds. Valid values range between 4 and 120.
--rotation-in <path>
MANDATORY: filepath to input rotation point file.
--rotation-out <path>
MANDATORY: filepath to output rotation point file.
--first-segment-index <index>
Specifies the first segment index. Default is 0.
--rights-issuer <url>
URI template for rights issuer.
--silent-rights <url>
URI template for silent rights acquisition.
--preview-rights <url>
URI template for preview rights acquisition.
--iv <iv>
A 128-bit initialization vector in hex. If this option is not specified, the default behavior is that the initialization vector will change for every rotation point (ECM insertion point).
--access-criteria <tag>:<value>
This option can be repeated to add more than one access criteria. The tag and value are specified in hex.
<input> – The MPEG-2 TS file to be encrypted.
– The resulting BBTS file.
Example
The following encrypts and packages the MPEG-2 TS file 796000.ts into the BBTS file 796000.bbts, using the specified options and rotation point files.
Ts2AdaptiveAwareEncrypt
–-protection bbts-2.0
--key cid:marlin#Suniversal@deadbeef::4bd3eb6bd171595764ec2050a20382e1
--traffic-seed 934b4bd3eb6bd171595764ec2050a20382e1
--traffic-key-lifetime 4
--ksm-pid 142
--rotation-in 796000_rotation_points.txt
--rotation-out 796000_rotation_points_bbts.txt 796000.ts 796000.bbts
Ts2Decrypt
Description
Decrypts a Marlin BBTS file, producing essentially the same MPEG-2 TS file originally encrypted to create the BBTS file.
Usage
Ts2Decrypt [options] <input> <output>
Parameters
[options]:
--key <cid>::<k> – In this, <cid> is a content ID (see §3) and <k> is a 128-bit key in hex.
<input> – The BBTS file to decrypt.
<output> – The resulting MPEG-2 TS file.
Example
The following call results in the decryption of the content in bigbucksbunny.bbts, and the creation of an MPEG-2 TS file bigbucksbunny.ts containing the decrypted content, assuming that the specified content ID and key are correct.
Ts2Decrypt --key cid:marlin#Suniversal@deadbeef::4bd3eb6bd171595764e
c2050a20382e1 bigbucksbunny.bbts bigbucksbunny.ts
Ts2Encrypt
Description
Encrypts and packages an MPEG-2 TS file into a Marlin BBTS file.
Usage
Ts2Encrypt [options] <input> <output>
Parameters
[options]:
--key <cid>::<k>
MANDATORY: <cid> is a BBTS-formatted content ID (see §3), and <k> is a 128-bit key in hex.
--protection {bbts-1.1|bbts-2.0}
MANDATORY: You must specify the BBTS protection option. The bbts-1.1 option is provided only for backward compatibility. New development should use the bbts-2.0 option value. There is no default value.
--zero-iv
If specified, a fixed all 0's IV will be used for content encryption. Overrides any preceeding --varying-iv options.
--crypto-period <n>
The crypto period (as defined in the BBTS specification), in seconds, between 1 and 120 (default: 2).
--varying-iv
If this is specified, a different IV will be used for each KSM (ECM). If this option is not specified, the default behavior is usage of a fixed random initialization vector.
--rights-issuer <url>
URI template for rights issuer.
--silent-rights <url>
URI template for silent rights acquisition.
--preview-rights <url>
URI template for preview rights acquisition.
--skip-payload-unit-start
If this is specified, any packet indicating the start of a new PES (Packetized Elementary Stream) will not be encrypted.
--single-key-layer
If this is specified, the encryption will be done using the BBTS single-key-layer mode.
--access-criteria <tag>:<value>
This option can be repeated to add more than one access criteria. The tag and value are specified in hex.
<input> – The MPEG-2 TS file to be encrypted.
<output> – The resulting BBTS file.
Example
The following encrypts the MPEG-2 TS file bigbucksbunny-trailer.ts using the specified key and content ID, creating the BBTS file bigbucksbunny-trailer.bbts.
Ts2Encrypt --protection bbts-2.0 --key cid:marlin#Suniversal@deadbeef::000102030405060708090a0b0c0d0e0f bigbucksbunny-trailer.ts bigbucksbunny-trailer.bbts
Ts2FileEncrypterStitcher
Description
Creates a single encrypted file out of one or more cleartext MPEG-2 TS files. The content ID and key are reset after each file.
Usage
Ts2FileEncrypterStitcher [options] <output>
Parameters
[options]:
--media <path>::<cid>::<k>
MANDATORY: <path> is the path to an MPEG-2 TS cleartext file, <cid> is a BBTS-formatted content ID (see §3), and <k> is a 128-bit key in hex. One or more --media options may appear, each specifying a particular input file, content ID, and key.
--protection {bbts-1.1|bbts-2.0}
MANDATORY: You must specify the BBTS protection option. The bbts-1.1 option is provided only for backward compatibility. New development should use the bbts-2.0 option value. There is no default value.
--zero-iv
If specified, a fixed all 0's IV will be used for content encryption. Overrides any preceeding --varying-iv options.
--crypto-period <n>
The crypto period (as defined in the BBTS specification), in seconds, between 1 and 120 (default: 2).
--varying-iv
If this is specified, a different IV will be used for each KSM (ECM). If this option is not specified, the default behavior is usage of a fixed random initialization vector.
--rights-issuer <url>
URI template for rights issuer.
--silent-rights <url>
URI template for silent rights acquisition.
--preview-rights <url>
URI template for preview rights acquisition.
--skip-payload-unit-start
If this is specified, any packet indicating the start of a new PES (Packetized Elementary Stream) will not be encrypted.
--access-criteria <tag>:<value>
This option can be repeated to add more than one access criteria. The tag and value are specified in hex.
<output> – The resulting BBTS file.
Example
The following creates bigbucks-stitched.bbts, which is the result of combining in one file the encryptions of the specified input files (bigbucks0.ts, bigbucks1.ts, and bigbucks2.ts). Each input is encrypted using the specified key and is assigned the specified content ID.
Ts2FileEncrypterStitcher --protection bbts-2.0 --media bigbucks0.ts::cid:marlin#Pvod:channel@0142cafd::ab98cd76ef541237080cfabe98421770 --media bigbucks1.ts::cid:marlin#Pvod:channel@0142cafe::ab98cd76ef541237080cfabe98421771 --media bigbucks2.ts::cid:marlin#Pvod:channel@0142caff::ab98cd76ef541237080cfabe98421772 bigbucks-stitched.bbts
Ts2Info
Description
Provides a small amount of information about an MPEG-2 TS file or a Marlin BBTS file. For the latter, the information includes the Marlin content ID.
Usage
Ts2Info [options] <input>
Parameters
[options]:
--max-packet-count <n>
Specifies the maximum number of packets screened. If <n> is -1, the number is unbounded. The default maximum number is 100.
--max-cat-packet-count-from-ksm <n>
Specifies the maximum number of packets to screen for CAT after KSMT/ECM is found. The value can be from 0 to max-packet-count (default is 100).
<input> – The BBTS file whose information will be returned.
Example
Ts2Info bloomberg_h264_sd_ac3-120sec.bbts
Marlin Protected file:
Traffic Protection System: BBTS 2.0, TRUNCATED SHA1 KDF
Marlin content id is cid:marlin#Suniversal@deadbeef
es pid: 68
es type: 1B
es pid: 69
es type: 81
Ts2UdpProcessor
Description
Uses UDP (User Datagram Protocol) to read data from an input port, encrypt or decrypt that data, and then send the output to a specified host and port. That is, it uses UDP to read and output data, and the output data is the result of either encrypting input MPEG-2 TS file data into a Marlin BBTS file or decrypting input BBTS file data into an MPEG-2 TS file.
Ts2UdpProcessor illustrates usage of TS2_BbtsBufferEncrypter, TS2_BbtsBufferDecrypter, and ATX_DataBuffer.
Usage
Ts2UdpProcessor [options] <input port> <output hostname> <output port>
Parameters
[options]:
--protection {bbts-1.1|bbts-2.0}
MANDATORY: You must specify the BBTS protection option. The bbts-1.1 option is provided only for backward compatibility. New development should use the bbts-2.0 option value. There is no default value.
--type <enc or dec>
Specifies whether the input stream should be encrypted (enc) or decrypted (dec). The default is enc.
--key <cid>::<k>
MANDATORY: <cid> is a BBTS-formatted content ID, and <k> is a 128-bit key in hex.
--crypto-period <n>
The crypto period (as defined in the BBTS specification), in seconds, between 1 and 120 (default: 2). This parameter is only relevant when the type value is enc.
--varying-iv
If this is specified, a different IV will be used for each KSM (ECM). If this option is not specified, the default behavior is usage of a fixed random initialization vector. This parameter is only relevant when the type value is enc. See also --zero-iv.
--zero-iv
If specified, a fixed all 0's IV will be used for content encryption. Overrides any preceeding --varying-iv options. This parameter is only relevant when the type value is enc.
--rights-issuer <url>
URI template for rights issuer. This parameter is only relevant when the type value is enc.
--silent-rights <url>
URI template for silent rights acquisition. This parameter is only relevant when the type value is enc.
--preview-rights <url>
URI template for preview rights acquisition. This parameter is only relevant when the type value is enc.
--skip-payload-unit-start
If this is specified, any packet indicating the start of a new PES (Packetized Elementary Stream) will not be encrypted. This parameter is only relevant when the type value is enc.
--multicast-join <group>
Join the multicast group <group>.
--multicast-ttl <ttl>
Set the Time To Live value for outgoing multicast packets (when sending to a multicast address).
Setting "--multicast-ttl 1" would appropriate for a LAN.
Higher numbers are useful when reaching computers/devices further away on a network that includes routers. Setting "--multicast-ttl 5" might be a reasonable choice on corporate network, allowing 5 hops crossing different subnets.
--show-progress
Print a running count of packets processed while the loop is running.
--payload-header-size
Ignore the first <n> bytes at the start of each packet. For example, if UDP packets contain RTP-encapsulated data with a 12-byte header followed by TS packets, the option --payload-header-size 12 tells the UDP to ignore the first 12 bytes of each UDP packet so as to only process the TS packet payload.
--access-criteria <tag>:<value>
This option can be repeated to add more than one access criteria. The tag and value are specified in hex.
<input port> – The input port.
<output hostname> – The output hostname.
<output port> – The output port.
Examples
In the following, data is read from port 8888 and encrypted using the specified key and content ID. The result is output to localhost on port 9999:
Ts2UdpProcessor
-–protection bbts-2.0
--type enc
--key cid:marlin#Pvod:channel@0142cafe::d8
b329977ca4132dac79821dbaca8214 8888 localhost 9999
In the following, data is read from port 8888 and decrypted using the specified key and content ID. The result is output to localhost on port 9999:
Ts2UdpProcessor
-–protection bbts-2.0
--type dec
--key cid:marlin#Pvod:channel@0142caff::1247563dcf9ca873baffc245978cba77 8888 localhost 9999
This will receive packets on port 8000, ignore the first 12 bytes of each packet, encrypt the rest of the payload, and retransmit the result (including the ignored 12 byte header) as multicast packets to the multicast address 239.255.255.252 on port 8001
Ts2UdpProcessor
-–protection bbts-2.0
--type enc
--payload-header-size 12
--multicast-ttl 5
--key cid:marlin#Pvod:channel@0142cafe::d8b329977ca4132dac79821dbaca8214 8000 239.255.255.252 8001
This joins the multicast group 239.255.255.252, receive packets on port 8001, ignore the first 12 bytes of each packet, decrypt the rest and transmit the result (including the ignored 12 byte header) to localhost on port 8002
Ts2UdpProcessor
-–protection bbts-2.0
--type dec
--payload-header-size 12
--multicast-join 239.255.255.252
--key cid:marlin#Pvod:channel@0142cafe::d8b329977ca4132dac79821dbaca8214 8001 localhost 8002
Ts2UdpProcessorCommand
Description
Provides the ability for Ts2UdpProcessor to rotate keys while running. The Ts2UdpProcessorCommand tool sends commands to Ts2UdpProcessor while running.
Usage
Ts2UdpProcessorCommand <cmd> <hostname> <port> [params]
Parameters
<cmd> – Currently only the following command is defined: set-key
<hostname> – The hostname or IP address of the UDP listener.
<port> – The UDP port on which to send the command to the listener Command Parameters.
Example
Parameters and Example
set-key: <cid-ext> <key>
<cid-ext> = 32-bit CID extension in hex
<k> = 128-bit key in hex
Example: Ts2UdpProcessorCommand.exe set-key localhost 8888 0142babe 00010203040506070001020304050607
where 8888 is input port, = 0142babe and = 00010203040506070001020304050607
Producing Marlin-Protected ABR Streams
HTTP Live Streaming (HLS) and Dynamic Adaptive Streaming over HTTP (DASH) are ways for a client to request streaming content according to its bandwidth limitations. It can be used for both live and VOD use cases..
The HLS specification is available as a draft IETF RFC available at http://tools.ietf.org/html/draft-pantos-http-live-streaming-07
This technology uses a playlist file as a manifest and MPEG2-TS as a container media format. A playlist is essentially a text file specifying media to be played in order, and the text file has a particular MIME type (application/vnd.apple.mpegurl) indicating that it’s a playlist.
MPEG DASH is MPEG’s standardized Dynamic 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 Description).
- ISO/IEC 23001-7 specifies the Common Encryption scheme 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.
This technology uses an MPD (Media Presentation Description) file as a manifest and fragmented MP4 files. An MPD is essentially a text file specifying media to be played in order.
Content Prerequisites
The steps below assume that you are starting from MP4 content and have already created or obtained cleartext MP4 content that is appropriately encoded, using hardware and/or software tools/encoders not provided by Intertrust.
For single-bitrate streaming, a single MP4 source file is all that is needed. If multi-bitrate streaming is desired, you will need to create multiple MP4 files, encoded at the desired different bitrates. They must be encoded with closed GOPs (Group of Pictures) with equal durations. The audio track in each of the files must also be encoded using the same durations as the video content. If content without closed GOPs of equal durations is provided, then the segments generated won’t be of equal durations, and you may see some improper seek bar behavior while playing HLS content. For example, the seek bar will end before the content is played completely in the desktop version of the ExpressPlayer application.
The following audio and video options are supported by the ExpressPlay SDK:
- Audio
- AAC-encoded ADTS packets
- 2 channels
- Video
- H.264-encoded video in an MPEG-4 container
- H.264-encoded video in an MPEG-2 container
- PAR (Pixel Aspect Ratio) must be 1:1
Converting MP4 to MPEG-2 TS
Once you have appropriately-encoded MP4 content, you can use the mp42ts tool to convert it to MPEG-2 TS. For single-bitrate streaming, you simply run mp42ts on the single MP4 file to convert it to an MPEG-2 TS file. For multi-bitrate streaming, run mp42ts multiple times, to convert each of the MP4 files (which were encoded at the different desirable bitrates) to MPEG-2 TS.
Given an MP4 file, mp42ts outputs one or more MPEG-2 TS file segments, each of a specified minimum duration or, more specifically, that duration minus a specified or default threshold number of milliseconds. In the following example, mp42ts converts the source MP4 file elephantsdream_source.mp4 into segment files and the duration of each segment (except possibly the last one) will be at least the specified duration of 5 seconds minus the default threshold of 50 ms:
mp42ts.exe --segment 5 elephantsdream_source.mp4 ele.%d.ts
Packaging HLS Content
Prerequisites
- Python2.7
- Clear MP4 Content (for example: $WasabiClientTestContentSampleAlwaysPlaySourceelephantsdream_source.mp4)
- Scripts:
- $WasabiServerToolsPackagingHttpLiveStreamingcreate-hls-playlist.py
- $WasabiServerToolsPackagingHttpLiveStreamingpackage-hls-files.py
- Binaries:
- mp42ts (bento4 tool)
- Ts2AdaptiveAwareEncrypt
Creating HLS Playlist
Use the create-hls-playlist.py script to create m3u8 HLS playlists out of a directory structure of files. The directory structure expected is:
MainDirectory
SubDirectory1
File1
File2
. . .
SubDirectory2
File1
File2
. . .
. . .
The naming conventions and requirements are the following:
- MainDirectory. There are no restrictions on the main directory name or location. A master playlist file named MainDirectory.m3u8 will be created within the MainDirectory.
- SubDirectoryN. Each of the subdirectories must contain the same number of files as the other subdirectories, and each must obey the following naming convention:
- FileN. Each file in a subdirectory must obey the following naming convention:
- Python 2.7
- Clear MP4 Content
- (for example: $WasabiClientTestContentSampleAlwaysPlaySourceelephantsdream_source.mp4)
- Scripts: (from Bento4 Trunk)
- $Bento4SourcePythonutilsmp4-dash.py
- Binaries: (bento4 tools)
- Mp4Fragment
- mp4encrypt
- mp4split
- mp4dump
- mp4info
<char(s)>-<at least one lowercase letter><bitrate>
That is, the name of each subdirectory must consist of one or more characters (letters and/or numbers), followed by a hyphen, followed by at least one lowercase letter, followed by digits indicating the bitrate to be used for all the files in the subdirectory. More specifically, the script will extract the bitrate from the subdirectory name and use it to construct the BANDWIDTH value (adding three zeros to the bitrate) to be specified in the playlist for the files in the subdirectory.
Here is an example subdirectory name:
elephantsdream-hq1234
Where 1234 indicates the bitrate (in kbps) of the files in the directory.
<name>.<mediasequence>.ts
where
Create a directory structure accepted by the script:
./ElephantsDream:
elephantsdream-q7777 elephantsdream-q888
./ElephantsDream/elephantsdream-q7777:
ele.0.ts ele.1.ts ele.2.ts ele.3.ts ele.4.ts ele.5.ts
./ElephantsDream/elephantsdream-q888:
ele.0.ts ele.1.ts ele.2.ts ele.3.ts ele.4.ts ele.5.ts
In case of multiple bit-rate, place the segments of the content with one bitrate in folder (say elephantsdream-q7777) and with other bitrate in another folder (say elephantsdream-q888).
Usage
Here is the script usage:
create-hls-playlist.py <targetduration> <directory>
Where <targetduration> represent the maximum media file duration (in seconds). Each file in the playlist must be no longer than <targetduration> seconds.
python create-hls-playlist.py 5 ElephantsDream
The script creates a master playlist (ElephantsDream.m3u8) in the main directory as well as sub playlists (index.m3u8) in each sub directory.
Package HLS
Create bin/<platform> folder (examples: bin/linux2, bin/darwin, bin/win32) where the script package-hls-files.py script is located and place the Ts2AdaptiveAwareEncrypt binary inside it. The package-hls-files.py script takes the master playlist as an input and encrypts the files to which it points.
Usage
package-hls-files.py [options] <contentid> <m3u8file>
Parameters
[options]:
-k KEY, --key=KEY
If specified, this must be 32 hex chars (representing 16 bytes). If not specified, it is automatically generated.
-t TRAFFIC_KEY_SEED, --traffic-key-seed=TRAFFIC_KEY_SEED
If specified, this must be 32 hex chars (representing 16 bytes). If not specified, it is automatically generated.
-i TRAFFIC_IV, --traffic-iv=TRAFFIC_IV
If specified, this must be 32 hex chars (representing 16 bytes). If not specified, it is automatically generated.
-e ECM_PID, --ecm-pid=ECM_PID
pid for the generated ecm [default: 142]
-v {bbts-1.1|bbts-2.0}, --protection {bbts-1.1|bbts-2.0}
MANDATORY: You must specify the BBTS protection option. The bbts-1.1 option is provided only for backward compatibility. New development should use the bbts-2.0 option value. There is no default value.
-o OUTPUT_DIR, --output-dir=OUTPUT_DIR
Output directory for the protected files [default: ./ProtectedHls]
-r RIGHTS_ISSUER_URL, --rights-issuer-url=RIGHTS_ISSUER_URL
URL of the rights issuer.
-s SILENT_RIGHTS_URL, --silent-rights-url=SILENT_RIGHTS_URL
URL of the silent rights.
-p PREVIEW_RIGHTS_URL, --preview-rights-url=PREVIEW_RIGHTS_URL
URL of the preview rights.
-h, --help
Show this help message and exit.
Example
Package HLS using the default values for keys, traffic key seeds, etc:
python package-hls-files.py --protection bbts-2.0 cid:marlin#Pvod:channel@0142babe ElephantsDreamElephantsDream.m3u8
Here a ProtectedHls directory is created containing files with exactly the same names as the ElephantsDream directory, except in this case all the .ts files have encrypted content. Also, the master playlist is a little different, containing a tag specifying encryption information.
Packaging DASH Content
Prerequisites
Fragment the content
Use the following command to fragment the mp4 content if you have not fragmented already.
Mp4Fragment.exe elephantsdream_source.mp4 ele.mp4
The Mp4Fragment command takes a single MP4 file as input and produces a single MP4 file as output with same content but it is fragmented.
Package the content
Encrypt the fragmented files using mp4encrypt in an MPEG DASH CENC (Common Encryption) mode:
mp4encrypt
--method MPEG-CENC
--key 1:a0a1a2a3a4a5a6a7a8a9aaabacadaeaf:0123456789abcdef
--property 1:KID:121a0fca0f1b475b8910297fa8e0a07e
--key 2:a0a1a2a3a4a5a6a7a8a9aaabacadaeaf:aaaaaaaabbbbbbbb
--property 2:KID:121a0fca0f1b475b8910297fa8e0a07e ele.mp4 ele-cenc.mp4
Note the KID reference in the property flag. This syntax follows the simple profile of Marlin Extensions for Adaptive Streaming in which the Marlin-specific content ID in the Marlin license is derived from the KID like so:
- urn:marlin:kid:
Example content ID:
- urn:marlin:kid:1586f237d6a6aadd992e4948297e4567
Create DASH content
The mp4-dash.py example Python script included with the tools package generates a DASH MPD and other files as needed to reference the fragmented and encrypted MP4 files. The script also optionally splits the MP4 files into multiple individual file segments, in which case the MPD references these. This script works using Python 2.7.
The mp4-dash.py script invokes the mp4info (§4.13), mp4dump (§4.8), mp4encrypt (§4.10), and mp4split (§4.14) tools. As with the other tools in the tools package, the binaries for these tools are included for the different platforms in the bin/<platform> directories of the tools package. You should either add the appropriate directory for your platform to your execution path so the tools will be found automatically or simply specify the appropriate directory using the mp4-dash.py --exec-dir option.
Usage
python mp4-dash.py [options] <filename> [<filename> ...]
Parameters
[options]:
-h or --help
Shows the usage format and these options, then exits.
-v or --verbose
Verbose.
-f or --force
Allow output to an existing directory.
-d or --debug
Print out debugging information.
-o <output-dir> or -–output-dir=<output-dir>
Output directory. Default behavior is to create an output directory named output within the current directory.
--init-segment=<filename>
Initialization segment filename for the file that provides the metadata for playing the individual segments. There will be one initialization segment file per bitrate. The default filename is init.mp4.
-m <filename> or –-mpd-name=<filename>
Name for the manifest file (MPD) that is output. This file will be the primary input to a media player for playing the content.
–-mpd-only
Generate only the MPD file. That is, do not perform any media processing; do not generate media segments.
If this option is not specified, and neither is the --no-split option, the script not only generates the MPD but also splits the media into video and audio segments for each bitrate.
–-no-split
Do not split the media into individual segment files. In this case, the MPD generated by the script references content using byte ranges within the source file(s) rather than referencing individual segment files.
If this option is not specified, the script splits the media into video and audio segments for each bitrate, and the MPD generated references the multiple individual segment files.
–-use-segment-list
Generates an MPD file with lists of individual segment URLs (using SegmentList XML elements), as opposed to containing more concise segment templates (using SegmentTemplate elements) to specify the segments. The default is usage of segment templates.
--min-buffer-time=<duration>
Minimum buffer time, in seconds. Default is 0.0.
--video-frame-rate=<rate>
Video frame rate, in frames per second. Default is 23.976.
--video-codec=<codec>
Video codec string.
--audio-sample-rate=<rate>
Audio sample rate, in samples per second. Default is 44100.
--audio-codec=<codec>
Audio codec string.
–-marlin
Adds Marlin signaling to the MPD file, indicating that the content is Marlin-protected, not generic clear content.
–-exec-dir=<exec_dir>
Specifies the directory in which the tools needed by the script are located. Usage of this option may be more convenient than ensuring that the tools directory is on your execution path.
<filename> – One or more input file names.
Example for Single-bitrate Streaming Content
Here is an example call to mp4-dash.py for the situation in which a single input file is specified. In this call, most of the options are defaulted, and as a result the output is placed in a directory named output at the top level of the current directory, the initialization segment filename is init.mp4, the MPD file name is mpd.xml, and the input file is split into segments.
$ python mp4-dash.py --marlin ele-cenc.mp4
Here is the output directory structure and contents:
output
stream.mpd
audio
init.mp4
seg-0000.m4f
seg-0001.m4f
...
video
init.mp4
seg-0000.m4f
seg-0001.m4f
...
Example for Multi-bitrate Streaming Content
Here is an example call to mp4-dash.py for the situation in which multiple input files are specified, each for a different bitrate. In this call, most of the options are defaulted, and as a result the output is placed in a directory named output at the top level of the current directory, the initialization segment filename is init.mp4, the MPD file name is mpd.xml, and the input files are split into segments.
python mp4-dash.py --marlin ele-cenc-1.mp4 ele-cenc-2.mp4 ele-cenc-3.mp4
Here is the output directory structure and contents:
output
stream.mpd
audio
init.mp4
seg-0000.m4f
seg-0001.m4f
...
video
1
init.mp4
seg-0000.m4f
seg-0001.m4f
...
2
init.mp4
seg-0000.m4f
seg-0001.m4f
...
3
init.mp4
seg-0000.m4f
seg-0001.m4f
...
Streaming Support in the ExpressPlay SDK
For a list of media formats supported by the ExpressPlay SDK, please see the SDK Key Concepts page.