PSSH: Fix loading of PlayReadyHeaders
Previously it would load PlayReadyHeader data under Widevine's SystemId breaking all PlayReady checks. The actual PlayReadyHeader init_data still needs code to parse it into an object.
This commit is contained in:
parent
e31ba61302
commit
3a910bd03a
|
@ -24,13 +24,19 @@ class PSSH:
|
||||||
|
|
||||||
def __init__(self, data: Union[Container, str, bytes], strict: bool = False):
|
def __init__(self, data: Union[Container, str, bytes], strict: bool = False):
|
||||||
"""
|
"""
|
||||||
Load a PSSH box or Widevine Cenc Header data as a new v0 PSSH box.
|
Load a PSSH box, WidevineCencHeader, or PlayReadyHeader.
|
||||||
|
|
||||||
|
When loading a WidevineCencHeader or PlayReadyHeader, a new v0 PSSH box will be
|
||||||
|
created and the header will be parsed and stored in the init_data field. However,
|
||||||
|
PlayReadyHeaders (and PlayReadyObjects) are not yet currently parsed and are
|
||||||
|
stored as bytes.
|
||||||
|
|
||||||
[Strict mode (strict=True)]
|
[Strict mode (strict=True)]
|
||||||
|
|
||||||
Supports the following forms of input data in either Base64 or Bytes form:
|
Supports the following forms of input data in either Base64 or Bytes form:
|
||||||
- Full PSSH mp4 boxes (as defined by pymp4 Box).
|
- Full PSSH mp4 boxes (as defined by pymp4 Box).
|
||||||
- Full Widevine Cenc Headers (as defined by WidevinePsshData proto).
|
- Full Widevine Cenc Headers (as defined by WidevinePsshData proto).
|
||||||
|
- Full PlayReady Objects and Headers (as defined by Microsoft Docs).
|
||||||
|
|
||||||
[Lenient mode (strict=False, default)]
|
[Lenient mode (strict=False, default)]
|
||||||
|
|
||||||
|
@ -77,21 +83,36 @@ class PSSH:
|
||||||
cenc_header = cenc_header.SerializeToString()
|
cenc_header = cenc_header.SerializeToString()
|
||||||
if cenc_header != data: # not actually a WidevinePsshData
|
if cenc_header != data: # not actually a WidevinePsshData
|
||||||
raise DecodeError()
|
raise DecodeError()
|
||||||
|
box = Box.parse(Box.build(dict(
|
||||||
|
type=b"pssh",
|
||||||
|
version=0,
|
||||||
|
flags=0,
|
||||||
|
system_ID=PSSH.SystemId.Widevine,
|
||||||
|
init_data=cenc_header
|
||||||
|
)))
|
||||||
except DecodeError: # not a widevine cenc header
|
except DecodeError: # not a widevine cenc header
|
||||||
if strict:
|
if "</WRMHEADER>".encode("utf-16-le") in data:
|
||||||
|
# TODO: Actually parse `data` as a PlayReadyHeader object and store that instead
|
||||||
|
box = Box.parse(Box.build(dict(
|
||||||
|
type=b"pssh",
|
||||||
|
version=0,
|
||||||
|
flags=0,
|
||||||
|
system_ID=PSSH.SystemId.PlayReady,
|
||||||
|
init_data=data
|
||||||
|
)))
|
||||||
|
elif strict:
|
||||||
raise DecodeError(f"Could not parse data as a {Container} nor a {WidevinePsshData}.")
|
raise DecodeError(f"Could not parse data as a {Container} nor a {WidevinePsshData}.")
|
||||||
# Data is not a Widevine Cenc Header, it's something custom.
|
else:
|
||||||
# The license server likely has something custom to parse it.
|
# Data is not a WidevineCencHeader nor a PlayReadyHeader.
|
||||||
# See doc-string about Lenient mode for more information.
|
# The license server likely has something custom to parse it.
|
||||||
cenc_header = data
|
# See doc-string about Lenient mode for more information.
|
||||||
|
box = Box.parse(Box.build(dict(
|
||||||
box = Box.parse(Box.build(dict(
|
type=b"pssh",
|
||||||
type=b"pssh",
|
version=0,
|
||||||
version=0,
|
flags=0,
|
||||||
flags=0,
|
system_ID=PSSH.SystemId.Widevine,
|
||||||
system_ID=PSSH.SystemId.Widevine,
|
init_data=data
|
||||||
init_data=cenc_header
|
)))
|
||||||
)))
|
|
||||||
|
|
||||||
self.version = box.version
|
self.version = box.version
|
||||||
self.flags = box.flags
|
self.flags = box.flags
|
||||||
|
|
Loading…
Reference in New Issue