Dolby
  • Up and Running
  • Amazon Web Services
  • Sources
  • Hybrik JSON
  • Video Filters
  • Audio Filters
  • Working with Audio
  • Task Modifiers
  • Package Task
  • HLS and DASH Packaging
  • Advanced HLS Packaging
  • DRM
  • Analysis & Quality Control
  • Dolby Technologies
  • Additional Tasks
  • Hybrik Versions
  • QC Player
  • Machine Performance Analysis

    DRM

    Table of Contents:

    • DRM Components
    • FairPlay, PlayReady, Widevine
    • Hybrik Video Encryption
    • DRM Specific Examples
    • DRM Playback Verification
    • Multiple DRM Support

    Introduction

    Digital Rights Management (DRM) is a systematic approach to copyright protection for digital media. The purpose of DRM is to prevent unauthorized redistribution of digital media and restrict the ways consumers can copy content.

    DRM Components

    There are many different parts to DRM, let’s define a few of the pieces:

    DRM Technologies

    DRM technologies are the underlying systems that power the protection of copyrighted content. These are some of the most common technologies:
    Widevine (Google), PlayReady (Microsoft), FairPlay (Apple), MARLIN, Adobe PrimeTime

    DRM Providers

    DRM Providers are technology companies that implement DRM technologies and provide credentials via API for both the protection and playback phases. These are some of the most common providers:
    Verimatrix, Nagra, Irdeto, Castlabs, Axinom, Brightcove, EZDRM, BuyDRM

    Video Transcoding & Packaging Systems/Platforms

    Transcoding and packaging systems are technologies that transcode or convert video and can apply DRM technologies. Some of these platforms are:

    • Dolby Hybrik
    • AWS Elemental
    • Encoding.com
    • Unified Streaming

    Video Encryption Algorithms/Formats

    Video encryption is the underlying algorithm used to protect the content as part of the DRM protection process: AES-128 CTR or CBC, Native Encryption vs. Sample-based Encryption, etc.

    Streaming Formats

    These streaming formats are common delivery methods for steaming/Over-The-Top (OTT) delivery and are the vehicles for DRM: HLS, DASH, Smooth, etc.

    Secure Video Playback

    In order to be able to playback DRM protected content you need a player that understands DRM. Depending on the device/browser/platform, the player will differ. Browser based players (Google Chrome, MS Edge, Firefox, etc.), App Players, etc.

    FairPlay, PlayReady, Widevine

    With a variety of market offerings for each component, different technologies, and platforms, video players may or may not be compatible with each other and the compatibility matrix evolves over time. Furthermore, new technologies and vendors keep coming. Below is a matrix for the three major DRM technologies and compatible browser support.

    DRM Players
    Widevine Chrome/Firefox/Android
    FairPlay Safari/iOS
    PlayReady Edge/Windows

    Refer to below link for a more comprehensive comparison
    DRM Compatibility from CastLabs.

    DRM uses the Advanced Encryption Standard (AES) encryption algorithm for media asset encryption. AES encryption algorithm operates on different block cipher modes (such as cbc, ctr, etc) and other factors such as sample encryption. Below is a matrix for the various AES encryption flavor each DRM system supports:

    DRM aes-ctr aes-cbc
    Widevine yes yes
    FairPlay no yes
    PlayReady(v4+) yes yes
    PlayReady(v1-3.3) yes no

    Similarly, below is a matrix for streaming formats support by different AES encryption block cipher modes

    streaming format aes-ctr aes-cbc
    mpeg-dash yes yes
    hls no yes

    Hybrik Video Encryption

    Hybrik supports large variety of video streaming formats, DRM technologies, and standard encryption algorithms for OTT video applications. Hybrik’s packaging processes can encrypt video content and construct manifest files based the specifications defined with Hybrik job json.

    A supported list of encryption can be found in the API documentation for encryption.

    Encryption Configuration in a Hybrik Package Task

    Hybrik has the ability to specify encryption per-layer or for all layers in your package task.

    Single DRM example

    For a more simple example where each layer has the same DRM applied let’s look at the following example.

    • Hybrik DRM configuration is specified within package task inside of the encryption object.
    • key_id, key etc. are provided by DRM systems. You provide the key and key_id from your DRM provider as part of your Hybrik Job. These parameters are not dynamically generated by Hybrik and must be acquired from your DRM system and inserted into your job json at job submission.
    • drm platform and encryption schema need to be specified.
    • This package task snippet demonstrates a Hybrik packager with encryption enabled. These parameters are specified in the encryption object.
    
    {
        "uid": "package_dash_playready_pssh",
        "kind": "package",
        "task": {
            "retry_method": "fail"
        },
        "payload": {
            "location": {
                "storage_provider": "s3",
                "path": "{{destination_path}}/cenc_dash_playready_pssh",
                "attributes": [
                    {
                        "name": "ContentType",
                        "value": "application/dash+xml"
                    }
                ]
            },
            "file_pattern": "master_manifest.mpd",
            "kind": "dash",
            "uid": "main_manifest",
            "encryption": {     <-------------
                "enabled": true,
                "schema": "mpeg-cenc",
                "drm": [
                    "playready"
                ],
                "key": "{{key}}",
                "key_id": "{{key_id}}",
                "playready_pssh": "{{pr_pssh}}"
            }
        }
    },
    ...    
    }
    
    • Use encryption object in package task to specify a single set of DRM/encryption parameters
    • The same DRM parameters including encryption key, key_id, schema, drm, PSSH string, etc. are applied to all layers
    • You may enable or disable encryption by setting the enabled parameter to true or false.

    Per-Layer DRM example

    Here is an example that demonstrates a Hybrik packager with per-layer encryption enabled. In this model, encryption_ids are specified in the transcode task when the video layers are generated or in the source element if you are packaging directly from a source. Subsequently, in the package task, you define the encryption objects to match each of the encryption_ids defined in the previous task.

    
    {
        "uid": "transcode_video",
        "kind": "transcode",
        "payload": {
            "location": {
                "storage_provider": "s3",
                "path": "{{destination_path}}/media"
            },
            "source_pipeline": {},
            "targets": [
                {
                    "file_pattern": "{{output_basename}}_2000{default_extension}",
                    "existing_files": "replace",
                    "container": {
                        "kind": "fmp4",
                        "segment_duration_sec": "{{fmp4_segment_duration_sec}}"
                    },
                    "video": {
                        "codec": "h264",
                        "bitrate_mode": "cbr",
                        "use_scene_detection": false,
                        "profile": "high",
                        "bitrate_kb": 2000,
                        "vbv_buffer_size_kb": 2000,
                        "height": 144,
                        "par": "1:1",
                        "level": "3.1"
                    },
                    "encryption_id": "id_widevine_key1"     <-------------
                },
                {
                    "file_pattern": "{{destination_path}}/media_3000{default_extension}",
                    "existing_files": "replace",
                    "container": {
                        "kind": "fmp4",
                        "segment_duration_sec": "{{fmp4_segment_duration_sec}}"
                    },
                    "video": {
                        "codec": "h264",
                        "bitrate_mode": "cbr",
                        "use_scene_detection": false,
                        "profile": "high",
                        "bitrate_kb": 3000,
                        "vbv_buffer_size_kb": 3000,
                        "height": 144,
                        "par": "1:1",
                        "level": "3.1"
                    },
                    "encryption_id": "id_widevine_key2"     <-------------
                }
            ]
        }
    },
    {
        "uid": "dash_widevine_encrypted_packaging",
        "kind": "package",
        "payload": {
            "location": {
                "storage_provider": "s3",
                "path": "{{destination_path}}/widevine-dash",
                "attributes": [
                    {
                        "name": "ContentType",
                        "value": "application/dash+xml"
                    }
                ]
            },
            "file_pattern": "manifest.mpd",
            "kind": "dash",
            "uid": "main_manifest",
            "force_original_media": false,
            "media_location": {
                "storage_provider": "s3",
                "path": "{{destination_path}}/widevine-dash",
                "attributes": [
                    {
                        "name": "ContentType",
                        "value": "video/mp4"
                    }
                ]
            },
            "encryptions": [                            <-------------
                {
                   "id": "id_widevine_key1",
                    "enabled": true,
                    "schema": "mpeg-cenc",
                    "drm": [
                        "widevine"
                    ],
                    "key": "{{key}}",
                    "key_id": "{{key_id}}"
                },
                {
                    "id": "id_widevine_key2",
                    "enabled": true,
                    "schema": "mpeg-cenc",
                    "drm": [
                        "widevine"
                    ],
                    "key": "{{key}}",
                    "key_id": "{{key_id}}"
                }
            ]
        }
    },
    ...
    
    
    • Assign a transcode.targets.encryption_id to each target (layer) in transcode task or source element.
    • Use an array of encryptions in package task to specify different set of DRM/encryption parameters
    • Use an encryption id in each encryptions array object to specify which layers that the object will be applied to.
    • The DRM parameters including encryption key, key_id, schema, drm, PSSH string, etc. are applied to the layers matching the encryption id.
    • Encryption id in transcode task targets and encryption id in packager encryptions array need to match with each other. Jobs will fail if encryption id and the encryptions array are defined but there is no match for the defined encryption_id
    • It is one or the other. encryptions array and encryption object cannot co-exist in the package task.

    In one Hybrik job json file, multiple package tasks can be defined for different streaming types such as dash and hls that utilize the same source media. In each of the package tasks, encryption can be enabled, and use the same or different encryption schema, DRM technology and key/key_id/iv, etc. parameters can be specified based on your requirements.

    DRM Specific Examples

    Widevine

    These values of Widevine DRM configuration are expected in the following format:

    • Widevine DRM key
      • (required) You need to provide a key that will be used to encrypt the content (16 byte encryption key, represented as 32 hexadecimal characters)
    • Widevine key_id
      • also known as Key ID, or ContentID. Its a unique identifier for your content (16 byte initialization vector, represented as 32 hexadecimal characters)
    • widevine_pssh
      • Base64 encoded String. This is an optional parameter with Hybrik packager. When it’s not provided, Hybrik will automatically generates a pssh string and play it to the manifest. Please note – Hybrik currently only takes a pssh string when there is a content id contained in the pssh string.

    Example

    json snippet for Widevine DRM

    "encryption": {
        "enabled": true,
        "schema": "mpeg-cenc",
        "drm": [
            "widevine"
        ],
        "key": "8cff2521c18397f1e002455b11cef702",
        "key_id": "1bb7b731-e125-496c-be5d-867ee09eb801",
        "widevine_provider": "Your_DRM_provider"
    }
    

    PSSH strings

    Streams may contain one or more Protection System Specific Header (PSSH) boxes, each for a unique SystemID, at each location where a PSSH box is necessary. Content using this stream format should include a box containing the Common SystemID and PSSH Box Format. PSSH strings are required when making a license request from a Player to Widevine and PlayReady DRM license servers.

    You can read details on the PSSH format

    The PSSH string is obtained from the response when making a key request to DRM server.

    Hybrik creates manifest files with DRM parameters included such as DRM platform, encryption key, pssh string, etc. Below is an example ContentProtection tag inside AdaptationSet of MPEG Dash with encryption manifest (.mpd) file:

    <ContentProtection cenc:default_KID="1b47a131-e125-496c-be5d-867ee09eb801" schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
    <ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
      <cenc:pssh>AAAAWXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADkSEBtHoTHhJUlsvl2GfuCeuAESEBtHoTHhJUlsvl2GfuCeuAEaDXRlc3RfcHJvdmlkZXJI49yVmwY=</cenc:pssh>
    </ContentProtection>
    

    PlayReady

    To encrypt your content so it can be used with PlayReady DRM, an encryption key is required.

    These values of PlayReady DRM configuration are expected in the following format:

    • PlayReady DRM key
      • (required) You need to provide a key that will be used to encrypt the content (16 byte encryption key, represented as 32 hexadecimal characters)
    • PlayReady key_id
      • also known as Key ID, or ContentID. Its a unique identifier for your content (16 byte initialization vector, represented as 32 hexadecimal characters)
    • playready_pssh
      • Base64 encoded String
    • playready_url
      • The URL string from DRM system that makes PlayReady license requests to Microsoft PlayReady licenses.
    • Please note – playready_pssh and playready_url are optional parameters, but at least one of the two will be required by the Hybrik packager

    Here is a json snippet for PlayReady:

    "encryption": {
        "enabled": true,
        "schema": "mpeg-cenc",
        "drm": [
            "playready"
        ],
        "key": "8cdd2521c18397f1e002455b11cef702",
        "key_id": "1b47a131-e125-496c-be5d-867ee09eb801",
        "playready_url": "https://www.yourDRMvendor.com/yourDRMvendorLic"
    }
    

    FairPlay

    These values of FairPlay DRM configuration are expected in the following format:

    • FairPlay DRM key:
      • 16 byte encryption key, represented as 32 hexadecimal characters)
    • FairPlay key_id
      • A unique identifier for your content (16 byte initialization vector, represented as 32 hexadecimal characters)
    • iv (initialization vector)
      • 16 byte initialization vector represented as 32 hexadecimal characters, using 32 “0”s in the example here (set with the DRM provider also). Refer here for more information about IV. An iv is used to ensure that the same value encrypted multiple times, even with the same secret key, will not always result in the same encrypted value. iv is mandatory.
    • fairplay_uri
      • the fairplay URI for the HLS URI attribute are provided by DRM vendor

    Here is a json snippet for FairPlay:

    "encryption": {
        "enabled": true,
        "schema": "sample-aes",
        "drm": [
            "fairplay"
        ],
        "iv": "00000000000000000000000000001234",
        "key": "8cdd2521c18397f1e002455b11fdf702",
        "key_id": "1b47a131-e125-496c-be5d-867ab09eb801",
        "fairplay_uri": "skd://yourdrm_skd_url?assetId=747164cd-b88c-4260-kk9e-37161c7b17cc"
    },
    

    For hls with encryption streaming manifest file, the DRM information would be included in individual media manifest files but not in the master manifest file. Below are example DRM entries in a HLS media manifest file:

    #EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://YourDRMskyURI?assetId=c1c6af27-32f0-472a-9448-c08a3d3addd1",KEYFORMAT="com.apple.streamingkeydelivery"
    

    DRM Playback Verification

    You may use various devices and players to play out DRM enabled OTT media to verify if your DRM workflow is working. DRM is largely a black box outside of the player and can be difficult to troubleshoot. A few important highlights on playback verification:

    • When you can not play out DRM enabled OTT media, you should first verify if you can play out with DRM disabled. This will eliminate non-DRM related causes for the failure of playback. An easy way to re-package without encryption is to set the enabled parameter to false.
    • Check the manifest files and OTT media assets generated by Hybrik to see if the manifest files have expected tags, and if the OTT media asset files are present as expected.
    • Refer to the beginning of this tutorial for the right platform and browser based on different DRM system. For example, you might need specific hardware to play out certain DRM encrypted streams.
    • Make sure to provide correct manifest URL and DRM license URL for player/device configuration. For FairPlay DRM, you will need to provide your Apple license certificate URL where Apple ASK is hosted. You need to make sure the streams, manifest files and license server/certificate URLs are all accessible by the player.

    Multiple DRM support

    Hybrik supports multiple DRMs in the same package task. These can be defined with a single package task illustrated below in this example:

    { 
        "uid": "manifest_creator_dash_hls_widevine_playready",
        "kind": "package",
        "task": {
            "retry_method": "fail"
        },
        "payload": {
            "location": {
                "storage_provider": "s3",
                "path": "{{destination_path}}/dash_hls_widevine_playread_mpeg-cbcs",
                "attributes": [
                    {
                        "name": "ContentType",
                        "value": "application/dash+xml"
                    }
                ]
            },
            "kind": [
                "dash",
                "hls"
            ],
            "uid": "main_manifest",
            "encryption": {
                "enabled": true,
                "schema": "mpeg-cbcs",
                "drm": [
                    "widevine",
                    "playready"
                ],
                "key": "8cdd2521c18397f1e002455b11fdf702",
                "key_id": "1b47a131-e125-496c-be5d-867ab09eb801",
                "widevine_provider": "yourDRMprovider",
                "playready_url": "{{playready_url_drmtoday}}"
            },
            "segmentation_mode": "fmp4",
            "dash": {
                "file_pattern": "master_manifest.mpd"
            },
            "hls": {
                "file_pattern": "master_manifest.m3u8"
            }
        }
    }, 
    

    Multiple Package Tasks for Different Streaming and DRM schemas

    In some use cases, you may need to package the same sources into a different streaming format (such as HLS and Dash), and encrypt each with different DRMs. This can be done with a single Hybrik job that starts from one source element or fragmented asset(s) and connects to multiple package tasks, each using different DRM and/or different streaming schemas.

    Example Jobs

    • HLS Packaging with Apple FairPlay encryption
    • DASH Packaging with Microsoft PlayReady encryption
    • DASH Packaging with Widevine encryption
    • HLS Packaging with Layer-based Fairplay DRM
    • Packaging with DRM from source (no transcoding)