devine-dl / pywidevine

Python implementation of Google's Widevine DRM CDM (Content Decryption Module)
GNU General Public License v3.0
535 stars 118 forks source link

Add opportunity to generate pssh with default_KID only #34

Closed Haxe18 closed 1 year ago

Haxe18 commented 1 year ago

First of all thanks for this awesome project and your work.

I am working with some mpd files which only contains a default_KID. A PSSH for Widevine/Playready is not given.

      <ContentProtection
        schemeIdUri="urn:mpeg:dash:mp4protection:2011"
        value="cenc"
        cenc:default_KID="79F8D3B2-3E0B-D27E-09E0-38435167AE13">
      </ContentProtection>

      <!-- Common Encryption -->
      <ContentProtection
        schemeIdUri="urn:mpeg:dash:mp4protection:2011"
        value="cenc"
        cenc:default_KID="2E7F8229-C1C6-012D-3BAF-8778CBA29C69">
      </ContentProtection>

In the shaka-project there is a fuction to generate a widevine pssh Box only by default_KID's: https://github.com/shaka-project/shaka-packager/blob/main/packager/tools/pssh/pssh-box.py#L171 The needed proto file is located here: https://github.com/shaka-project/shaka-packager/blob/main/packager/media/base/widevine_pssh_data.proto

I am using it now like this in combination with your project:

    widevine_key_video = "79F8D3B2-3E0B-D27E-09E0-38435167AE13"
    widevine_key_audio = "2E7F8229-C1C6-012D-3BAF-8778CBA29C69"

    def generate_pssh(self):
        import base64
        import struct
        import widevine_pssh_data_pb2 as widevine_pssh_data_pb2
        from pywidevine.pssh import PSSH

        wv = widevine_pssh_data_pb2.WidevinePsshData()
        wv.key_id.extend([base64.b16decode(widevine_key_video).replace('-','')])
        wv.key_id.extend([base64.b16decode(widevine_key_audio).replace('-','')])
        # 'cenc' is the default, so omitted to save bytes.
        wv.protection_scheme = struct.unpack('>L', 'cenc'.encode())[0]
        pssh_box = base64.b64encode(wv.SerializeToString()).decode("utf-8")

        pssh = PSSH(pssh_box)

        return pssh.dumps()

Is it be possible to implement the option to generate a pssh only by default_KID's into pywidevine ?

Thanks in advance.

rlaphoenix commented 1 year ago

This is already possible:

from uuid import UUID

from pywidevine import PSSH

pssh = PSSH.new(
    key_ids=[
        UUID("79F8D3B2-3E0B-D27E-09E0-38435167AE13"),
        UUID("2E7F8229-C1C6-012D-3BAF-8778CBA29C69")
    ],
    system_id=PSSH.SystemId.Widevine
)
Haxe18 commented 1 year ago

Works as expected with less code 😅 Thanks for the hint. Issue can be closed.