Integrating Bitmovin Encoder with PallyCon Multi-DRM


This tutorial walks through integrating Bitmovin CENC Encoding with PallyCon CPIX DRM in TWO simple steps.

For a full working sample refer to the Appendix

3 Minute Video Guide of Bitmovin CENC + Pallycon CPIX Integration


  1. CONTENT-ID ; your script can generate this id to uniquely identify each content
  2. KMS version ; this tutorial uses PallyCon KMS version 2 as it supports multi-key encryption
  3. PallyCon KMS URL ; most of the time it looks like this
  4. KMS token ; to uniquely identify and protect your request to the PallyCon KMS

Screenshot from the PALLYCON portal

Applicable Use cases

  1. Single Key for all renditions
  2. Multi-key i.e different keys for different renditions

In this tutorial we'll run through use case #2 i.e Multi-Key

1. Get DRM information from PallyCon


We'll be discussing multi-key integration i.e 1 key for SD and 1 key for AUDIO. Implementation of the below logic can be found in the method _get_pallycon_drm_config @


  1. Get the values from the pre-requisites section and update them respectively
CONTENT_ID = "my-unique_content_id"
# Request headers
headers = {'content-type': 'application/xml'}
  1. Request DRM keys from PallyCon. in this case it's been configured for the Fairplay, Widevine and Playready for 1 SD key and 1 AUDIO key.
a. `<cpix:ContentKey>` - 1 for each key. 
    a.1 In our use case there'd be two such elements
  b. `cpix:DRMSystem` - the different DRM systems i.e Widevine/Playready/Fairplay we are requesting for each key in #1. 
    b.1 In our usecase there'd be 6 elements (3 for the 1st key and 3 for the 2nd.)
  c. `cpix:ContentKeyUsageRule` - the intended track type (SD/HD/AUDIO) for each key
    c.1 In our usecase there'd be 2 such elements are we are requesting 1 key for `SD` and another for `AUDIO`
  1. Parse the PallyCon DRM response into the Pallycon_Drm_Config helper class

2. Apply PallyCon DRM using Bitmovin CENC API

  1. After getting the PallyCon drm configs we first split the DRM config by tracks i.e SD/AUDIO
    def get_drm_config_by_track(pallycon_drm_configs: typing.Dict, track: str) -> typing.Dict:
        return dict(filter(lambda elem: (elem[1]).get_track() == track,pallycon_drm_configs.items()))
    pallycon_drm_configs = _get_pallycon_drm_config()
    audio_drm_configs = get_drm_config_by_track(pallycon_drm_configs, "AUDIO")
    sd_drm_configs = get_drm_config_by_track(pallycon_drm_configs, "SD")
  1. Lastly we apply the Pallycon_Drm_Config and create the DRM Muxing by using the method _create_drm_config @



Question: Exception in _get_pallycon_drm_config @

Answer: This could be due to an

  1. expired PallyCon DRM token OR
  2. invalid request body

Kindly check with your PallyCon contact for more details.


WORKING Source code

  1. Clone the Bitmovin GitHub repository
  2. use this updated cenc_drm_content_protection_v1.2 file w/ the PallyCon integation in place of the GitHub sample

Additional reads

  1. the underpinnings of the SPEKE integration OR
  2. the CENC integration option

please visit the reference By PallyCon.