Integrate BuyDRM with the Bitmovin Cloud Encoder
This tutorial will show you how to create an encoding with MultiDRM protection using the KeyOS MultiKeyTM Service from BuyDRM as your DRM key provider. Furthermore, you can use our native HTML5 Bitmovin player to play your DRM protected content on every device out there.
The following sections will explain each step you need to take to achieve a successful encoding with DRM protection using our encoding services and BuyDRM.
Requesting the Keys from BuyDRM’s KeyOS Multikey Service
First of all, we need to get the keys necessary to encrypt your encoded content. To do this we will issue an HTTP POST request against BuyDRM’s KeyOS Multikey Service API, which will provide us the “pssh box” necessary for Widevine DRM and the “content Key” which is required for PlayReady DRM.
That request requires 4 parameters:
- Your “KeyOS User Key”
It can be obtained from the BuyDRM KeyOS support team - KeyID
It is a randomly generated GUID. You can use the same key for multiple content that you want to encode and protect. As a result you will get a “group of contents” using a single license. If you don’t want to do this, we recommend using unique Key ID every time you make a request to the API. - ContentID
This is also a randomly generated GUID, but is unique within the KeyOS system. - MediaID
You can think of this value as a filename. You can use something like “my file” or an ID that makes sense to you.
These 4 parameters are required for the request body. The whole HTTP POST request will look like the following (please see the highlighted placeholder for the required parameters):
POST /pck HTTP/1.1 Host: packager.licensekeyserver.com Content-Type: text/xml; charset=utf-8 SOAPAction: http://tempuri.org/ISmoothPackager/RequestEncryptionInfo <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <RequestEncryptionInfo xmlns="http://tempuri.org/"> <ServerKey>08CC2D0F-DF0C-4217-9460-326B60C41E7E</ServerKey> <RequestXml> <![CDATA[ <KeyOSEncryptionInfoRequest> <APIVersion>5.0.0.2</APIVersion> <DRMType>smooth</DRMType> <EncoderVersion>BuyDRMAP v1.0</EncoderVersion> <UserKey>__YOUR_KEY_OS_USER_KEY__</UserKey> <KeyID>__YOUR_KID__</KeyID> <ContentID>__YOUR_CONTENT_ID__</ContentID> <MediaID>__YOUR_MEDIA_ID__</MediaID> <fl_GeneratePRHeader>true</fl_GeneratePRHeader> <fl_GenerateWVHeader>true</fl_GenerateWVHeader> </KeyOSEncryptionInfoRequest> ']]> </RequestXml> </RequestEncryptionInfo> </s:Body> </s:Envelope>
Javascript Example
BuyDRM already provides a basic Javascript example (see below), which you can use to test the retrieval of the necessary keys from their API. It relies on jQuery and guid.js.
<!DOCTYPE html> <html lang="en"> <head> <script type="text/javascript" src="http://code.jquery.com/jquery-3.1.0.min.js"></script> <script type="text/javascript" src="https://raw.githubusercontent.com/dandean/guid/master/guid.js"></script> <meta charset="UTF-8"> <title>Sample Bitcodin Setup</title> </head> <body> <script type="text/javascript"> (function($, Guid) { function requestKeysFromKeyOS() { // Function is used to translate Base64 encoded values into HEX values. function base64ToHex(str) { for (var i = 0, bin = atob(str.replace(/[ \r\n]+$/, '')), hex = []; i < bin.length; ++i) { var tmp = bin.charCodeAt(i).toString(16); if (tmp.length === 1) tmp = '0' + tmp; hex[hex.length] = tmp; } return hex.join(''); } // Get keys required for DRM protection from KeyOS Key Management API. jQuery will be used to make a request. var keyosUserKey = 'PLEASE, GET FROM KEYOS SUPPORT'; var fileName = 'File ' + Guid.raw(); var kid = Guid.raw(); var cid = Guid.raw(); return new Promise(function(fulfill, reject) { console.log('Getting keys from KeyOS API.'); $.ajax({ type: 'POST', url: 'https://packager.licensekeyserver.net/pck', contentType: 'text/xml; charset=utf-8', headers: { SOAPAction: 'http://tempuri.org/ISmoothPackager/RequestEncryptionInfo' }, data: '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">' + '<s:Body>' + '<RequestEncryptionInfo xmlns="http://tempuri.org/">' + '<ServerKey>08CC2D0F-DF0C-4217-9460-326B60C41E7E</ServerKey>' + '<RequestXml><![CDATA[' + '<KeyOSEncryptionInfoRequest>' + '<APIVersion>5.0.0.2</APIVersion>' + '<DRMType>smooth</DRMType>' + '<EncoderVersion>BuyDRMAP v1.0</EncoderVersion>' + '<UserKey>' + keyosUserKey + '</UserKey>' + '<KeyID>' + kid + '</KeyID>' + '<ContentID>' + cid + '</ContentID>' + '<fl_GeneratePRHeader>true</fl_GeneratePRHeader>' + '<fl_GenerateWVHeader>true</fl_GenerateWVHeader>' + '<MediaID>' + fileName + '</MediaID>' + '</KeyOSEncryptionInfoRequest>' + ']]></RequestXml>' + '</RequestEncryptionInfo>' + '</s:Body>' + '</s:Envelope>', success: function (data, status, jqXHR) { try { console.log('KeyOS API responded.', data); var requestResult = $($.parseXML(jqXHR.responseText)).find('RequestEncryptionInfoResult').text(); var response = $($.parseXML(requestResult)); if (!response) throw new Error('Response from KeyOS Key Management API is malformed.'); var responseStatus = response.find('Status').text(); var responseMessage = response.find('Message').text(); var responseLogId = response.find('LogId').text(); if (responseStatus === '1') throw new Error('Response from KeyOS Key Management API contains an error: ' + responseLogId + ', ' + responseMessage); console.log('KeyOS API responded with success.', data); var psshBox = response.find('WVHeader').text(); var contentKey = response.find('ContentKey').text(); fulfill({ pssh: psshBox, // Return ContentKey as HEX, not Base64 encoded byte array. contentKey: base64ToHex(contentKey), // Return KeyID as HEX, not GUID. keyId: kid.split('-').join(''), // Return ContentID as HEX, not GUID. contentId: cid.split('-').join(''), prLAUrl: 'http://sldrm.licensekeyserver.com/core/rightsmanager.asmx', wvLAUrl: 'http://widevine.licensekeyserver.com' }); } catch(err) { console.log('KeyOS API responded with error.', err); reject({ error: err.message }); } }, error: function() { reject({ error: 'Sorry, error while trying to get data from KeyOS Key Management API' }); } }); }); } requestKeysFromKeyOS(); })(jQuery, Guid); </script> </body> </html>
Create an Encoding with Multi DRM Configuration (PlayReady + Widevine) with our Java API Client
The following Configuration can be found in our Java API Client example at line 77 . You will need to enter the values you obtained from BuyDRM’s API earlier. Based on that example, all you need to do is to replace: __YOUR_KID__ with your randomly generated KeyID from before, __BUYDRM_CONTENT_KEY__ and __BUYDRM_PSSH__ with the ContentKey and PSSH Information you obtained earlier from the request against BuyDRM’s API.
CreateJobWithPlayreadyWidevineCombinedDRM.java (@GitHub):
CombinedDrmConfig drmConfig = new CombinedDrmConfig(); drmConfig.kid = "__YOUR_KID__"; //HEX Format required drmConfig.key = "__BUYDRM_CONTENT_KEY__"; //HEX Format required drmConfig.laUrl = "http://pr.test.expressplay.com/playready/RightsManager.asmx"; drmConfig.pssh = "__BUYDRM_PSSH__"; //BASE64 encoded string required
BuyDRM has prepared an example based on our Javascript API Client, which comes with the example for obtaining the keys from their API and it creates a DRM protected Encoding with our encoding service. BuyDRM customers can access that here.
Setup the Bitmovin HTML5 Player with DRM
We already have a tutorial in place, which explains how to configure the Bitmovin HTML5 Player with BuyDRM in order to play your DRM protected content.
We also offer other API clients for the most popular languages including PHP, java, node.js, python, Ruby and C#/.NET. You can try out our encoding service for free, just sign up for a free account. This account will allow you up to 10 encodings or 2.5GB per month.
Our encoding API is well documented, and you can find information on how to use it in our support section.
You may also find our tutorial on using multiple DRMs useful.
Video technology guides and articles
- Back to Basics: Guide to the HTML5 Video Tag
- What is a VoD Platform?A comprehensive guide to Video on Demand (VOD)
- Video Technology [2022]: Top 5 video technology trends
- HEVC vs VP9: Modern codecs comparison
- What is the AV1 Codec?
- Video Compression: Encoding Definition and Adaptive Bitrate
- What is adaptive bitrate streaming
- MP4 vs MKV: Battle of the Video Formats
- AVOD vs SVOD; the “fall” of SVOD and Rise of AVOD & TVOD (Video Tech Trends)
- MPEG-DASH (Dynamic Adaptive Streaming over HTTP)
- Container Formats: The 4 most common container formats and why they matter to you.
- Quality of Experience (QoE) in Video Technology [2022 Guide]