Support+1 888 882 1880
Search IconA magnifying glass icon.
Talk to Us


Brightcove Engineering

By Brightcove Engineering

at Brightcove

How to Protect Video Content with Digital Rights Management (DRM)

Tech Talk

BlogPost: DRM

Understanding Digital Rights Management

DRM: an acronym that strikes fear into the hearts of CTOs and developers alike. Digital Rights Management (DRM) is a method of securing digital content to prevent unauthorized use and piracy, and it has become a requirement for many streaming video platforms as more premium content is delivered via the public Internet.

In a nutshell, DRM ensures that video content is stored and transmitted in an encrypted form, so that only authorized users and devices can play it back. Before it is streamed,  video content must be encrypted and packaged, often using multiple DRM schemes for greater device compatibility. When a user attempts to play back a video, the video player requests a key from a license server. The server determines whether the user and device are authorized, before issuing a license response with a decryption key. The player can then decrypt and play back the content for the user.

The figure below illustrates this process. In this series of posts, we’ll dive into the details of setting up a DRM-protected streaming system like the one pictured, starting with an overview of some of the available protection schemes and how to encrypt and package content for each with static delivery. Then we'll cover how DRM packaging is applied with Dynamic Delivery.

Flow chart of streaming video workflow with DRM.

If you’re using a full-featured online video platform, like Video Cloud, supporting DRM may be as simple as upgrading your account and configuration to enable it. If you’ve customized your player or built out a custom streaming workflow, you’ll need to update and add some components to support DRM.

Enabling DRM requires changes to at least three components of your streaming workflow:

  1. Content
    • your assets must be transcoded, encrypted, and packaged in formats compatible with the DRM systems you need to  support.
  2. Player
    • your video player must be able to request a key from a license server and decrypt the video; this may require different players on different platforms.
  3. License Server - your video player will request decryption keys from a license server every time a piece of content is requested; the license server authenticates and responds to these requests.

Though there are many DRM systems available to protect video content, we only need to worry about The Big Three for supporting the most popular web browsers, devices, and set-top boxes:

  • Google’s Widevine
    • Widevine-protected content can be played in Chrome and Firefox web browsers, as well as Android and Chromecast devices.
  • Apple’s FairPlay
    • FairPlay-protected content can be played in Safari on OS X, as well as iPhones, iPads, and AppleTVs.
  • Microsoft's PlayReady
    • PlayReady-protected content can be played in IE11 and Edge browsers, Windows Phone, Xbox, and other platforms via SDKs.

This compatibility chart shows a sampling of popular platforms and their compatibility with these DRM systems. See here for more details.

Internet Explorer 11
Microsoft Edge
Chromecast / AndroidTV
Fire TV
Xbox One
Samsung Smart TV

Packaging Content
To prevent content from being copied or played back by unauthorized players or devices, DRM requires content to be encrypted. It must also be packaged in a compatible format, generally MPEG-DASH or HLS. This can be done as part of the transcoding process, or assets can be encrypted and packaged after the fact. Some platforms and CDNs also support just-in-time encryption and packaging of assets as they are requested by players.

Widevine and PlayReady both support Common Encryption (CENC) and MPEG-DASH, which means you can encrypt and package your content once and decrypt those assets using either DRM system. FairPlay uses SAMPLE-AES encryption and HLS packaging, which means you will need to encrypt and package your content twice if you need to support all three systems. Zencoder allows you to transcode your content once, and transmux that content to both MPEG-DASH with CENC encryption and HLS with SAMPLE-AES encryption, all in one operation.

For each asset that you want to serve with DRM, you’ll need to generate an encryption key, an asset ID, and a key ID. Both CENC and FairPlay use an AES 128-bit key to encrypt content. For FairPlay, you’ll also generate and provide an Initialization Vector (IV). You can generate these keys and IDs yourself, or use the tools provided by your license server to generate them automatically.

You’ll ingest these keys and IDs into your license server so that it can be sent to the player, which will use the key to decrypt the content. It’s important to also store this key securely within your platform as a backup; you’ll need access to these keys if you move to a different license server in the future.

The keys and IDs, along with a few other parameters, are also used to encrypt and package the content. The following Zencoder example job illustrates how to encode, encrypt and package content for all three DRM systems, with further description below:

