EZDRM
Using CPIX
The base CPIX request URL for EZDRM is the following:
https://cpix.ezdrm.com/keygenerator/cpix.aspx
To make a request query parameters are used to specify what is actually required. An example with parameters:
https://cpix.ezdrm.com/KeyGenerator/cpix.aspx?k=KeyID&u=USERNAME&p=PASSWORD&c=RESOURCENAME
The following is the CPIX document returned for the test URL above (query parameter values are defined in the next paragraph):
<cpix:CPIX id="1"
xmlns:cpix="urn:dashif:org:cpix"
xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc">
<cpix:ContentKeyList>
<cpix:ContentKey kid="77794df2-1783-4d59-bad7-80ea909a99b6" explicitIV="d3lN8heDTVm614DqkJqZtg==">
<cpix:Data>
<pskc:Secret>
<pskc:PlainValue>7sigIvU2BT2kwdkspVcNrQ==</pskc:PlainValue>
</pskc:Secret>
</cpix:Data>
</cpix:ContentKey>
</cpix:ContentKeyList>
<cpix:DRMSystemList>
<cpix:DRMSystem kid="77794df2-1783-4d59-bad7-80ea909a99b6" systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
<cpix:PSSH>AAAAdnBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAFYIARIQd3lN8heDTVm614DqkJqZthoIbW92aWRvbmUiMnsia2lkIjoiZDNsTjhoZURUVm02MTREcWtKcVp0Zz09IiwidHJhY2tzIjpbIlNEIl19KgJTRA==</cpix:PSSH>
</cpix:DRMSystem>
<cpix:DRMSystem kid="77794df2-1783-4d59-bad7-80ea909a99b6" systemId="9a04f079-9840-4286-ab92-e65be0885f95">
<cpix:PSSH>AAADBnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAubmAgAAAQABANwCPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgA4AGsAMQA1AGQANABNAFgAVwBVADIANgAxADQARABxAGsASgBxAFoAdABnAD0APQA8AC8ASwBJAEQAPgA8AEwAQQBfAFUAUgBMAD4AaAB0AHQAcABzADoALwAvAHAAbABhAHkAcgBlAGEAZAB5AC4AZQB6AGQAcgBtAC4AYwBvAG0ALwBjAGUAbgBjAHkALwBwAHIAZQBhAHUAdABoAC4AYQBzAHAAeAA/AHAAWAA9AEUAMAAxADgAMwBGADwALwBMAEEAXwBVAFIATAA+ADwARABTAF8ASQBEAD4AVgBsAFIANwBJAGQAcwBJAEoARQB1AFIAZAAwADYATABhAHEAcwAyAGoAdwA9AD0APAAvAEQAUwBfAEkARAA+ADwAQwBIAEUAQwBLAFMAVQBNAD4AcwBXAGMARABtAEIASwAwAHoAdgBjAD0APAAvAEMASABFAEMASwBTAFUATQA+ADwALwBEAEEAVABBAD4APAAvAFcAUgBNAEgARQBBAEQARQBSAD4A</cpix:PSSH>
<cpix:ContentProtectionData>PG1zcHI6cHJvIHhtbG5zOm1zcHI9InVybjptaWNyb3NvZnQ6cGxheXJlYWR5Ij41Z0lBQUFFQUFRRGNBandBVndCU0FFMEFTQUJGQUVFQVJBQkZBRklBSUFCNEFHMEFiQUJ1QUhNQVBRQWlBR2dBZEFCMEFIQUFPZ0F2QUM4QWN3QmpBR2dBWlFCdEFHRUFjd0F1QUcwQWFRQmpBSElBYndCekFHOEFaZ0IwQUM0QVl3QnZBRzBBTHdCRUFGSUFUUUF2QURJQU1BQXdBRGNBTHdBd0FETUFMd0JRQUd3QVlRQjVBRklBWlFCaEFHUUFlUUJJQUdVQVlRQmtBR1VBY2dBaUFDQUFkZ0JsQUhJQWN3QnBBRzhBYmdBOUFDSUFOQUF1QURBQUxnQXdBQzRBTUFBaUFENEFQQUJFQUVFQVZBQkJBRDRBUEFCUUFGSUFUd0JVQUVVQVF3QlVBRWtBVGdCR0FFOEFQZ0E4QUVzQVJRQlpBRXdBUlFCT0FENEFNUUEyQUR3QUx3QkxBRVVBV1FCTUFFVUFUZ0ErQUR3QVFRQk1BRWNBU1FCRUFENEFRUUJGQUZNQVF3QlVBRklBUEFBdkFFRUFUQUJIQUVrQVJBQStBRHdBTHdCUUFGSUFUd0JVQUVVQVF3QlVBRWtBVGdCR0FFOEFQZ0E4QUVzQVNRQkVBRDRBT0FCckFERUFOUUJrQURRQVRRQllBRmNBVlFBeUFEWUFNUUEwQUVRQWNRQnJBRW9BY1FCYUFIUUFad0E5QUQwQVBBQXZBRXNBU1FCRUFENEFQQUJNQUVFQVh3QlZBRklBVEFBK0FHZ0FkQUIwQUhBQWN3QTZBQzhBTHdCd0FHd0FZUUI1QUhJQVpRQmhBR1FBZVFBdUFHVUFlZ0JrQUhJQWJRQXVBR01BYndCdEFDOEFZd0JsQUc0QVl3QjVBQzhBY0FCeUFHVUFZUUIxQUhRQWFBQXVBR0VBY3dCd0FIZ0FQd0J3QUZnQVBRQkZBREFBTVFBNEFETUFSZ0E4QUM4QVRBQkJBRjhBVlFCU0FFd0FQZ0E4QUVRQVV3QmZBRWtBUkFBK0FGWUFiQUJTQURjQVNRQmtBSE1BU1FCS0FFVUFkUUJTQUdRQU1BQTJBRXdBWVFCeEFITUFNZ0JxQUhjQVBRQTlBRHdBTHdCRUFGTUFYd0JKQUVRQVBnQThBRU1BU0FCRkFFTUFTd0JUQUZVQVRRQStBSE1BVndCakFFUUFiUUJDQUVzQU1BQjZBSFlBWXdBOUFEd0FMd0JEQUVnQVJRQkRBRXNBVXdCVkFFMEFQZ0E4QUM4QVJBQkJBRlFBUVFBK0FEd0FMd0JYQUZJQVRRQklBRVVBUVFCRUFFVUFVZ0ErQUE9PTwvbXNwcjpwcm8+</cpix:ContentProtectionData>
</cpix:DRMSystem>
<cpix:DRMSystem kid="77794df2-1783-4d59-bad7-80ea909a99b6" systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
<cpix:URIExtXKey>c2tkOi8vZnBzLmV6ZHJtLmNvbS87Nzc3OTRkZjItMTc4My00ZDU5LWJhZDctODBlYTkwOWE5OWI2</cpix:URIExtXKey>
</cpix:DRMSystem>
<cpix:DRMSystem kid="77794df2-1783-4d59-bad7-80ea909a99b6" systemId="3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c">
<cpix:PSSH>AAAAq3Bzc2gAAAAAPV5tNZuaQei4Q908bnLELAAAAIt7ImNvbnRlbnRJRCI6IlpETnNUamhvWlVSVVZtMDJNVFJFY1d0S2NWcDBaejA5IiwiZW5zY2hlbWEiOiJDRU5DIiwia2lkcyI6WyJOemMzT1RSa1pqSXhOemd6TkdRMU9XSmhaRGM0TUdWaE9UQTVZVGs1WWpZPSJdLCJ2ZXJzaW9uIjoiVjEuMCJ9</cpix:PSSH>
<cpix:ContentProtectionData></cpix:ContentProtectionData>
</cpix:DRMSystem>
</cpix:DRMSystemList>
</cpix:CPIX>
~
The following query parameters can be used:
Parameter |
Description |
---|---|
k= |
Key ID value (client generated) in GUID format |
u= |
Username |
p= |
password |
c= |
Content Resource ID (such as a stream name or media asset name) |
'm' value not provided |
Default (returns all available keys) |
m=1 |
MPEG_DASH (PlayReady and Widevine) |
m=2 |
HLS (FairPlay) |
For further details on the EZDRM CPIX API please consult the EZDRM documentation.
The resulting CPIX document then can be used as outlined in Content Protection Information eXchange (CPIX).
Adding WisePlay DRM
Support for WisePlay (by Huawei) is also achieved by calling the API for a CPIX document:
#!/bin/bash
curl -v https://eu-dev.ezdrm.com/keygenerator/cpix.aspx?k=77794df2-1783-4d59-bad7-80ea909a99b6&u=USERNAME&p=PASSWORD&c=1 > wiseplay.cpix
The returned document looks for instance like the following:
<?xml version='1.0' encoding='utf-8'?>
<CPIX xmlns="urn:dashif:org:cpix" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc" xsi:schemaLocation="urn:dashif:org:cpix cpix.xsd">
<ContentKeyList>
<ContentKey kid="77794df2-1783-4d59-bad7-80ea909a99b6" commonEncryptionScheme="cenc">
<Data>
<pskc:Secret>
<pskc:PlainValue>7sigIvU2BT2kwdkspVcNrQ==</pskc:PlainValue>
</pskc:Secret>
</Data>
</ContentKey>
</ContentKeyList>
<DRMSystemList>
<DRMSystem kid="77794df2-1783-4d59-bad7-80ea909a99b6" systemId="3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c">
<PSSH>AAAAq3Bzc2gAAAAAPV5tNZuaQei4Q908bnLELAAAAIt7ImNvbnRlbnRJRCI6IlpETnNUamhvWlVSVVZtMDJNVFJFY1d0S2NWcDBaejA5IiwiZW5zY2hlbWEiOiJDRU5DIiwia2lkcyI6WyJOemMzT1RSa1pqSXhOemd6TkdRMU9XSmhaRGM0TUdWaE9UQTVZVGs1WWpZPSJdLCJ2ZXJzaW9uIjoiVjEuMCJ9</PSSH>
<ContentProtectionData />
</DRMSystem>
</DRMSystemList>
</CPIX>
Note
Please note that the systemId
used is the same as 'ChinaDRM'.
The resulting CPIX document then can be used as outlined in Content Protection Information eXchange (CPIX), for instance:
#!/bin/bash
mp4split -o wiseplay.ism \
--mpd.cpix=wiseplay.cpix \
test.mp4
Attention
WisePlay is only available for MPEG-DASH.
Note
The following section outlines the pre-CPIX APIs.
Adding FairPlay DRM
Using EZDRM's web service, the bash script below retrieves the Adding FairPlay DRM values from the web service and then adds it to the mp4split command to create a server manifest.
The U
and P
values should be replaced with your credentials (username
and password).
#!/bin/bash
resp=`curl -X POST -v 'http://fps.ezdrm.com/api/keys?U=USERNAME&P=PASSWORD' -d ''`
cek16=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//KeyHEX").text)'`
mp4split -o fairplay.ism \
--hls.key=:${cek16:0:32} \
--hls.key_iv=${cek16:32:32} \
--hls.playout=sample_aes_streamingkeydelivery
test.mp4
Please note how the KeyHEX value is split into content key (the first 16 bytes) and key_iv (the second 16 bytes): the key_iv is not listed in the playlist but it is a value shared between encryption and playout. The player will receive it as part of the key request.
Adding PlayReady (CENC)
Using EZDRM's web service, the bash script below retrieves the Widevine specific data from the web service and then adds it to the mp4split command to create a server manifest.
The U
and P
values should be replaced with your credentials (username
and password).
#!/bin/bash
resp=`curl -s 'http://wvm.ezdrm.com/ws/LicenseInfo.asmx/GenerateKeys?U=USERNAME&P=PASSWORD&C=""'`
cek=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//PlayReady/KeyHEX").text)'`
kid=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//WideVine/KeyIDHEX").text)'`
laurl=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//PlayReady/LAURL").text)'`
mp4split -o playready.ism \
--iss.key=${kid}:${cek} \
--iss.license_server_url=${laurl} \
test.mp4
Adding PlayReady (PIFF)
Using EZDRM's web service, the bash script below retrieves the PlayReady specific data from the web service and then adds it to the mp4split command to create a server manifest.
Please note this for HSS/PIFF, not DASH/CENC - see below for multi DRM CENC.
The U
and P
values should be replaced with your credentials (username
and password).
#!/bin/bash
resp=`curl -s 'http://wvm.ezdrm.com/ws/LicenseInfo.asmx/GenerateKeys?U=USERNAME&P=PASSWORD&C="")'`
cek16=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//PlayReady/KeyHEX").text)'`
kid=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//PlayReady/KeyIDGUID").text)'`
laurl=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//PlayReady/LAURL").text)'`
# Service returns as GUID so convert to UUID
kid16=`python3 -c "exec(\"import uuid,base64; print(base64.b16encode(uuid.UUID(base64.b16encode(uuid.UUID('$kid').bytes_le)).bytes);\")";`
mp4split -o playready.ism \
--iss.key=${kid16}:${cek16} \
--iss.license_server_url=${laurl} \
test.mp4
Adding Widevine (CENC)
Using EZDRM's web service, the bash script below retrieves the Widevine specific data from the web service and then adds it to the mp4split command to create a server manifest.
The U
and P
values should be replaced with your credentials (username
and password).
#!/bin/bash
resp=`curl -s 'http://wvm.ezdrm.com/ws/LicenseInfo.asmx/GenerateKeys?U=USERNAME&P=PASSWORD&C="")'`
cek=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//WideVine/KeyHEX").text)'`
kid=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//WideVine/KeyIDHEX").text)'`
pssh=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//WideVine/PSSH").text)'`
laurl=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//WideVine/ServerURL").text)'`
mp4split -o widevine.ism \
--widevine.key=${kid}:${cek} \
--widevine.drm_specific_data=${pssh} \
test.mp4
Using CENC multi DRM
The combination of PlayReady and Widevine as CENC multi DRM is supported as well, in this setup a single key id and content key combination is valid for both PlayReady and Widevine: Common Encryption.
The U
and P
values should be replaced with your credentials (username
and password).
To use this you would need to combine the CENC options as described above, e.g.
#!/bin/bash
resp=`curl -s 'http://wvm.ezdrm.com/ws/LicenseInfo.asmx/GenerateKeys?U=USERNAME&P=PASSWORD&C=""'`
cek=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//WideVine/KeyHEX").text)'`
kid=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//WideVine/KeyIDHEX").text)'`
laurl=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//PlayReady/LAURL").text)'`
pssh=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//WideVine/PSSH").text)'`
serverurl=`echo $resp | python3 -c 'import sys, xml.etree.cElementTree as et; tree = et.parse(sys.stdin); print(tree.find(".//WideVine/ServerURL").text)'`
mp4split -o playready.ism \
--iss.key=${kid}:${cek} \
--iss.license_server_url=${laurl} \
--widevine.key=${kid}:${cek} \
--widevine.drm_specific_data=${pssh} \
test.mp4