Fix for DSNP incorrect kid

This commit is contained in:
chu23465 2025-04-16 13:51:04 +05:30
parent 11108223bc
commit e1aeee8d36
5 changed files with 44 additions and 41 deletions

View File

@ -11,7 +11,7 @@ authors = []
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.9" python = "^3.9"
appdirs = "^1.4.4" appdirs = "^1.4.4"
beautifulsoup4 = "~4.11.2" beautifulsoup4 = "^4.8.2"
click = "^8.0.1" click = "^8.0.1"
cffi = "^1.16.0" cffi = "^1.16.0"
coloredlogs = "^15.0" coloredlogs = "^15.0"

View File

@ -10,7 +10,7 @@ repository = "https://github.com/vevv/subby"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.8" python = "^3.8"
pymp4 = "~1.4.0" pymp4 = "~1.4.0"
beautifulsoup4 = "^4.11.2" beautifulsoup4 = "^4.8.2"
tinycss = "^0.4" tinycss = "^0.4"
click = "^8.1.3" click = "^8.1.3"
srt = "^3.5.3" srt = "^3.5.3"

Binary file not shown.

View File

@ -8,6 +8,7 @@ import shutil
import subprocess import subprocess
import sys import sys
import uuid import uuid
import xmltodict
from collections import defaultdict from collections import defaultdict
from enum import Enum from enum import Enum
from io import BytesIO, TextIOWrapper from io import BytesIO, TextIOWrapper
@ -187,24 +188,25 @@ class Track:
break break
# Below converts PlayReady PSSH to WideVine PSSH # Below converts PlayReady PSSH to WideVine PSSH
try: try:
xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore") if self.psshPR:
xml_str = xml_str[xml_str.index("<"):] xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore")
xml = load_xml(xml_str).find("DATA") # root: WRMHEADER xml_str = xml_str[xml_str.index("<"):]
xml = load_xml(xml_str).find("DATA") # root: WRMHEADER
kid = xml.findtext("KID") # v4.0.0.0 kid = xml.findtext("KID") # v4.0.0.0
if not kid: # v4.1.0.0 if not kid: # v4.1.0.0
kid = next(iter(xml.xpath("PROTECTINFO/KID/@VALUE")), None) kid = next(iter(xml.xpath("PROTECTINFO/KID/@VALUE")), None)
if not kid: # v4.3.0.0 if not kid: # v4.3.0.0
kid = next(iter(xml.xpath("PROTECTINFO/KIDS/KID/@VALUE")), None) # can be multiple? kid = next(iter(xml.xpath("PROTECTINFO/KIDS/KID/@VALUE")), None) # can be multiple?
self.kid = uuid.UUID(base64.b64decode(self.kid).hex()).bytes_le.hex() self.kid = uuid.UUID(base64.b64decode(self.kid).hex()).bytes_le.hex()
if not track.psshWV: #if not track.psshWV:
self.psshWV = Box.parse(Box.build(dict( # self.psshWV = Box.parse(Box.build(dict(
type=b"pssh", # type=b"pssh",
version=0, # version=0,
flags=0, # flags=0,
system_ID="9a04f079-9840-4286-ab92-e65be0885f95", # system_ID="9a04f079-9840-4286-ab92-e65be0885f95",
init_data=b"\x12\x10" + base64.b64decode(kid) # init_data=b"\x12\x10" + base64.b64decode(kid)
))) # )))
return True return True
except: pass except: pass
@ -223,31 +225,32 @@ class Track:
automatically. automatically.
""" """
if self.encrypted and self.source == "DSNP": if self.encrypted and self.source == "DSNP":
log = logging.getLogger("Tracks") try:
log.info("+ Replacing KID with correct track KID (DSNP workaround)") log = logging.getLogger("Tracks")
if self.descriptor == self.Descriptor.M3U: log.info("+ Replacing KID with correct track KID (DSNP workaround)")
# if an m3u, try get from playlist xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore")
master = m3u8.loads((requests or session).get(as_list(self.url)[0]).text, uri=self.url) xml_str = xml_str[xml_str.index("<"):]
for x in master.session_keys: kids = [uuid.UUID(base64.b64decode(kid_xml['@VALUE']).hex()).bytes_le.hex() for kid_xml in xmltodict.parse(xml_str)['WRMHEADER']['DATA']['CUSTOMATTRIBUTES']['KIDS']['KID']]
if x and x.keyformat.lower == "com.microsoft.playready" and not self.psshPR: if self.kid:
self.psshPR = x.uri.split(",")[-1] kids.remove(self.kid)
break self.kid = kids[-1]
for x in master.keys: except:
if x and "com.microsoft.playready" in str(x) and not self.psshPR: raise log.exit("Failed To Replace Correct KID for DSNP")
self.psshPR = str(x).split("\"")[1].split(",")[-1]
break
xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore") elif self.source != "DSNP" and self.psshPR:
xml_str = xml_str[xml_str.index("<"):] xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore")
xml = load_xml(xml_str).find("DATA") # root: WRMHEADER xml_str = xml_str[xml_str.index("<"):]
xml = load_xml(xml_str).find("DATA") # root: WRMHEADER
self.kid = xml.findtext("KID") # v4.0.0.0 self.kid = xml.findtext("KID") # v4.0.0.0
if not self.kid: # v4.1.0.0 if not self.kid: # v4.1.0.0
self.kid = next(iter(xml.xpath("PROTECTINFO/KID/@VALUE")), None) self.kid = next(iter(xml.xpath("PROTECTINFO/KID/@VALUE")), None)
if not self.kid: # v4.3.0.0 if not self.kid: # v4.3.0.0
self.kid = next(iter(xml.xpath("PROTECTINFO/KIDS/KID/@VALUE")), None) # can be multiple? self.kid = next(iter(xml.xpath("PROTECTINFO/KIDS/KID/@VALUE")), None) # can be multiple?
if not self.kid:
raise
self.kid = uuid.UUID(base64.b64decode(self.kid).hex()).bytes_le.hex() self.kid = uuid.UUID(base64.b64decode(self.kid).hex()).bytes_le.hex()
if self.source == "NF": if self.source == "NF":
self.kid = "{}{}{}".format( self.kid = "{}{}{}".format(