diff --git a/binaries/ffmpeg-6.1.1-essentials_build.7z b/binaries/ffmpeg-6.1.1-essentials_build.7z deleted file mode 100644 index 5415cbf..0000000 Binary files a/binaries/ffmpeg-6.1.1-essentials_build.7z and /dev/null differ diff --git a/pyproject.toml b/pyproject.toml index ee96213..ffd691d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ authors = [] [tool.poetry.dependencies] python = "^3.9" appdirs = "^1.4.4" -beautifulsoup4 = "~4.11.2" +beautifulsoup4 = "^4.8.2" click = "^8.0.1" cffi = "^1.16.0" coloredlogs = "^15.0" diff --git a/scripts/subby/pyproject.toml b/scripts/subby/pyproject.toml index 28db507..22bcb23 100644 --- a/scripts/subby/pyproject.toml +++ b/scripts/subby/pyproject.toml @@ -10,7 +10,7 @@ repository = "https://github.com/vevv/subby" [tool.poetry.dependencies] python = "^3.8" pymp4 = "~1.4.0" -beautifulsoup4 = "^4.11.2" +beautifulsoup4 = "^4.8.2" tinycss = "^0.4" click = "^8.1.3" srt = "^3.5.3" diff --git a/vinetrimmer/key_store.db b/vinetrimmer/key_store.db index 7bd7f3b..7d8b988 100644 Binary files a/vinetrimmer/key_store.db and b/vinetrimmer/key_store.db differ diff --git a/vinetrimmer/objects/tracks.py b/vinetrimmer/objects/tracks.py index 65c838c..e2ceec2 100644 --- a/vinetrimmer/objects/tracks.py +++ b/vinetrimmer/objects/tracks.py @@ -8,6 +8,7 @@ import shutil import subprocess import sys import uuid +import xmltodict from collections import defaultdict from enum import Enum from io import BytesIO, TextIOWrapper @@ -187,24 +188,25 @@ class Track: break # Below converts PlayReady PSSH to WideVine PSSH try: - xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore") - xml_str = xml_str[xml_str.index("<"):] - xml = load_xml(xml_str).find("DATA") # root: WRMHEADER + if self.psshPR: + xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore") + xml_str = xml_str[xml_str.index("<"):] + xml = load_xml(xml_str).find("DATA") # root: WRMHEADER - kid = xml.findtext("KID") # v4.0.0.0 - if not kid: # v4.1.0.0 - kid = next(iter(xml.xpath("PROTECTINFO/KID/@VALUE")), None) - if not kid: # v4.3.0.0 - 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() - if not track.psshWV: - self.psshWV = Box.parse(Box.build(dict( - type=b"pssh", - version=0, - flags=0, - system_ID="9a04f079-9840-4286-ab92-e65be0885f95", - init_data=b"\x12\x10" + base64.b64decode(kid) - ))) + kid = xml.findtext("KID") # v4.0.0.0 + if not kid: # v4.1.0.0 + kid = next(iter(xml.xpath("PROTECTINFO/KID/@VALUE")), None) + if not kid: # v4.3.0.0 + 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() + #if not track.psshWV: + # self.psshWV = Box.parse(Box.build(dict( + # type=b"pssh", + # version=0, + # flags=0, + # system_ID="9a04f079-9840-4286-ab92-e65be0885f95", + # init_data=b"\x12\x10" + base64.b64decode(kid) + # ))) return True except: pass @@ -223,31 +225,32 @@ class Track: automatically. """ if self.encrypted and self.source == "DSNP": - log = logging.getLogger("Tracks") - log.info("+ Replacing KID with correct track KID (DSNP workaround)") - if self.descriptor == self.Descriptor.M3U: - # if an m3u, try get from playlist - master = m3u8.loads((requests or session).get(as_list(self.url)[0]).text, uri=self.url) - for x in master.session_keys: - if x and x.keyformat.lower == "com.microsoft.playready" and not self.psshPR: - self.psshPR = x.uri.split(",")[-1] - break - for x in master.keys: - if x and "com.microsoft.playready" in str(x) and not self.psshPR: - self.psshPR = str(x).split("\"")[1].split(",")[-1] - break + try: + log = logging.getLogger("Tracks") + log.info("+ Replacing KID with correct track KID (DSNP workaround)") + xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore") + xml_str = xml_str[xml_str.index("<"):] + 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 self.kid: + kids.remove(self.kid) + self.kid = kids[-1] + except: + raise log.exit("Failed To Replace Correct KID for DSNP") - xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore") - xml_str = xml_str[xml_str.index("<"):] - xml = load_xml(xml_str).find("DATA") # root: WRMHEADER + elif self.source != "DSNP" and self.psshPR: + xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore") + 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 - if not self.kid: # v4.1.0.0 - self.kid = next(iter(xml.xpath("PROTECTINFO/KID/@VALUE")), None) - if not self.kid: # v4.3.0.0 - self.kid = next(iter(xml.xpath("PROTECTINFO/KIDS/KID/@VALUE")), None) # can be multiple? + self.kid = xml.findtext("KID") # v4.0.0.0 + if not self.kid: # v4.1.0.0 + self.kid = next(iter(xml.xpath("PROTECTINFO/KID/@VALUE")), None) + if not self.kid: # v4.3.0.0 + 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": self.kid = "{}{}{}".format(