Search code examples
wrapperlicensingmpeg-dashdrmwidevine

how to Wrapping License Requests to drmtoday server via python


i'm trying to simulate drm media playing in python so i start with this demo from castlab "https://demo.castlabs.com/" and the video that i'm testing it is in MPEG-DASH format and drm system is widevine provided via cenc (if is that how to say it) , here is the url of the video

https://demo.cf.castlabs.com/media/msspr/Manifest?v=5.1.38

key id is :

8bdf77c0-5665-46c5-8ec8-422e571fc000

and the pssh is :

AAAAVHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADQIARIQi993wFZlRsWOyEIuVx/AABoIY2FzdGxhYnMiEIvfd8BWZUbFjshCLlcfwAAqAlNE

schemeIdUri (widevine) is :

edef8ba9-79d6-4ace-a3c8-27dcd51d21ed

and the drm server url :

https://lic.staging.drmtoday.com/license-proxy-widevine/cenc/

the drm server need an custom header witch is :

dt-custom-data: eyJ1c2VySWQiOiJwdXJjaGFzZSIsInNlc3Npb25JZCI6InAwIiwibWVyY2hhbnQiOiJzaXgifQ==

and never change its base64 encoded from :

{"userId":"purchase","sessionId":"p0","merchant":"six"}

and it also need the body request or payload request , and thats where my problem is i was able to catch the body request in arraybuffer from chrom developer tool and converted to base64 an this is what i find

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

i really don't know how this code was formed i know that it converted to arraybuffer "Unit8 and "int8" and used as body request to the server , i coped this base64 code and try to decoded in this site "https://tools.axinom.com/decoders/LicenseRequest" and it give me information about the license request like Certificate and Serial Number and the signature plus the pssh data and content id , algorithm (AES-CTR) now since most of the information that are stored in that base64 code are in my hand (pssh,kid,system id), i want to know how to create\build\wrapper the request in the same way that base64 code was build to use it in python


Solution

  • The request is generated by interacting with the CDM in the browser via the EME API: https://w3c.github.io/encrypted-media/. You can learn more by using this: https://chrome.google.com/webstore/detail/eme-call-and-event-logger/cniohcjecdcdhgmlofniddfoeokbpbpb

    Maybe this helps to call Chromium from Python: Python - how to load Google Chrome or Chromium browser in the gtk.Window like webkit.WebView()?

    You would also need to take care to enable Widevine in CEF, and there might be limitations associated with that because of some signature verification process. See https://bitbucket.org/chromiumembedded/cef/src/master/include/cef_web_plugin.h#lines-168 and look for "VMP" here: https://github.com/castlabs/electron-releases