


{"id":11040,"date":"2017-09-08T21:00:09","date_gmt":"2017-09-08T21:00:09","guid":{"rendered":"https:\/\/expressplay.local\/?page_id=11040"},"modified":"2021-01-29T10:08:13","modified_gmt":"2021-01-29T18:08:13","slug":"packager-guide","status":"publish","type":"page","link":"https:\/\/www.expressplay.com\/ko\/developer\/packager-guide\/","title":{"rendered":"ExpressPlay Packager Guide"},"content":{"rendered":"<style>\nh2,h3 {\n    margin: 20px 0;\n}<\/p>\n<p>code {\n    word-break: break-all;\n    white-space: pre-wrap;\n    font-size: 14px;\n    color: #555;\n    margin: 20px 0;\n    background-color: #f5f5f5;\n    padding: 20px;\n}\n.anchor-offset {  display: block;< position: relative;  top: -75px;visibility: hidden;}\n\ntable {\n    margin: 10px 0;\n}\n\ntd,th {\n    padding: 10px;\n}\n\ntable, td, th {\n    border: 1px solid #eee;\n}\nblockquote {\n    border-left: 5px solid #eee;\n    padding: 10px 20px;\n    margin-top: 20px;\n\n}\ndt {\n    font-weight: 600;\n}\ndd {\n    padding-left: 20px;\n    margin-bottom: 10px;\n}\n<\/style>\n<h2>ExpressPlay Packager Guide<\/h2>\n<div class=\"bg-grey-100 p-8 mb-12\" id=\"rest-api_my-sub-menu\">\n<p>Jump to section<\/p>\n<ol>\n<li><a href=\"#introduction\" class=\"my-hyperlink\">Introduction<\/a><\/li>\n<li><a href=\"#mp4dashtools\" class=\"my-hyperlink\">MP4\/DASH Tools<\/a><\/li>\n<li><a href=\"#summaryoftstools\" class=\"my-hyperlink\">ExpressPlay TS Tools<\/a><\/li>\n<li><a href=\"#bbtscontentids\" class=\"my-hyperlink\"><span>BBTS Content IDs<\/span><\/a><\/li>\n<li><a href=\"#tstoolsindetail\" class=\"my-hyperlink\"><span>TS Tools in Detail<\/span><\/a><\/li>\n<li><a href=\"#producingmarlinabrstreams\" class=\"my-hyperlink\"><span>Producing Marlin-Protected ABR Streams<\/span><\/a><\/li>\n<li><a href=\"#streamingsupport\" class=\"my-hyperlink\"><span>Streaming Support in ExpressPlay SDK<\/span><\/a><\/li>\n<\/ol><\/div>\n<div id=\"\" class=\"\">\n<div id=\"introduction\" class=\"boxslice1 anchorlinks-dev\" style=\"min-height:0;\">\n<h2>Introduction<\/h2>\n<p>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.<\/p>\n<p>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:<\/p>\n<ul>\n<li>Bento4 Tools for DASH\/Smooth\/MP4 (tools and documentation available at<a href=\"http:\/\/bento4.com\" target=\"_blank\" rel=\"noopener noreferrer nofollow\"> www.bento4.com<\/a>), for streaming and downloaded MP4 media<\/li>\n<li>Apple HLS Tools (tools and documentation available at Apple's<a href=\"https:\/\/developer.apple.com\/streaming\/\" target=\"_blank\" rel=\"noopener noreferrer nofollow\"> developer web site<\/a>) for streaming of TS media<\/li>\n<li>ExpressPlay TS Tools (available<a href=\"\/developer\/packaging\"> HERE<\/a>, 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.<\/li>\n<\/ul>\n<p>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:<\/p>\n<ul>\n<li>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.<\/li>\n<li>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).<\/li>\n<li>Modifying file content. For example, mp4edit can be used to insert, remove, or replace atoms (a.k.a. boxes) in an MP4-based file.<\/li>\n<li>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).<\/li>\n<\/ul>\n<p>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.<\/p>\n<p>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.<\/p>\n<h3>Marlin-Protected Content<\/h3>\n<p>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:<\/p>\n<ul>\n<li>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.<\/li>\n<li>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.<\/li>\n<li>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.<\/li>\n<\/ul>\n<p>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).<\/p>\n<\/div>\n<div id=\"mp4dashtools\" class=\"boxslice1 anchorlinks-dev\">\n<h2>MP4\/DASH Tools<\/h2>\n<p>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.<\/p>\n<p>\n<a class=\"btn btn-primary btn-expressplay\" href=\"http:\/\/www.bento4.com\" style=\"margin: 0 !important;display: inline;\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">Bento4 Web Site<\/a><\/p>\n<\/div>\n<div id=\"hlstools\" class=\"boxslice1 anchorlinks-dev\">\n<h2>HLS Tools<\/h2>\n<p>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.<\/p>\n<p>\n<a class=\"btn btn-primary btn-expressplay\" href=\"https:\/\/developer.apple.com\/streaming\/\" style=\"margin: 0 !important;display: inline;\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">Apple HLS Streaming Site<\/a><\/p>\n<\/div>\n<div id=\"summaryoftstools\" class=\"boxslice1 mydivider anchorlinks-dev\">\n<h2>ExpressPlay TS Tools<\/h2>\n<div class=\"no-more-tables\">\n<table cellspacing=\"0\" cellpadding=\"0\" class=\"t1\">\n<tbody>\n<tr>\n<td valign=\"middle\" class=\"td1\">\n<p class=\"p1 bold\">Ts2AdaptiveAwareEncrypt<\/p>\n<\/td>\n<td valign=\"middle\" class=\"td2\">\n<p class=\"p1\">Encrypts and packages an MPEG-2 TS file into a Marlin BBTS file, just like Ts2Encrypt, except that this also takes a \u201crotation point file\u201d as input that is used to dictate where the Entitlement Control Messages (ECMs) are to be inserted.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\" class=\"td1\">\n<p class=\"p1 bold\">Ts2Decrypt<\/p>\n<\/td>\n<td valign=\"middle\" class=\"td2\">\n<p class=\"p1\">Decrypts a Marlin BBTS file, producing essentially the same MPEG-2 TS file originally encrypted to create the BBTS file.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\" class=\"td1\">\n<p class=\"p1 bold\">Ts2Encrypt<\/p>\n<\/td>\n<td valign=\"middle\" class=\"td2\">\n<p class=\"p1\">Encrypts and packages an MPEG-2 TS file into a Marlin BBTS file.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\" class=\"td1\">\n<p class=\"p1 bold\">Ts2FileEncrypterStitcher<\/p>\n<\/td>\n<td valign=\"middle\" class=\"td2\">\n<p class=\"p1\">Creates a single encrypted file out of one or more cleartext TS2 files.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\" class=\"td1\">\n<p class=\"p1 bold\">Ts2Info<\/p>\n<\/td>\n<td valign=\"middle\" class=\"td2\">\n<p class=\"p1\">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.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\" class=\"td1\">\n<p class=\"p1 bold\">Ts2UdpProcessor<span class=\"Apple-converted-space\">&nbsp;<\/span><\/p>\n<\/td>\n<td valign=\"middle\" class=\"td2\">\n<p class=\"p1\">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.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"middle\" class=\"td1\">\n<p class=\"p1 bold\">Ts2UdpProcessorCommand<span class=\"Apple-converted-space\">&nbsp;<\/span><\/p>\n<\/td>\n<td valign=\"middle\" class=\"td2\">\n<p class=\"p1\">Provides the ability for Ts2UdpProcessor to rotate keys while running. The Ts2UdpProcessorCommand tool sends commands to Ts2UdpProcessor while running.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<div id=\"bbtscontentids\" class=\"boxslice1 mydivider anchorlinks-dev\">\n<h2>BBTS Content IDs<\/h2>\n<p>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.<\/p>\n<p>The syntax for a content ID for a program is the following:<\/p>\n<p><span class=\"courier\">CID=\"cid:\"||socID||\"#P\"||serviceBaseCID||\"@\"||hex(program_CID_extension)<\/span><\/p>\n<p>and the syntax for a content ID for a service is the following:<\/p>\n<p><span class=\"courier\">CID=\"cid:\"||socID||\"#S\"||serviceBaseCID||\"@\"||hex(service_CID_extension)<\/span><\/p>\n<p>where<\/p>\n<ul>\n<li>|| represents concatenation.<\/li>\n<li>socID equals \u201cmarlin\u201d or is retrieved via an unspecified out-of-band mechanism.<\/li>\n<li>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:<\/li>\n<p><span class=\"courier\">serviceBaseCID=organization||\"-\"||service<\/span><\/p>\n<p>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.<\/p>\n<li>program_CID_extension identifies a specific content item within the program.<\/li>\n<li>service_CID_extension identifies a specific content item within the service.<\/li>\n<li>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.<\/li>\n<\/ul>\n<p>Here is an example of a content ID for a program:<\/p>\n<p><span class=\"courier\">cid:marlin#Pvod:channel@0142cafd<\/span><\/p>\n<p>Here is one for a service:<\/p>\n<p><span class=\"courier\">cid:marlin#Suniversal@21cafe34<\/span><\/p>\n<\/div>\n<div id=\"tstoolsindetail\" class=\"boxslice1 mydivider anchorlinks-dev\">\n<h2>TS Tools in Detail<\/h2>\n<p>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.<\/p>\n<p>How to interpret the usage statements:<\/p>\n<ul>\n<li>Items in angle brackets represent placeholders for actual values. For example, one of the options may be shown as<\/li>\n<p><span class=\"courier\">&#45;&#45;verbosity &lt;n&gt;<\/span><\/p>\n<p>Here, &lt;n&gt; is a placeholder for a number between 0 and 3, so the option specified in an actual call would look something like the following:<\/p>\n<p><span class=\"courier\">&#45;&#45;verbosity 2<\/span><\/p>\n<li>Items in square brackets are optional.<\/li>\n<li>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.<\/li>\n<li>You can see the usage statement for each of the mp4* and Ts2* tools by calling the tool with no parameters.<\/li>\n<li>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 \u201cline\u201d in order to make an actual call with the specified parameters.<\/li>\n<\/ul>\n<h3>Ts2AdaptiveAwareEncrypt<\/h3>\n<h4>Description<\/h4>\n<p>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 \u201crotation point file\u201d as input that is used to dictate where (in the Transport Stream Packets) the Entitlement Control Messages (ECMs) are to be inserted.<\/p>\n<p>The format of the rotation file is the following:<\/p>\n<ul>\n<li>File ::= RotationPoints<\/li>\n<li>RotationPoints ::= [SwitchPoints] RotationPoint<\/li>\n<li>RotationPoint ::= PacketNum NewLine<\/li>\n<li>PacketNum ::= Decimal Integer<\/li>\n<\/ul>\n<p>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:<\/p>\n<div><code>7<br \/>\n2137<br \/>\n4666<br \/>\n6836<br \/>\n9172<br \/>\n11500<br \/>\n13868<br \/>\n16037<br \/>\n18358<br \/>\n20688<br \/>\n22994<br \/>\n25529<br \/>\n27520<br \/>\n30107<br \/>\n32211<br \/>\n34683<\/code><\/div>\n<p><\/p>\n<h4>Usage<\/h4>\n<p><span class=\"courier\">Ts2AdaptiveAwareEncrypt [options] &lt;input&gt; &lt;output&gt;<\/span><\/p>\n<h4>Parameters<\/h4>\n<p><span class=\"courier\">[options]:<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;protection {bbts-1.1|bbts-2.0}<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;key &lt;cid&gt;::&lt;k&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">MANDATORY: &lt;cid&gt; is a BBTS-formatted content ID (see \u00a73), and &lt;k&gt; is a 128-bit key in hex.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;traffic-seed &lt;s&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">MANDATORY: traffic seed in hex.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;ksm-pid &lt;pid&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">MANDATORY: PID of the KSM (ECM).<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;traffic-key-lifetime &lt;secs&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">MANDATORY: traffic key lifetime in seconds. Valid values range between 4 and 120.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;rotation-in &lt;path&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">MANDATORY: filepath to input rotation point file.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;rotation-out &lt;path&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">MANDATORY: filepath to output rotation point file.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;first-segment-index &lt;index&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Specifies the first segment index. Default is 0.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;rights-issuer &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for rights issuer.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;silent-rights &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for silent rights acquisition.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;preview-rights &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for preview rights acquisition.\n<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;iv &lt;iv&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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).<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;access-criteria &lt;tag&gt;:&lt;value&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">This option can be repeated to add more than one access criteria. The tag and value are specified in hex.<\/p>\n<p><span class=\"courier\">&lt;input&gt;<\/span> \u2013 The MPEG-2 TS file to be encrypted.<\/p>\n<p><span class=\"courier\"><output><\/output><\/span> \u2013 The resulting BBTS file.<\/p>\n<h4>Example<\/h4>\n<p>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.<\/p>\n<p><b>Ts2AdaptiveAwareEncrypt<\/b><\/p>\n<p><b><\/p>\n<p>\u2013-protection bbts-2.0<\/p>\n<p>&#45;&#45;key cid:marlin#Suniversal@deadbeef::4bd3eb6bd171595764ec2050a20382e1<\/p>\n<p>&#45;&#45;traffic-seed 934b4bd3eb6bd171595764ec2050a20382e1<\/p>\n<p>&#45;&#45;traffic-key-lifetime 4<\/p>\n<p>&#45;&#45;ksm-pid 142<\/p>\n<p>&#45;&#45;rotation-in 796000_rotation_points.txt<\/p>\n<p><\/b><\/p>\n<p><b>&#45;&#45;rotation-out 796000_rotation_points_bbts.txt 796000.ts 796000.bbts<\/b><\/p>\n<h3>Ts2Decrypt<\/h3>\n<h4>Description<\/h4>\n<p>Decrypts a Marlin BBTS file, producing essentially the same MPEG-2 TS file originally encrypted to create the BBTS file.<\/p>\n<h4>Usage<\/h4>\n<p><span class=\"courier\">Ts2Decrypt [options] &lt;input&gt; &lt;output&gt;<\/span><\/p>\n<h4>Parameters<\/h4>\n<p><span class=\"courier\">[options]:<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;key &lt;cid&gt;::&lt;k&gt;<\/span> \u2013 In this, &lt;cid&gt; is a content ID (see \u00a73) and &lt;k&gt; is a 128-bit key in hex.<\/p>\n<p><span class=\"courier\">&lt;input&gt;<\/span> \u2013 The BBTS file to decrypt.<\/p>\n<p><span class=\"courier\">&lt;output&gt;<\/span> \u2013 The resulting MPEG-2 TS file.<\/p>\n<h4>Example<\/h4>\n<p>The following call results in the decryption of the content in <i>bigbucksbunny.bbts<\/i>, and the creation of an MPEG-2 TS file <i>bigbucksbunny.ts<\/i> containing the decrypted content, assuming that the specified content ID and key are correct.<\/p>\n<p><b>Ts2Decrypt &#45;&#45;key cid:marlin#Suniversal@deadbeef::4bd3eb6bd171595764e<br \/>\nc2050a20382e1 bigbucksbunny.bbts bigbucksbunny.ts<\/b><\/p>\n<h3>Ts2Encrypt<\/h3>\n<h4>Description<\/h4>\n<p>Encrypts and packages an MPEG-2 TS file into a Marlin BBTS file.<\/p>\n<h4>Usage<\/h4>\n<p><span class=\"courier\">Ts2Encrypt [options] &lt;input&gt; &lt;output&gt;<\/span><\/p>\n<h4>Parameters<\/h4>\n<p><span class=\"courier\">[options]:<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;key &lt;cid&gt;::&lt;k&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">MANDATORY: &lt;cid&gt; is a BBTS-formatted content ID (see \u00a73), and &lt;k&gt; is a 128-bit key in hex.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;protection {bbts-1.1|bbts-2.0}<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;zero-iv<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">If specified, a fixed all 0's IV will be used for content encryption. Overrides any preceeding &#45;&#45;varying-iv options.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;crypto-period &lt;n&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">The crypto period (as defined in the BBTS specification), in seconds, between 1 and 120 (default: 2).<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;varying-iv<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;rights-issuer &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for rights issuer.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;silent-rights &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for silent rights acquisition.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;preview-rights &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for preview rights acquisition.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;skip-payload-unit-start<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">If this is specified, any packet indicating the start of a new PES (Packetized Elementary Stream) will not be encrypted.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;single-key-layer<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">If this is specified, the encryption will be done using the BBTS single-key-layer mode.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;access-criteria &lt;tag&gt;:&lt;value&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">This option can be repeated to add more than one access criteria. The tag and value are specified in hex.<\/p>\n<p><span class=\"courier\">&lt;input&gt;<\/span> \u2013 The MPEG-2 TS file to be encrypted.<\/p>\n<p><span class=\"courier\">&lt;output&gt;<\/span> \u2013 The resulting BBTS file.<\/p>\n<h4>Example<\/h4>\n<p>The following encrypts the MPEG-2 TS file <i>bigbucksbunny-trailer.ts<\/i> using the specified key and content ID, creating the BBTS file <i>bigbucksbunny-trailer.bbts<\/i>.<\/p>\n<p><b>Ts2Encrypt &#45;&#45;protection bbts-2.0 &#45;&#45;key cid:marlin#Suniversal@deadbeef::000102030405060708090a0b0c0d0e0f bigbucksbunny-trailer.ts bigbucksbunny-trailer.bbts<\/b><\/p>\n<h3>Ts2FileEncrypterStitcher<\/h3>\n<h4>Description<\/h4>\n<p>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.<\/p>\n<h4>Usage<\/h4>\n<p><span class=\"courier\">Ts2FileEncrypterStitcher [options] &lt;output&gt;<\/span><\/p>\n<h4>Parameters<\/h4>\n<p><span class=\"courier\">[options]:<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;media &lt;path&gt;::&lt;cid&gt;::&lt;k&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">MANDATORY: &lt;path&gt; is the path to an MPEG-2 TS cleartext file, &lt;cid&gt; is a BBTS-formatted content ID (see \u00a73), and &lt;k&gt; is a 128-bit key in hex. One or more &#45;&#45;media options may appear, each specifying a particular input file, content ID, and key.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;protection {bbts-1.1|bbts-2.0}<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;zero-iv<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">If specified, a fixed all 0's IV will be used for content encryption. Overrides any preceeding &#45;&#45;varying-iv options.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;crypto-period &lt;n&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">The crypto period (as defined in the BBTS specification), in seconds, between 1 and 120 (default: 2).<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;varying-iv<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;rights-issuer &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for rights issuer.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;silent-rights &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for silent rights acquisition.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;preview-rights &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for preview rights acquisition.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;skip-payload-unit-start<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">If this is specified, any packet indicating the start of a new PES (Packetized Elementary Stream) will not be encrypted.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;access-criteria &lt;tag&gt;:&lt;value&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">This option can be repeated to add more than one access criteria. The tag and value are specified in hex.<\/p>\n<p><span class=\"courier\">&lt;output&gt;<\/span> \u2013 The resulting BBTS file.<\/p>\n<h4>Example<\/h4>\n<p>The following creates bigbucks-stitched.bbts, which is the result of combining in one file the encryptions of the specified input files (<i>bigbucks0.ts<\/i>, <i>bigbucks1.ts<\/i>, and <i>bigbucks2.ts<\/i>). Each input is encrypted using the specified key and is assigned the specified content ID.<\/p>\n<p><b>Ts2FileEncrypterStitcher &#45;&#45;protection bbts-2.0 &#45;&#45;media bigbucks0.ts::cid:marlin#Pvod:channel@0142cafd::ab98cd76ef541237080cfabe98421770 &#45;&#45;media bigbucks1.ts::cid:marlin#Pvod:channel@0142cafe::ab98cd76ef541237080cfabe98421771 &#45;&#45;media bigbucks2.ts::cid:marlin#Pvod:channel@0142caff::ab98cd76ef541237080cfabe98421772 bigbucks-stitched.bbts<\/b><\/p>\n<h3>Ts2Info<\/h3>\n<h4>Description<\/h4>\n<p>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.<\/p>\n<h4>Usage<\/h4>\n<h4>\n<p><span class=\"courier\">Ts2Info [options] &lt;input&gt;<\/span><\/p>\n<\/h4>\n<h4>Parameters<\/h4>\n<p><span class=\"courier\">[options]:<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;max-packet-count &lt;n&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Specifies the maximum number of packets screened. If &lt;n&gt; is -1, the number is unbounded. The default maximum number is 100.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;max-cat-packet-count-from-ksm &lt;n&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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).<\/p>\n<p><span class=\"courier\">&lt;input&gt;<\/span> \u2013  The BBTS file whose information will be returned.<\/p>\n<h4>Example<\/h4>\n<p><b>Ts2Info bloomberg_h264_sd_ac3-120sec.bbts<\/b><\/p>\n<div><code>Marlin Protected file:<br \/>\nTraffic Protection System: BBTS 2.0, TRUNCATED SHA1 KDF<br \/>\nMarlin content id is cid:marlin#Suniversal@deadbeef<\/p>\n<p>es pid:  68<br \/>\nes type: 1B<\/p>\n<p>es pid:  69<br \/>\nes type: 81<\/code><\/div>\n<h3>Ts2UdpProcessor<\/h3>\n<h4>Description<\/h4>\n<p>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.<\/p>\n<p>Ts2UdpProcessor illustrates usage of <b>TS2_BbtsBufferEncrypter, TS2_BbtsBufferDecrypter, and ATX_DataBuffer.<\/b><\/p>\n<h4>Usage<\/h4>\n<p><span class=\"courier\">Ts2UdpProcessor [options] &lt;input port&gt; &lt;output hostname&gt; &lt;output port&gt;<\/span><\/p>\n<h4>Parameters<\/h4>\n<p><span class=\"courier\">[options]:<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;protection {bbts-1.1|bbts-2.0}<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;type &lt;enc or dec&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Specifies whether the input stream should be encrypted (enc) or decrypted (dec). The default is enc.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;key &lt;cid&gt;::&lt;k&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">MANDATORY: &lt;cid&gt; is a BBTS-formatted content ID, and &lt;k&gt; is a 128-bit key in hex.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;crypto-period &lt;n&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;varying-iv<\/span><\/p>\n<p>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 &#45;&#45;zero-iv.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;zero-iv<span><\/span><\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">If specified, a fixed all 0's IV will be used for content encryption. Overrides any preceeding &#45;&#45;varying-iv options. This parameter is only relevant when the type value is enc.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;rights-issuer &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for rights issuer. This parameter is only relevant when the type value is enc.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;silent-rights &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for silent rights acquisition. This parameter is only relevant when the type value is enc.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;preview-rights &lt;url&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URI template for preview rights acquisition. This parameter is only relevant when the type value is enc.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;skip-payload-unit-start<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;multicast-join &lt;group&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Join the multicast group &lt;group&gt;.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;multicast-ttl &lt;ttl&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Set the Time To Live value for outgoing multicast packets (when sending to a multicast address).<\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Setting \"&#45;&#45;multicast-ttl 1\" would appropriate for a LAN.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Higher numbers are useful when reaching computers\/devices further away on a network that includes routers. Setting \"&#45;&#45;multicast-ttl 5\" might be a reasonable choice on corporate network, allowing 5 hops crossing different subnets.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;show-progress<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Print a running count of packets processed while the loop is running.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;payload-header-size<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Ignore the first &lt;n&gt; 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 &#45;&#45;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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;access-criteria &lt;tag&gt;:&lt;value&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">This option can be repeated to add more than one access criteria. The tag and value are specified in hex.<\/p>\n<p><span class=\"courier\">&lt;input port&gt;<\/span> \u2013 The input port.<\/p>\n<p><span class=\"courier\">&lt;output hostname&gt;<\/span> \u2013 The output hostname.<\/p>\n<p><span class=\"courier\">&lt;output port&gt;<\/span> \u2013 The output port.<\/p>\n<h4>Examples<\/h4>\n<p>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:<\/p>\n<p><b>Ts2UdpProcessor<\/b><\/p>\n<div><code>-\u2013protection bbts-2.0<br \/>\n&#45;&#45;type enc<br \/>\n&#45;&#45;key cid:marlin#Pvod:channel@0142cafe::d8<br \/>\nb329977ca4132dac79821dbaca8214 8888 localhost 9999<\/code><\/div>\n<p>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:<\/p>\n<p><b>Ts2UdpProcessor<\/b><\/p>\n<div><code>-\u2013protection bbts-2.0<br \/>\n&#45;&#45;type dec<br \/>\n&#45;&#45;key cid:marlin#Pvod:channel@0142caff::1247563dcf9ca873baffc245978cba77 8888 localhost 9999<\/code><\/div>\n<p>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<\/p>\n<p><b>Ts2UdpProcessor<\/b><\/p>\n<div><code>-\u2013protection bbts-2.0<br \/>\n&#45;&#45;type enc<br \/>\n&#45;&#45;payload-header-size 12<br \/>\n&#45;&#45;multicast-ttl 5<br \/>\n&#45;&#45;key cid:marlin#Pvod:channel@0142cafe::d8b329977ca4132dac79821dbaca8214 8000 239.255.255.252 8001<\/code><\/div>\n<p>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<\/p>\n<p><b>Ts2UdpProcessor<\/b><\/p>\n<div><code>-\u2013protection bbts-2.0<br \/>\n&#45;&#45;type dec<br \/>\n&#45;&#45;payload-header-size 12<br \/>\n&#45;&#45;multicast-join 239.255.255.252<br \/>\n&#45;&#45;key cid:marlin#Pvod:channel@0142cafe::d8b329977ca4132dac79821dbaca8214 8001 localhost 8002<\/code><\/div>\n<h3>Ts2UdpProcessorCommand<\/h3>\n<h4>Description<\/h4>\n<p>Provides the ability for Ts2UdpProcessor to rotate keys while running. The Ts2UdpProcessorCommand tool sends commands to Ts2UdpProcessor while running.<\/p>\n<h4>Usage<\/h4>\n<p><span class=\"courier\">Ts2UdpProcessorCommand &lt;cmd&gt; &lt;hostname&gt; &lt;port&gt; [params]<\/span><\/p>\n<h4>Parameters<\/h4>\n<p><span class=\"courier\">&lt;cmd&gt;<\/span> \u2013 Currently only the following command is defined: set-key<\/p>\n<p><span class=\"courier\">&lt;hostname&gt;<\/span> \u2013 The hostname or IP address of the UDP listener.<\/p>\n<p><span class=\"courier\">&lt;port&gt;<\/span> \u2013 The UDP port on which to send the command to the listener Command Parameters.<\/p>\n<h4>Example<\/h4>\n<p><b>Parameters and Example<\/b><\/p>\n<div><code>set-key: &lt;cid-ext&gt; &lt;key&gt;<br \/>\n&lt;cid-ext&gt; = 32-bit CID extension in hex<br \/>\n&lt;k&gt; = 128-bit key in hex<\/code><\/div>\n<div><code>Example: Ts2UdpProcessorCommand.exe set-key localhost 8888 0142babe 00010203040506070001020304050607<br \/>\nwhere 8888 is input port, <cid-ext> = 0142babe and <k> = 00010203040506070001020304050607<\/k><\/cid-ext><\/code><\/div>\n<\/div>\n<div id=\"producingmarlinabrstreams\" class=\"boxslice1 mydivider anchorlinks-dev\">\n<h2>Producing Marlin-Protected ABR Streams<\/h2>\n<p>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..<\/p>\n<p>The HLS specification is available as a draft IETF RFC available at <a target=\"_blank\" href=\"http:\/\/tools.ietf.org\/html\/draft-pantos-http-live-streaming-07\" rel=\"noopener noreferrer nofollow\">http:\/\/tools.ietf.org\/html\/draft-pantos-http-live-streaming-07<\/a><\/p>\n<p>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\u2019s a playlist.<\/p>\n<p>MPEG DASH is MPEG\u2019s standardized Dynamic Adaptive Streaming over HTTP. It is specified in the following international standards:<\/p>\n<ul>\n<li>ISO\/IEC 23009-1 specifies the overall DASH architecture and the XML syntax for the MPD (Media Presentation Description).<\/li>\n<li>ISO\/IEC 23001-7 specifies the Common Encryption scheme for MP4 fragments.<\/li>\n<li>ISO\/IEC 14496-12\/AMD 3 specifies the extensions to 14496-12 that are necessary to support DASH with fragmented MP4 media.<\/li>\n<\/ul>\n<p>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.<\/p>\n<h3>Content Prerequisites<\/h3>\n<p>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.<\/p>\n<p>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\u2019t 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.<\/p>\n<p>The following audio and video options are supported by the ExpressPlay SDK:<\/p>\n<ul>\n<li>Audio<\/li>\n<ul>\n<li>AAC-encoded ADTS packets<\/li>\n<li>2 channels<\/li>\n<\/ul>\n<li>Video<\/li>\n<ul>\n<li>H.264-encoded video in an MPEG-4 container<\/li>\n<li>H.264-encoded video in an MPEG-2 container<\/li>\n<li>PAR (Pixel Aspect Ratio) must be 1:1<\/li>\n<\/ul>\n<\/ul>\n<h3>Converting MP4 to MPEG-2 TS<\/h3>\n<p>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.<\/p>\n<p>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:<\/p>\n<p><span class=\"courier\">mp42ts.exe &#45;&#45;segment 5 elephantsdream_source.mp4 ele.%d.ts<\/span><\/p>\n<h3>Packaging HLS Content<\/h3>\n<h4>Prerequisites<\/h4>\n<ol>\n<li>Python2.7<\/li>\n<li>Clear MP4 Content (for example: $WasabiClientTestContentSampleAlwaysPlaySourceelephantsdream_source.mp4)<\/li>\n<li>Scripts:<\/li>\n<ul>\n<li>$WasabiServerToolsPackagingHttpLiveStreamingcreate-hls-playlist.py<\/li>\n<li>$WasabiServerToolsPackagingHttpLiveStreamingpackage-hls-files.py<\/li>\n<\/ul>\n<li>Binaries:<\/li>\n<ul>\n<li>mp42ts (bento4 tool)<\/li>\n<li>Ts2AdaptiveAwareEncrypt<\/li>\n<\/ul>\n<\/ol>\n<h4>Creating HLS Playlist<\/h4>\n<p>Use the <i>create-hls-playlist.py<\/i> script to create m3u8 HLS playlists out of a directory structure of files. The directory structure expected is:<\/p>\n<div><code>MainDirectory<br \/>\n  SubDirectory1<br \/>\n    File1<br \/>\n    File2<br \/>\n    . . .<br \/>\n  SubDirectory2<br \/>\n    File1<br \/>\n    File2<br \/>\n    . . .<br \/>\n  . . .<\/code><\/div>\n<p>The naming conventions and requirements are the following:<\/p>\n<ul>\n<li><b>MainDirectory<\/b>. There are no restrictions on the main directory name or location. A master playlist file named <i>MainDirectory.m3u8<\/i> will be created within the MainDirectory.<\/li>\n<li><b>SubDirectoryN<\/b>. Each of the subdirectories must contain the same number of files as the other subdirectories, and each must obey the following naming convention:<\/li>\n<p><span class=\"courier\">&lt;char(s)&gt;-&lt;at least one lowercase letter&gt;&lt;bitrate&gt;<\/span><\/p>\n<p>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.<\/p>\n<p>Here is an example subdirectory name:<\/p>\n<p><span class=\"courier\">elephantsdream-hq1234<\/span><\/p>\n<p>Where 1234 indicates the bitrate (in kbps) of the files in the directory.<\/p>\n<li><b>FileN<\/b>. Each file in a subdirectory must obey the following naming convention:<\/li>\n<p><span class=\"courier\">&lt;name&gt;.&lt;mediasequence&gt;.ts<\/span><\/p>\n<p>where <name> represents whatever file name you want to use, and &lt;mediasequence&gt; is the index to be used for the file in the playlist.<\/name><\/p>\n<p>Create a directory structure accepted by the script:<\/p>\n<div><code>.\/ElephantsDream:<br \/>\nelephantsdream-q7777       elephantsdream-q888<\/p>\n<p>.\/ElephantsDream\/elephantsdream-q7777:<br \/>\nele.0.ts ele.1.ts ele.2.ts ele.3.ts ele.4.ts ele.5.ts<\/p>\n<p>.\/ElephantsDream\/elephantsdream-q888:<br \/>\nele.0.ts ele.1.ts ele.2.ts ele.3.ts ele.4.ts ele.5.ts<\/code><\/div>\n<p>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).<\/p>\n<h4>Usage<\/h4>\n<p>Here is the script usage:<\/p>\n<p><span class=\"courier\">create-hls-playlist.py &lt;targetduration&gt; &lt;directory&gt;<\/span><\/p>\n<p>Where &lt;targetduration&gt; represent the maximum media file duration (in seconds). Each file in the playlist must be no longer than &lt;targetduration&gt; seconds.<\/p>\n<p><span class=\"courier\">python create-hls-playlist.py 5 ElephantsDream<\/span><\/p>\n<p>The script creates a master playlist (ElephantsDream.m3u8) in the main directory as well as sub playlists (index.m3u8) in each sub directory.<\/p>\n<h4>Package HLS<\/h4>\n<p>Create bin\/&lt;<i>platform<\/i>&gt; 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.<\/p>\n<h4>Usage<\/h4>\n<p><span class=\"courier\">package-hls-files.py [options] &lt;contentid&gt; &lt;m3u8file&gt;<\/span><\/p>\n<h4>Parameters<\/h4>\n<p><span class=\"courier\">[options]:<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-k KEY, &#45;&#45;key=KEY<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">If specified, this must be 32 hex chars (representing 16 bytes). If not specified, it is automatically generated.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-t TRAFFIC_KEY_SEED, &#45;&#45;traffic-key-seed=TRAFFIC_KEY_SEED<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">If specified, this must be 32 hex chars (representing 16 bytes). If not specified, it is automatically generated.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-i TRAFFIC_IV, &#45;&#45;traffic-iv=TRAFFIC_IV<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">If specified, this must be 32 hex chars (representing 16 bytes). If not specified, it is automatically generated.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-e ECM_PID, &#45;&#45;ecm-pid=ECM_PID<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">pid for the generated ecm [default: 142]<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-v {bbts-1.1|bbts-2.0}, &#45;&#45;protection {bbts-1.1|bbts-2.0}<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-o OUTPUT_DIR, &#45;&#45;output-dir=OUTPUT_DIR<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Output directory for the protected files [default: .\/ProtectedHls]<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-r RIGHTS_ISSUER_URL, &#45;&#45;rights-issuer-url=RIGHTS_ISSUER_URL<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URL of the rights issuer.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-s SILENT_RIGHTS_URL, &#45;&#45;silent-rights-url=SILENT_RIGHTS_URL<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URL of the silent rights.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-p PREVIEW_RIGHTS_URL, &#45;&#45;preview-rights-url=PREVIEW_RIGHTS_URL<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">URL of the preview rights.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-h, &#45;&#45;help<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Show this help message and exit.<\/p>\n<h4>Example<\/h4>\n<p>Package HLS using the default values for keys, traffic key seeds, etc:<\/p>\n<p><span class=\"courier\">python package-hls-files.py &#45;&#45;protection bbts-2.0 cid:marlin#Pvod:channel@0142babe ElephantsDreamElephantsDream.m3u8<\/span><\/p>\n<p>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.<\/p>\n<h3>Packaging DASH Content<\/h3>\n<h4>Prerequisites<\/h4>\n<ol>\n<li>Python 2.7<\/li>\n<li>Clear MP4 Content<\/li>\n<ul>\n<li>(for example: <span class=\"courier\">$WasabiClientTestContentSampleAlwaysPlaySourceelephantsdream_source.mp4<\/span>)<\/li>\n<\/ul>\n<li>Scripts: (from Bento4 Trunk)<\/li>\n<ul>\n<li><span class=\"courier\">$Bento4SourcePythonutilsmp4-dash.py<\/span><\/li>\n<\/ul>\n<li>Binaries: (bento4 tools)<\/li>\n<ul>\n<li><span class=\"courier\">Mp4Fragment<\/span><\/li>\n<li><span class=\"courier\">mp4encrypt<\/span><\/li>\n<li><span class=\"courier\">mp4split<\/span><\/li>\n<li><span class=\"courier\">mp4dump<\/span><\/li>\n<li><span class=\"courier\">mp4info<\/span><\/li>\n<\/ul>\n<\/ol>\n<h4>Fragment the content<\/h4>\n<p>Use the following command to fragment the mp4 content if you have not fragmented already.<\/p>\n<p><span class=\"courier\">Mp4Fragment.exe elephantsdream_source.mp4 ele.mp4<\/span><\/p>\n<p>The <b>Mp4Fragment<\/b> command takes a single MP4 file as input and produces a single MP4 file as output with same content but it is fragmented.<\/p>\n<h4>Package the content<\/h4>\n<p>Encrypt the fragmented files using mp4encrypt in an MPEG DASH CENC (Common Encryption) mode:<\/p>\n<div><code>mp4encrypt<br \/>\n   &#45;&#45;method MPEG-CENC<br \/>\n   &#45;&#45;key 1:a0a1a2a3a4a5a6a7a8a9aaabacadaeaf:0123456789abcdef<br \/>\n   &#45;&#45;property 1:KID:121a0fca0f1b475b8910297fa8e0a07e<br \/>\n   &#45;&#45;key 2:a0a1a2a3a4a5a6a7a8a9aaabacadaeaf:aaaaaaaabbbbbbbb<br \/>\n   &#45;&#45;property 2:KID:121a0fca0f1b475b8910297fa8e0a07e ele.mp4 ele-cenc.mp4<\/code><\/div>\n<p>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:<\/p>\n<p style=\"text-indent: 3em\" ;=\"\">-  urn:marlin:kid:<kid-in-hex>, where KID-in-hex is the lowercase hexadecimal representation of the 16 bytes of KID<\/kid-in-hex><\/p>\n<p>Example content ID:<\/p>\n<p style=\"text-indent: 3em\" ;=\"\">-  urn:marlin:kid:1586f237d6a6aadd992e4948297e4567<\/p>\n<h4>Create DASH content<\/h4>\n<p>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.<\/p>\n<p>The <i>mp4-dash.py<\/i> script invokes the mp4info (\u00a74.13), mp4dump (\u00a74.8), mp4encrypt (\u00a74.10), and mp4split (\u00a74.14) tools. As with the other tools in the tools package, the binaries for these tools are included for the different platforms in the <i>bin\/&lt;platform&gt;<\/i> 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 <i>mp4-dash.py<\/i> &#45;&#45;exec-dir option.<\/p>\n<h4>Usage<\/h4>\n<p><span class=\"courier\">python mp4-dash.py [options] &lt;filename&gt; [&lt;filename&gt; ...]<\/span><\/p>\n<h4>Parameters<\/h4>\n<p><span class=\"courier\">[options]:<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-h or &#45;&#45;help<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Shows the usage format and these options, then exits.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-v or &#45;&#45;verbose<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Verbose.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-f or &#45;&#45;force<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\"> Allow output to an existing directory.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-d or &#45;&#45;debug<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\"> Print out debugging information.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-o &lt;output-dir&gt; or -\u2013output-dir=&lt;output-dir&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Output directory. Default behavior is to create an output directory named output within the current directory.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;init-segment=&lt;filename&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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 <i>init.mp4<\/i>.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">-m &lt;filename&gt; or \u2013-mpd-name=&lt;filename&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Name for the manifest file (MPD) that is output. This file will be the primary input to a media player for playing the content.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">\u2013-mpd-only<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Generate only the MPD file. That is, do not perform any media processing; do not generate media segments.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\">If this option is not specified, and neither is the &#45;&#45;no-split option, the script not only generates the MPD but also splits the media into video and audio segments for each bitrate.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">\u2013-no-split<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">\u2013-use-segment-list<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;min-buffer-time=&lt;duration&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Minimum buffer time, in seconds. Default is 0.0.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;video-frame-rate=&lt;rate&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Video frame rate, in frames per second. Default is 23.976.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;video-codec=&lt;codec&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Video codec string.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;audio-sample-rate=&lt;rate&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Audio sample rate, in samples per second. Default is 44100.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">&#45;&#45;audio-codec=&lt;codec&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Audio codec string.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">\u2013-marlin<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">Adds Marlin signaling to the MPD file, indicating that the content is Marlin-protected, not generic clear content.<\/p>\n<p style=\"text-indent: 3em\" ;=\"\"><span class=\"courier\">\u2013-exec-dir=&lt;exec_dir&gt;<\/span><\/p>\n<p style=\"text-indent: 3em\" ;=\"\">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.<\/p>\n<p><span class=\"courier\">&lt;filename&gt;<\/span> \u2013 One or more input file names.<\/p>\n<h4>Example for Single-bitrate Streaming Content<\/h4>\n<p>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.<\/p>\n<p><span class=\"courier\">$ python mp4-dash.py &#45;&#45;marlin ele-cenc.mp4<\/span><\/p>\n<p>Here is the output directory structure and contents:<\/p>\n<div><code>output<br \/>\n  stream.mpd<br \/>\n  audio<br \/>\n    init.mp4<br \/>\n    seg-0000.m4f<br \/>\n    seg-0001.m4f<br \/>\n    ...<br \/>\n  video<br \/>\n    init.mp4<br \/>\n    seg-0000.m4f<br \/>\n    seg-0001.m4f<br \/>\n    ...<\/code><\/div>\n<h4>Example for Multi-bitrate Streaming Content<\/h4>\n<p>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.<\/p>\n<p><span class=\"courier\">python mp4-dash.py &#45;&#45;marlin ele-cenc-1.mp4 ele-cenc-2.mp4 ele-cenc-3.mp4<\/span><\/p>\n<p>Here is the output directory structure and contents:<\/p>\n<div><code>output<br \/>\n  stream.mpd<br \/>\n  audio<br \/>\n    init.mp4<br \/>\n    seg-0000.m4f<br \/>\n    seg-0001.m4f<br \/>\n    ...<br \/>\n  video<br \/>\n    1<br \/>\n      init.mp4<br \/>\n      seg-0000.m4f<br \/>\n      seg-0001.m4f<br \/>\n      ...<br \/>\n    2<br \/>\n      init.mp4<br \/>\n      seg-0000.m4f<br \/>\n      seg-0001.m4f<br \/>\n      ...<br \/>\n    3<br \/>\n      init.mp4<br \/>\n      seg-0000.m4f<br \/>\n      seg-0001.m4f<br \/>\n      ...<\/code><\/div>\n<\/ul>\n<\/div>\n<div id=\"streamingsupport\" class=\"boxslice1 mydivider anchorlinks-dev\">\n<h2>Streaming Support in the ExpressPlay SDK<\/h2>\n<p>For a list of media formats supported by the ExpressPlay SDK, please see the <a href=\"\/developer\/sdk-key-concepts\">SDK Key Concepts page.<\/a><\/p>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>ExpressPlay Packager Guide Jump to section Introduction MP4\/DASH Tools ExpressPlay TS Tools BBTS Content IDs TS Tools in Detail Producing Marlin-Protected ABR Streams Streaming Support in ExpressPlay SDK 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 [&hellip;]<\/p>\n","protected":false},"author":124,"featured_media":0,"parent":10924,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-expressplay-developer.php","meta":{"_acf_changed":false,"footnotes":""},"tax_page_type":[512],"coauthors":[621],"class_list":["post-11040","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.expressplay.com\/ko\/wp-json\/wp\/v2\/pages\/11040","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.expressplay.com\/ko\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.expressplay.com\/ko\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.expressplay.com\/ko\/wp-json\/wp\/v2\/users\/124"}],"replies":[{"embeddable":true,"href":"https:\/\/www.expressplay.com\/ko\/wp-json\/wp\/v2\/comments?post=11040"}],"version-history":[{"count":0,"href":"https:\/\/www.expressplay.com\/ko\/wp-json\/wp\/v2\/pages\/11040\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.expressplay.com\/ko\/wp-json\/wp\/v2\/pages\/10924"}],"wp:attachment":[{"href":"https:\/\/www.expressplay.com\/ko\/wp-json\/wp\/v2\/media?parent=11040"}],"wp:term":[{"taxonomy":"tax_page_type","embeddable":true,"href":"https:\/\/www.expressplay.com\/ko\/wp-json\/wp\/v2\/tax_page_type?post=11040"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.expressplay.com\/ko\/wp-json\/wp\/v2\/coauthors?post=11040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}