mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-03-09 16:09:01 +00:00
fix(dash): handle placeholder KIDs and improve DRM init from segments
- Add CENC namespace support for kid/default_KID attributes - Detect and replace placeholder/test KIDs in Widevine PSSH: - All zeros (key rotation default) - Sequential 0x00-0x0f pattern - Shaka Packager test pattern - Change DRM init condition from `not track.drm` to `init_data` to ensure DRM is always re-initialized from init segments Fixes issue where Widevine PSSH contains placeholder KIDs while the real KID is only in ContentProtection default_KID attributes.
This commit is contained in:
@@ -466,7 +466,7 @@ class DASH:
|
|||||||
track.data["dash"]["timescale"] = int(segment_timescale)
|
track.data["dash"]["timescale"] = int(segment_timescale)
|
||||||
track.data["dash"]["segment_durations"] = segment_durations
|
track.data["dash"]["segment_durations"] = segment_durations
|
||||||
|
|
||||||
if not track.drm and isinstance(track, (Video, Audio)):
|
if init_data and isinstance(track, (Video, Audio)):
|
||||||
if isinstance(cdm, PlayReadyCdm):
|
if isinstance(cdm, PlayReadyCdm):
|
||||||
try:
|
try:
|
||||||
track.drm = [PlayReady.from_init_data(init_data)]
|
track.drm = [PlayReady.from_init_data(init_data)]
|
||||||
@@ -766,6 +766,11 @@ class DASH:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_drm(protections: list[Element]) -> list[DRM_T]:
|
def get_drm(protections: list[Element]) -> list[DRM_T]:
|
||||||
drm: list[DRM_T] = []
|
drm: list[DRM_T] = []
|
||||||
|
PLACEHOLDER_KIDS = {
|
||||||
|
UUID("00000000-0000-0000-0000-000000000000"), # All zeros (key rotation default)
|
||||||
|
UUID("00010203-0405-0607-0809-0a0b0c0d0e0f"), # Sequential 0x00-0x0f
|
||||||
|
UUID("00010203-0405-0607-0809-101112131415"), # Shaka Packager test pattern
|
||||||
|
}
|
||||||
|
|
||||||
for protection in protections:
|
for protection in protections:
|
||||||
urn = (protection.get("schemeIdUri") or "").lower()
|
urn = (protection.get("schemeIdUri") or "").lower()
|
||||||
@@ -775,17 +780,27 @@ class DASH:
|
|||||||
if not pssh_text:
|
if not pssh_text:
|
||||||
continue
|
continue
|
||||||
pssh = PSSH(pssh_text)
|
pssh = PSSH(pssh_text)
|
||||||
|
kid_attr = protection.get("kid") or protection.get("{urn:mpeg:cenc:2013}kid")
|
||||||
|
kid = UUID(bytes=base64.b64decode(kid_attr)) if kid_attr else None
|
||||||
|
|
||||||
kid = protection.get("kid")
|
if not kid:
|
||||||
if kid:
|
default_kid_attr = protection.get("default_KID") or protection.get(
|
||||||
kid = UUID(bytes=base64.b64decode(kid))
|
"{urn:mpeg:cenc:2013}default_KID"
|
||||||
|
)
|
||||||
|
kid = UUID(default_kid_attr) if default_kid_attr else None
|
||||||
|
|
||||||
default_kid = protection.get("default_KID")
|
if not kid:
|
||||||
if default_kid:
|
kid = next(
|
||||||
kid = UUID(default_kid)
|
(
|
||||||
|
UUID(p.get("default_KID") or p.get("{urn:mpeg:cenc:2013}default_KID"))
|
||||||
|
for p in protections
|
||||||
|
if p.get("default_KID") or p.get("{urn:mpeg:cenc:2013}default_KID")
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
|
||||||
if not pssh.key_ids and not kid:
|
if kid and (not pssh.key_ids or all(k.int == 0 or k in PLACEHOLDER_KIDS for k in pssh.key_ids)):
|
||||||
kid = next((UUID(p.get("default_KID")) for p in protections if p.get("default_KID")), None)
|
pssh.set_key_ids([kid])
|
||||||
|
|
||||||
drm.append(Widevine(pssh=pssh, kid=kid))
|
drm.append(Widevine(pssh=pssh, kid=kid))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user