VideoHelp Forum




+ Reply to Thread
Results 1 to 5 of 5
  1. Hello, the get_pssh(mpd_url) found in some script never worked for me, so this is n00b's way (noob in python) :

    Code:
    import urllib.request
    
    mpd_url = input("\nInput mpd url: ")
    print("")
    
    try:
        mpd = urllib.request.urlopen(mpd_url)
        print('[+] Retrieving mpd file')
        print("")
        mpd_content = mpd.read().decode("utf-8")
        Balise_A, Balise_B = mpd_content.find('<cenc:pssh>'), mpd_content.find('</cenc:pssh>')
        pssh = mpd_content[Balise_A+11:Balise_B]
    except Exception as e:
        print(f"[-] couldn't retrive mpd file.\n\terror: {e}")
        exit()
    No need of parsing xml brows tree etc. ...
    It presume's that all encoded streams have the same pssh.

    Et voilą
    Quote Quote  
  2. Sorry to be a spoiler, but this method won't reliably work if the mpd contains PSSH's for multiple content protection systems like PlayReady.

    There is a reason why you'd usually want to parse the mpd content. You should at least check that you got a Widevine PSSH...

    The easiest probably is to search for
    Code:
    <cenc:pssh>AAAA
    or (imo even simpler) use a regex like:

    Code:
    import re
    m = re.search("<cenc:pssh>(?P<pssh>AAAA.+)</cenc:pssh>", mpd_content)
    print(m['pssh'])
    Last edited by Obo; 9th Feb 2024 at 09:54.
    Quote Quote  
  3. Search, Learn, Download! Karoolus's Avatar
    Join Date
    Oct 2022
    Location
    Belgium
    Search Comp PM
    Sorry to be even spoilier (is that even a word?) but what if there is no PSSH in the MPD?

    In that case you're better off getting the PSSH from the init file. There's a python code floating around this forum to get that done.
    Quote Quote  
  4. (Deepl means: yes, exists; but has a different meaning )

    For the record, here is a slightly modified version of the script you mentioned:

    Code:
    import sys
    from pywidevine import PSSH
    
    def find_wv_pssh_offsets(raw: bytes) -> list:
        offsets = []
        offset = 0
        while True:
            offset = raw.find(b'pssh', offset)
            if offset == -1:
                break
            size = int.from_bytes(raw[offset-4:offset], byteorder='big')
            pssh_offset = offset - 4
            offsets.append(raw[pssh_offset:pssh_offset+size])
            offset += size
        return offsets
    
    def to_pssh(content: bytes) -> list:
        wv_offsets = find_wv_pssh_offsets(content)
        return [base64.b64encode(wv_offset).decode() for wv_offset in wv_offsets]
    
    def from_file(file_path: str) -> list:
        with open(file_path, 'rb') as f:
            buffer = f.read(1_048_576)
        return to_pssh(buffer)
    
    pssh_list = from_file(sys.argv[1])
    target_pssh = None
    for item in pssh_list:
        pssh = PSSH(item)
        if pssh.system_id == PSSH.SystemId.Widevine:
            print(pssh)
    Last edited by Obo; 9th Feb 2024 at 11:36.
    Quote Quote  
  5. lol I told you that it is the n00b way, and it works for me for a simple mpd file with the same pssh for all encrypted streams.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!