{ “input“: “//“, “outputs“: [ { “label“: “mp4-1500k“, “prepare_for_segmenting“: [“hls“, “dash“], “audio_bitrate“: 128, “video_bitrate“: 1100, “size“: “1280x720“, “url“: “s3://my-bucket/mp4/1500.mp4“
}, { “label“: “mp4-1000k“, “prepare_for_segmenting“: [“hls“, “dash“], “audio_bitrate“: 128, “video_bitrate“: 695, “size“: “960x540“, “url“: “s3://my-bucket/mp4/1000.mp4“
}, { “label“: “mp4-500k“, “prepare_for_segmenting“: [“hls“, “dash“], “audio_bitrate“: 128, “video_bitrate“: 290, “size“: “640x360“, “url“: “s3://my-bucket/mp4/500.mp4“
}, { “label“: “hls-1500k“, “source“: “mp4-1500k“, “copy_video“: true, “copy_audio“: true, “type“: “segmented“, “byte_range_segmenting“: true, “url“: “s3://my-bucket/hls/1500.m3u8“, “drm“: { “method“: “fairplay“ }, “encryption_key_url“: “skd://my-asset-id“, “encryption_iv“: “b4839b42647b884eb5a0804d3699aac4“, “encryption_key“: “162c823de34317d84fcbbc7b44b54943“
}, { “label“: “hls-1000k“, “source“: “mp4-1000k“, “copy_video“: true, “copy_audio“: true, “type“: “segmented“, “byte_range_segmenting“: true, “url“: “s3://my-bucket/hls/1000.m3u8“, “drm“: { “method“: “fairplay“ }, “encryption_key_url“: “skd://my-asset-id“, “encryption_iv“: “b4839b42647b884eb5a0804d3699aac4“, “encryption_key“: “162c823de34317d84fcbbc7b44b54943“
}, { “label“: “hls-500k“, “source“: “mp4-500k“, “copy_video“: true, “copy_audio“: true, “type“: “segmented“, “byte_range_segmenting“: true, “url“: “s3://my-bucket/hls/500.m3u8“, “drm“: { “method“: “fairplay“ }, “encryption_key_url“: “skd://my-asset-id“, “encryption_iv“: “b4839b42647b884eb5a0804d3699aac4“, “encryption_key“: “162c823de34317d84fcbbc7b44b54943“
}, { “type“: “playlist“, “url“: “s3://my-bucket/hls/multi_bitrate_playlist.m3u8“, “streams“: [ { “path“: “1000.m3u8“, “source“: “hls-1000k“ }, { “path“: “1500.m3u8“, “source“: “hls-1500k“ }, { “path“: “500.m3u8“, “source“: “hls-500k“ } ] }, { “label“: “dash-1500k“, “source“: “mp4-1500k“, “copy_video“: true, “copy_audio“: true, “streaming_delivery_format“: “dash“, “type“: “segmented“, “url“: “s3://my-bucket/dash/1500k/rendition.mpd“, “drm“: { “content_id“: “my-asset-id“, “content_key“: “dfee49d3822fb27d4dcce206661786d6“, “iv_size“: 8, “key_id“: “3c60f4bb73073b408c83ee373c33ebf7“, “method“: “cenc“, “schemas“: [ { “license_acquisition_url“: “//my-license-server/cenc/“, “provider“: “drmtoday“, “type“: “widevine“
}, { “license_acquisition_url“: “//my-license-server/playready/“, “provider“: “drmtoday“, “type“: “playready“
} ] } }, { “label“: “dash-1000k“, “source“: “mp4-1000k“, “copy_video“: true, “copy_audio“: true, “streaming_delivery_format“: “dash“, “type“: “segmented“, “url“: “s3://my-bucket/dash/1000k/rendition.mpd“, “drm“: { “content_id“: “my-asset-id“, “content_key“: “dfee49d3822fb27d4dcce206661786d6“, “iv_size“: 8, “key_id“: “3c60f4bb73073b408c83ee373c33ebf7“, “method“: “cenc“, “schemas“: [ { “license_acquisition_url“: “//my-license-server/cenc/“, “provider“: “drmtoday“, “type“: “widevine“
}, { “license_acquisition_url“: “//my-license-server/playready/“, “provider“: “drmtoday“, “type“: “playready“
} ] } }, { “label“: “dash-500k“, “source“: “mp4-500k“, “copy_video“: true, “copy_audio“: true, “streaming_delivery_format“: “dash“, “type“: “segmented“, “url“: “s3://my-bucket/dash/500k/rendition.mpd“, “drm“: { “content_id“: “my-asset-id“, “content_key“: “dfee49d3822fb27d4dcce206661786d6“, “iv_size“: 8, “key_id“: “3c60f4bb73073b408c83ee373c33ebf7“, “method“: “cenc“, “schemas“: [ { “license_acquisition_url“: “//my-license-server/cenc/“, “provider“: “drmtoday“, “type“: “widevine“
}, { “license_acquisition_url“: “//my-license-server/playready/“, “provider“: “drmtoday“, “type“: “playready“
} ] } }, { “streaming_delivery_format“: “dash“, “type“: “playlist“, “url“: “s3://my-bucket/dash/manifest.mpd“, “streams“: [ { “source“: “dash-1500k“, “path“: “1500k“ }, { “source“: “dash-1000k“, “path“: “1000k“ }, { “source“: “dash-500k“, “path“: “500k“ } ], “drm“: { “content_id“: “my-asset-id“, “content_key“: “dfee49d3822fb27d4dcce206661786d6“, “iv_size“: 8, “key_id“: “3c60f4bb73073b408c83ee373c33ebf7“, “method“: “cenc“, “schemas“: [ { “license_acquisition_url“: “//my-license-server/cenc/“, “provider“: “my-provider“, “type“: “widevine“
}, { “license_acquisition_url“: “//my-license-server/playready/“, “provider“: “drmtoday“, “type“: “playready“
} ] } } ] }

This job has three mp4 encodes (mp4-1500k, mp4-1000k, and mp4-500k), which are then used as the source for both the HLS and DASH outputs. The HLS outputs specify the FairPlay DRM method, the encryption_key, the encryption_iv, and the encryption_key_url. For FairPlay, the encryption_key_url is actually a reference to the asset ID, and the format of this URL will vary depending on your license server’s implementation.

The DASH outputs specify the CENC encryption method and the Widevine and PlayReady DRM systems, as well as a few more fields:

content_idasset ID (user-defined string)
content_keyAES 128-bit encryption key
key_idusually 16 Base64 encoded bytes (user defined or automatically generated)
license_acquisition_urlURL of the license server’s Widevine or PlayReady endpoint
providername of the license server provider

Once your content is encrypted and packaged, it needs to be transferred to your origin server or CDN for streaming to your users. This can also be done as part of a Zencoder job. Stay tuned for the next part of this series, when we’ll dive into how DRM packaging is applied with Dynamic Delivery.

*Post updated on July 17, 2018 by JD Russell.