Configure encryption for digital rights management and content protection

To support digital rights management (DRM) and content protection, configure encryption of your output video with the Transcoder API. The current version of the Transcoder API supports common encryption (CENC) DRM from Google Widevine and Microsoft PlayReady, as well as Apple FairPlay DRM and AES-128 content protection. The Transcoder API is only responsible for encryption of the content.

Before you begin

Before you upload your content to the Transcoder API for encryption, you need a way to generate and store random 128-bit keys (32 hexadecimal characters). The Transcoder API uses those keys to encrypt the content according to the container. Ensure that the keys are registered in a license policy from your DRM provider. This will allow players to decrypt your content later. Content encryption is supported for the following containers:

Type Technology Format Video Codecs Audio Codecs
H.264 H.265 AAC
DRM FairPlay HLS TS (SAMPLE-AES) fMP4 (SAMPLE-AES) TS (SAMPLE-AES)
fMP4 (SAMPLE-AES) fMP4 (SAMPLE-AES)
DRM Widevine, PlayReady DASH fMP4 (MPEG-CENC) fMP4 (MPEG-CENC)
DRM Widevine, PlayReady HLS fMP4 (MPEG-CENC) fMP4 (MPEG-CENC)
Content protection AES-128 HLS, DASH fMP4, TS (AES-128) fMP4, TS (AES-128) fMP4, TS (AES-128)

Google Widevine and Microsoft PlayReady support both dynamic adaptive streaming over HTTP (DASH) and HTTP live streaming (HLS) protocols. Device support for these protocols varies (for example, HLS and DASH are supported on Android and the web, but only HLS is supported on iOS). The output for these protocols is encrypted using the CENC standard (ISO/IEC 23001-7:2016 for ISO-BMFF fragments). In particular, the encryption scheme must be AES-128 CTR.

Apple FairPlay uses the HLS protocol. The output for this protocol is encrypted using SAMPLE-AES CBC. For more information on this output, see MPEG-2 Stream Encryption Format for HTTP Live Streaming.

Content protection

AES-128 supports either DASH or HLS and is encrypted using CTR or CBC mode.

Select an output container

The Transcoder API supports the following containers:

  • TS (using the AES-128 CBC scheme):
    • HLS with SAMPLE-AES
    • HLS with (AES-128 CTR or AES-128 CBC)
  • fMP4:
    • HLS
      • SAMPLE-AES
    • DASH
      • MPEG-CENC
      • Scheme: AES-128 CTR or AES-128 CBC

Create the multiplexed output stream

Add the output stream to the muxStreams list in the job configuration. Configure the encryption settings using the Encryption object.

The following is a REST/JSON example for the TS output file container:

"muxStreams": [
  {
    "key": "360p-my-video-ts",
    "fileName": "360p-my-video.ts",
    "container": "ts",
    "elementaryStreams": [
      "video-stream0",
      "audio-stream0"
    ],
    "encryption": {
      "key": "aabbccddeeff11223344556677889900",
      "iv": "00112233445566778899aabbccddeeff",
      "sampleAes": {
        "keyUri": "skd://00112233445566778899aabbccddeeff"
      }
    }
  }
]

The following is a REST/JSON example for the fMP4 output container:

"muxStreams": [
  {
    "key": "360p-my-video-fmp4",
    "container": "fmp4",
    "elementaryStreams": [
      "video-stream0"
    ],
    "fileName": "360p-my-video.fmp4",
    "encryption": {
      "key": "aabbccddeeff11223344556677889900",
      "iv": "00112233445566778899aabbccddeeff",
      "sampleAes": {
        "keyUri": "skd://00112233445566778899aabbccddeeff"
      }
    }
  },
  {
    "key": "360p-my-audio-fmp4",
    "container": "fmp4",
    "elementaryStreams": [
      "audio-stream0"
    ],
    "fileName": "360p-my-audio.fmp4",
    "encryption": {
      "key": "aabbccddeeff11223344556677889900",
      "iv": "00112253445566778899aabbccddeeff",
      "sampleAes": {
        "keyUri": "skd://00112233445566778899aabbccddeeff"
      }
    }
  }
]

Add the output streams to the manifest file

The following is a REST/JSON example for the TS output file container:

"manifests": [
  {
    "fileName": "manifest.m3u8",
    "type": "HLS",
    "muxStreams": [
      "360p-my-video-ts"
    ]
  }
]

The following is a REST/JSON example for the fMP4 output container:

"manifests": [
  {
    "fileName": "main-cbcs.mpd",
    "type": "DASH",
    "muxStreams": [
      "360p-my-audio-fmp4",
      "360p-my-video-fmp4"
    ]
  }
]