diff --git a/README.md b/README.md index 11bec22..c298fc9 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,6 @@ Config file values can be overridden using command-line arguments. | `--temp-path` / `temp_path` | Path to temporary directory. | `temp` | | `--wvd-path` / `wvd_path` | Path to .wvd file. | `device.wvd` | | `--aria2c-path` / `aria2c_path` | Path to aria2c binary. | `aria2c` | -| `--unplayplay-path` / `unplayplay_path` | Path to unplayplay binary. | `unplayplay` | | `--ffmpeg-path` / `ffmpeg_path` | Path to ffmpeg binary. | `ffmpeg` | | `--mp4box-path` / `mp4box_path` | Path to MP4Box binary. | `mp4box` | | `--mp4decrypt-path` / `mp4decrypt_path` | Path to mp4decrypt binary. | `mp4decrypt` | diff --git a/pyproject.toml b/pyproject.toml index 50455b5..7e9a0df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ dependencies = [ "protobuf", "pybase62", "pycryptodome", + "re-unplayplay", "yt-dlp", ] readme = "README.md" diff --git a/requirements.txt b/requirements.txt index 04c93d3..5ffb21b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,5 @@ pillow protobuf pybase62 pycryptodome +re-unplayplay yt-dlp diff --git a/votify/cli.py b/votify/cli.py index 4c5f312..c748206 100644 --- a/votify/cli.py +++ b/votify/cli.py @@ -174,12 +174,6 @@ def load_config_file( default=downloader_sig.parameters["aria2c_path"].default, help="Path to aria2c binary.", ) -@click.option( - "--unplayplay-path", - type=str, - default=downloader_sig.parameters["unplayplay_path"].default, - help="Path to unplayplay binary.", -) @click.option( "--ffmpeg-path", type=str, @@ -362,7 +356,6 @@ def main( wvd_path: Path, download_mode: DownloadMode, aria2c_path: str, - unplayplay_path: str, ffmpeg_path: str, mp4box_path: str, mp4decrypt_path: str, @@ -403,7 +396,6 @@ def main( temp_path, wvd_path, aria2c_path, - unplayplay_path, ffmpeg_path, mp4box_path, mp4decrypt_path, @@ -485,12 +477,6 @@ def main( ) return downloader.set_cdm() - else: - if not downloader.unplayplay_path_full: - logger.critical( - X_NOT_FOUND_STRING.format("Unplayplay", unplayplay_path) - ) - return if download_mode == DownloadMode.ARIA2C and not downloader.aria2c_path_full: logger.critical(X_NOT_FOUND_STRING.format("aria2c", aria2c_path)) return diff --git a/votify/downloader.py b/votify/downloader.py index c616365..485584a 100644 --- a/votify/downloader.py +++ b/votify/downloader.py @@ -10,6 +10,7 @@ import subprocess from io import BytesIO from pathlib import Path +from re_unplayplay import decrypt_and_bind_key import requests from InquirerPy import inquirer from InquirerPy.base.control import Choice @@ -50,7 +51,6 @@ class Downloader: temp_path: Path = Path("./temp"), wvd_path: Path = Path("./device.wvd"), aria2c_path: str = "aria2c", - unplayplay_path: str = "unplayplay", ffmpeg_path: str = "ffmpeg", mp4box_path: str = "mp4box", mp4decrypt_path: str = "mp4decrypt", @@ -78,7 +78,6 @@ class Downloader: self.temp_path = temp_path self.wvd_path = wvd_path self.aria2c_path = aria2c_path - self.unplayplay_path = unplayplay_path self.ffmpeg_path = ffmpeg_path self.mp4box_path = mp4box_path self.mp4decrypt_path = mp4decrypt_path @@ -107,7 +106,6 @@ class Downloader: def _set_binaries_full_path(self): self.aria2c_path_full = shutil.which(self.aria2c_path) - self.unplayplay_path_full = shutil.which(self.unplayplay_path) self.ffmpeg_path_full = shutil.which(self.ffmpeg_path) self.mp4box_path_full = shutil.which(self.mp4box_path) self.mp4decrypt_path_full = shutil.which(self.mp4decrypt_path) @@ -375,17 +373,8 @@ class Downloader: ) playplay_license_response = PlayPlayLicenseResponse() playplay_license_response.ParseFromString(playplay_license_response_bytes) - obfuscated = playplay_license_response.obfuscated_key.hex() - output = subprocess.check_output( - [ - self.unplayplay_path_full, - file_id, - obfuscated, - ], - shell=False, - ) - key = bytes.fromhex(output.strip().decode("utf-8")) - assert key + obfuscated_key = playplay_license_response.obfuscated_key + key = decrypt_and_bind_key(obfuscated_key, file_id) return key def get_widevine_decryption_key(