Developers

Integrate BuyDRM with Bitmovin

Gernot Zwantschko
. 6 min read
BuyDRM tutorial Bitmovin Multi-DRM

BuyDRM tutorial Bitmovin Multi-DRM

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

 

Gernot Zwantschko

Gernot Zwantschko

Head of Support, Global

Gernot is one of Bitmovin's most experienced developers, and leads the customer support team as well as assisting in many areas of our product development cycle. His knowledge spans the entire range of Bitmovin products, features and solutions.


Related Posts

- Bitmovin
Developers

Open-Source vs. Commercial Players: Understanding the True Cost of Ownership

Join the conversation