devine-dl/pywidevine

Error while using pssh.dumps() on some PSSH

Closed this issue · 2 comments

Describe the bug
Error while using .dumps() on some PSSH, for testing used: https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd (AAAARHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAACQIARIBNRoNd2lkZXZpbmVfdGVzdCIKMjAxNV90ZWFycyoCU0Q=), this is only video with that problem as far as I tested

To Reproduce
Steps to reproduce the behavior:

  1. Install pywidevine
  2. Create basic script
from pywidevine.pssh import PSSH

# https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd

pssh = PSSH('AAAARHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAACQIARIBNRoNd2lkZXZpbmVfdGVzdCIKMjAxNV90ZWFycyoCU0Q=')

print(pssh.dumps())
  1. Run it
  2. See error.

Expected behavior
pssh.dumps() works fine

Additional context

Traceback (most recent call last):
  File "test\pssh.py", line 8, in <module>
    print(pssh.dumps())
  File "lib\site-packages\pywidevine\pssh.py", line 240, in dumps     
    return base64.b64encode(self.dump()).decode()
  File "lib\site-packages\pywidevine\pssh.py", line 234, in dump      
    key_IDs=self.key_ids,
  File "lib\site-packages\pywidevine\pssh.py", line 200, in key_ids   
    return [
  File "lib\site-packages\pywidevine\pssh.py", line 202, in <listcomp>
    UUID(bytes=key_id) if len(key_id) == 16 else UUID(hex=key_id.decode())
  File "lib\uuid.py", line 177, in __init__
    raise ValueError('badly formed hexadecimal UUID string')
ValueError: badly formed hexadecimal UUID string

The value within the key_IDs field of the PSSH is non-conformative. It's meant to be a 16-byte value to be represented as a UUID, but is instead just a 1-byte value, a number. I presume a track or testing mpd ID number.

This is somewhat problematic to deal with cases like this as the rest of the code has to assume it as a 16-byte value once parsed. I could pad it to a 16-byte value before parsing. Thanks for the report I will work on this soon.

As of the commit linked, any Key ID that is not 16 bytes will be assumed to be a number and will load in big-endian order. For the provided example MPD's PSSH, it will come out as:

>>> pssh = PSSH('AAAARHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAACQIARIBNRoNd2lkZXZpbmVfdGVzdCIKMjAxNV90ZWFycyoCU0Q=')
<pywidevine.pssh.PSSH object at 0x000002D176DBB760>
>>> pssh.key_ids
[UUID('00000000-0000-0000-0000-000000000035')]