mirror of
https://cdm-project.com/Decryption-Tools/TPD-Keys.git
synced 2025-04-30 00:54:26 +02:00
v1.2
GUI release
This commit is contained in:
parent
48b2eae31d
commit
f42123e269
@ -7,3 +7,4 @@ from . import mpd_parse
|
|||||||
from . import download
|
from . import download
|
||||||
from . import binary_check
|
from . import binary_check
|
||||||
from . import os_check
|
from . import os_check
|
||||||
|
from . import gui
|
@ -304,6 +304,7 @@ def create_binaries():
|
|||||||
|
|
||||||
# Remove binary from download folder if Linux
|
# Remove binary from download folder if Linux
|
||||||
if operating_system == "Linux":
|
if operating_system == "Linux":
|
||||||
|
os.remove(f"{os.getcwd()}/download/temp/yt-dlp.tar.gz")
|
||||||
shutil.rmtree(f"{os.getcwd()}/download/temp/yt-dlp")
|
shutil.rmtree(f"{os.getcwd()}/download/temp/yt-dlp")
|
||||||
|
|
||||||
# Print a new line
|
# Print a new line
|
||||||
|
@ -25,9 +25,9 @@ def web_dl_generic(mpd: str = None, device: str = None, api_key: str = None, rem
|
|||||||
|
|
||||||
# Retrieve the keys
|
# Retrieve the keys
|
||||||
if not remote:
|
if not remote:
|
||||||
mp4decrypt_keys = Sites.Generic.decrypt_generic(mpd_url=mpd, wvd=device, license_curl_headers=license_curl.headers)
|
mp4decrypt_keys, _ = Sites.Generic.decrypt_generic(mpd_url=mpd, wvd=device, license_curl_headers=license_curl.headers)
|
||||||
if remote:
|
if remote:
|
||||||
mp4decrypt_keys = Sites.Generic.decrypt_generic_remotely(api_key=api_key, license_curl_headers=license_curl.headers, mpd_url=mpd)
|
mp4decrypt_keys, _ = Sites.Generic.decrypt_generic_remotely(api_key=api_key, license_curl_headers=license_curl.headers, mpd_url=mpd)
|
||||||
|
|
||||||
# Define n_m3u8dl-re download parameters
|
# Define n_m3u8dl-re download parameters
|
||||||
n_m3u8dl_re_download = [
|
n_m3u8dl_re_download = [
|
||||||
@ -79,9 +79,9 @@ def web_dl_crunchyroll(mpd: str = None, device: str = None, api_key: str = None,
|
|||||||
|
|
||||||
# Retrieve the keys
|
# Retrieve the keys
|
||||||
if not remote:
|
if not remote:
|
||||||
mp4decrypt_keys = Sites.Crunchyroll.decrypt_crunchyroll(mpd_url=mpd, wvd=device, license_curl_headers=license_curl.headers)
|
mp4decrypt_keys, _ = Sites.Crunchyroll.decrypt_crunchyroll(mpd_url=mpd, wvd=device, license_curl_headers=license_curl.headers)
|
||||||
if remote:
|
if remote:
|
||||||
mp4decrypt_keys = Sites.Crunchyroll.decrypt_crunchyroll_remotely(api_key=api_key, license_curl_headers=license_curl.headers, mpd_url=mpd)
|
mp4decrypt_keys, _ = Sites.Crunchyroll.decrypt_crunchyroll_remotely(api_key=api_key, license_curl_headers=license_curl.headers, mpd_url=mpd)
|
||||||
|
|
||||||
# Define n_m3u8dl-re download parameters
|
# Define n_m3u8dl-re download parameters
|
||||||
n_m3u8dl_re_download = [
|
n_m3u8dl_re_download = [
|
||||||
@ -135,9 +135,9 @@ def youtube_dlp(url: str = None, device: str = None, api_key: str = None, remote
|
|||||||
|
|
||||||
# Retrieve the keys
|
# Retrieve the keys
|
||||||
if not remote:
|
if not remote:
|
||||||
mp4decrypt_keys = Sites.YouTube.decrypt_youtube(wvd=device, license_curl_headers=license_curl.headers, license_curl_json=license_curl.json_data, license_curl_cookies=license_curl.cookies)
|
mp4decrypt_keys, _ = Sites.YouTube.decrypt_youtube(wvd=device, license_curl_headers=license_curl.headers, license_curl_json=license_curl.json_data, license_curl_cookies=license_curl.cookies)
|
||||||
if remote:
|
if remote:
|
||||||
mp4decrypt_keys = Sites.YouTube.decrypt_youtube_remotely(api_key=api_key, license_curl_headers=license_curl.headers, license_curl_json=license_curl.json_data, license_curl_cookies=license_curl.cookies)
|
mp4decrypt_keys, _ = Sites.YouTube.decrypt_youtube_remotely(api_key=api_key, license_curl_headers=license_curl.headers, license_curl_json=license_curl.json_data, license_curl_cookies=license_curl.cookies)
|
||||||
|
|
||||||
# Define yt-dlp download parameters
|
# Define yt-dlp download parameters
|
||||||
yt_dlp_download = [
|
yt_dlp_download = [
|
||||||
|
195
Helpers/gui.py
Normal file
195
Helpers/gui.py
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
import PySimpleGUI as sg
|
||||||
|
import Sites
|
||||||
|
import ast
|
||||||
|
|
||||||
|
|
||||||
|
def clean_dict(dict: str = None):
|
||||||
|
header_string = f"'''" \
|
||||||
|
f"{dict}" \
|
||||||
|
f"'''"
|
||||||
|
cleaned_string = '\n'.join(line for line in header_string.split('\n') if not line.strip().startswith('#'))
|
||||||
|
clean_dict = ast.literal_eval(cleaned_string)
|
||||||
|
return clean_dict
|
||||||
|
|
||||||
|
|
||||||
|
def start_gui(wvd: str = None, api_key: str = None):
|
||||||
|
|
||||||
|
sg.theme('Dark Amber') # Add theme
|
||||||
|
|
||||||
|
# 1- the layout
|
||||||
|
left_frame_normal = sg.Col([
|
||||||
|
[sg.Text('PSSH:'), sg.Text(size=(15, 1), key='-PSSH_TEXT-')],
|
||||||
|
[sg.Input(key="-PSSH-")],
|
||||||
|
[sg.Text(text='License URL:'), sg.Text(size=(15, 1), key='-LIC_URL_TEXT-')],
|
||||||
|
[sg.Input(key='-LIC_URL-')],
|
||||||
|
[sg.Text('Keys:')],
|
||||||
|
[sg.Output(size=(45, 6), key='-OUTPUT-')],
|
||||||
|
[sg.Button('Decrypt'), sg.Button('Reset')]
|
||||||
|
], p=0)
|
||||||
|
|
||||||
|
right_frame_normal = sg.Col([
|
||||||
|
[sg.Text('Headers:')],
|
||||||
|
[sg.Multiline(key='-HEADERS-', size=(50, 10))],
|
||||||
|
[sg.Text('JSON:', key='-JSON_TEXT-', visible=False)],
|
||||||
|
[sg.Multiline(key='-JSON-', size=(50, 10), visible=False)],
|
||||||
|
[sg.Text('Cookies:', key='-COOKIES_TEXT-', visible=False)],
|
||||||
|
[sg.Multiline(key='-COOKIES-', size=(50, 10), visible=False)],
|
||||||
|
[sg.Combo(values=['Generic', 'Crunchyroll', 'YouTube'], default_value='Generic', key='-OPTIONS-', enable_events=True),sg.Push(), sg.Checkbox(text="Use CDM-Project API", key='-USE_API-')]
|
||||||
|
], p=0)
|
||||||
|
|
||||||
|
window_layout = [
|
||||||
|
[left_frame_normal, right_frame_normal]
|
||||||
|
]
|
||||||
|
|
||||||
|
# 2 - the window
|
||||||
|
window = sg.Window('TPD-Keys', layout=window_layout)
|
||||||
|
|
||||||
|
# 3 - the event loop
|
||||||
|
while True:
|
||||||
|
|
||||||
|
event, values = window.read()
|
||||||
|
|
||||||
|
if event == sg.WIN_CLOSED:
|
||||||
|
break
|
||||||
|
|
||||||
|
if event == 'Decrypt':
|
||||||
|
|
||||||
|
if values['-PSSH-'] != '' and values['-LIC_URL-'] == '' and values['-OPTIONS-'] == 'Generic':
|
||||||
|
window['-OUTPUT-'].update(f"No License URL provided")
|
||||||
|
|
||||||
|
if values['-LIC_URL-'] != '' and values['-PSSH-'] == '' and values['-OPTIONS-'] == 'Generic':
|
||||||
|
window['-OUTPUT-'].update(f"No PSSH provided")
|
||||||
|
|
||||||
|
if values['-PSSH-'] == '' and values['-LIC_URL-'] == '' and values['-OPTIONS-'] == 'Generic':
|
||||||
|
window['-OUTPUT-'].update(f"No PSSH or License URL provided")
|
||||||
|
|
||||||
|
if values['-PSSH-'] != '' and values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'Generic':
|
||||||
|
if values['-HEADERS-'] == '':
|
||||||
|
if not values['-USE_API-']:
|
||||||
|
try:
|
||||||
|
_, key_out = Sites.Generic.decrypt_generic(wvd=wvd, in_pssh=values['-PSSH-'],
|
||||||
|
in_license_url=values['-LIC_URL-'])
|
||||||
|
window['-OUTPUT-'].update(f"{key_out}")
|
||||||
|
except Exception as error:
|
||||||
|
window['-OUTPUT-'].update(f"{error}")
|
||||||
|
if values['-USE_API-']:
|
||||||
|
try:
|
||||||
|
_, key_out = Sites.Generic.decrypt_generic_remotely(api_key=api_key, in_pssh=values['-PSSH-'],
|
||||||
|
in_license_url=values['-LIC_URL-'])
|
||||||
|
window['-OUTPUT-'].update(f"{key_out}")
|
||||||
|
except Exception as error:
|
||||||
|
window['-OUTPUT-'].update(f"{error}")
|
||||||
|
|
||||||
|
if values['-HEADERS-'] != '':
|
||||||
|
if not values['-USE_API-']:
|
||||||
|
try:
|
||||||
|
_, key_out = Sites.Generic.decrypt_generic(wvd=wvd, in_pssh=values['-PSSH-'],
|
||||||
|
in_license_url=values['-LIC_URL-'],
|
||||||
|
license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-'])))
|
||||||
|
window['-OUTPUT-'].update(f"{key_out}")
|
||||||
|
except Exception as error:
|
||||||
|
window['-OUTPUT-'].update(f"{error}")
|
||||||
|
if values['-USE_API-']:
|
||||||
|
try:
|
||||||
|
_, key_out = Sites.Generic.decrypt_generic_remotely(api_key=api_key,
|
||||||
|
in_pssh=values['-PSSH-'],
|
||||||
|
in_license_url=values['-LIC_URL-'],
|
||||||
|
license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-'])))
|
||||||
|
window['-OUTPUT-'].update(f"{key_out}")
|
||||||
|
except Exception as error:
|
||||||
|
window['-OUTPUT-'].update(f"{error}")
|
||||||
|
|
||||||
|
if values['-PSSH-'] != '' and values['-OPTIONS-'] == 'Crunchyroll' and values['-HEADERS-'] != '':
|
||||||
|
if not values['-USE_API-']:
|
||||||
|
try:
|
||||||
|
_, key_out = Sites.Crunchyroll.decrypt_crunchyroll(wvd=wvd, in_pssh=values['-PSSH-'],
|
||||||
|
license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-'])))
|
||||||
|
window['-OUTPUT-'].update(f"{key_out}")
|
||||||
|
except Exception as error:
|
||||||
|
window['-OUTPUT-'].update(f"{error}")
|
||||||
|
if values['-USE_API-']:
|
||||||
|
try:
|
||||||
|
_, key_out = Sites.Crunchyroll.decrypt_crunchyroll_remotely(api_key=api_key, in_pssh=values['-PSSH-'],
|
||||||
|
license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-'])))
|
||||||
|
window['-OUTPUT-'].update(f"{key_out}")
|
||||||
|
except Exception as error:
|
||||||
|
window['-OUTPUT-'].update(f"{error}")
|
||||||
|
|
||||||
|
if values['-PSSH-'] != '' and values['-OPTIONS-'] == 'Crunchyroll' and values['-HEADERS-'] == '':
|
||||||
|
window['-OUTPUT-'].update(f"No Headers provided")
|
||||||
|
|
||||||
|
if values['-PSSH-'] == '' and values['-OPTIONS-'] == 'Crunchyroll':
|
||||||
|
window['-OUTPUT-'].update(f"No PSSH provided")
|
||||||
|
|
||||||
|
if values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'YouTube' and values['-HEADERS-'] != '' and values['-JSON-'] != '' and values['-COOKIES-'] != '':
|
||||||
|
if not values['-USE_API-']:
|
||||||
|
try:
|
||||||
|
_, key_out = Sites.YouTube.decrypt_youtube(wvd=wvd, in_license_url=values['-LIC_URL-'],
|
||||||
|
license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-'])),
|
||||||
|
license_curl_json=ast.literal_eval(clean_dict(dict=values['-JSON-'])),
|
||||||
|
license_curl_cookies=ast.literal_eval(clean_dict(dict=values['-COOKIES-'])))
|
||||||
|
window['-OUTPUT-'].update(f"{key_out}")
|
||||||
|
except Exception as error:
|
||||||
|
window['-OUTPUT-'].update(f"{error}")
|
||||||
|
if values['-USE_API-']:
|
||||||
|
try:
|
||||||
|
_, key_out = Sites.YouTube.decrypt_youtube_remotely(api_key=api_key, in_license_url=values['-LIC_URL-'],
|
||||||
|
license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-'])),
|
||||||
|
license_curl_json=ast.literal_eval(clean_dict(dict=values['-JSON-'])),
|
||||||
|
license_curl_cookies=ast.literal_eval(clean_dict(dict=values['-COOKIES-'])))
|
||||||
|
window['-OUTPUT-'].update(f"{key_out}")
|
||||||
|
except Exception as error:
|
||||||
|
window['-OUTPUT-'].update(f"{error}")
|
||||||
|
|
||||||
|
if values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'YouTube' and values['-HEADERS-'] == '' and values['-JSON-'] != '' and values['-COOKIES-'] != '':
|
||||||
|
window['-OUTPUT-'].update(f"No Headers provided")
|
||||||
|
|
||||||
|
if values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'YouTube' and values['-JSON-'] == '' and values['-HEADERS-'] != '' and values['-COOKIES-'] != '':
|
||||||
|
window['-OUTPUT-'].update(f"No JSON provided")
|
||||||
|
|
||||||
|
if values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'YouTube' and values['-COOKIES-'] == '' and values['-HEADERS-'] != '' and values['-JSON-'] != '':
|
||||||
|
window['-OUTPUT-'].update(f"No Cookies provided")
|
||||||
|
|
||||||
|
if values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'YouTube' and values['-HEADERS-'] == '' and values['-JSON-'] == '' and values['-COOKIES-'] == '':
|
||||||
|
window['-OUTPUT-'].update(f"All fields empty!")
|
||||||
|
|
||||||
|
if values['-LIC_URL-'] == '' and values['-OPTIONS-'] == 'YouTube':
|
||||||
|
window['-OUTPUT-'].update(f"No license URL provided")
|
||||||
|
|
||||||
|
|
||||||
|
if event == 'Reset':
|
||||||
|
window['-PSSH-'].update(value="", disabled=False)
|
||||||
|
window['-LIC_URL-'].update(value="", disabled=False)
|
||||||
|
window['-OUTPUT-'].update(value="", disabled=False)
|
||||||
|
window['-HEADERS-'].update(value="", disabled=False)
|
||||||
|
window['-OPTIONS-'].update(value="Generic", disabled=False)
|
||||||
|
|
||||||
|
if event == '-OPTIONS-' and values['-OPTIONS-'] == 'Crunchyroll':
|
||||||
|
window['-PSSH-'].update(value="", disabled=False)
|
||||||
|
window['-LIC_URL-'].update(value="", disabled=True)
|
||||||
|
window['-JSON-'].update(visible=False)
|
||||||
|
window['-JSON_TEXT-'].update(visible=False)
|
||||||
|
window['-COOKIES-'].update(visible=False)
|
||||||
|
window['-COOKIES_TEXT-'].update(visible=False)
|
||||||
|
|
||||||
|
if event == '-OPTIONS-' and values['-OPTIONS-'] == 'Generic':
|
||||||
|
window['-PSSH-'].update(value="", disabled=False)
|
||||||
|
window['-LIC_URL-'].update(value="", disabled=False)
|
||||||
|
window['-JSON-'].update(visible=False)
|
||||||
|
window['-JSON_TEXT-'].update(visible=False)
|
||||||
|
window['-COOKIES-'].update(visible=False)
|
||||||
|
window['-COOKIES_TEXT-'].update(visible=False)
|
||||||
|
|
||||||
|
if event == '-OPTIONS-' and values['-OPTIONS-'] == 'YouTube':
|
||||||
|
window['-PSSH-'].update(value="", disabled=True)
|
||||||
|
window['-LIC_URL-'].update(value="", disabled=False)
|
||||||
|
window['-JSON-'].update(visible=True)
|
||||||
|
window['-JSON_TEXT-'].update(visible=True)
|
||||||
|
window['-COOKIES-'].update(visible=True)
|
||||||
|
window['-COOKIES_TEXT-'].update(visible=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 4 - the close
|
||||||
|
window.close()
|
@ -10,7 +10,8 @@ import Helpers
|
|||||||
|
|
||||||
|
|
||||||
# Defining decrypt function for Crunchyroll
|
# Defining decrypt function for Crunchyroll
|
||||||
def decrypt_crunchyroll(wvd: str = None, license_curl_headers: dict = None, mpd_url: str = None):
|
def decrypt_crunchyroll(wvd: str = None, license_curl_headers: dict = None, mpd_url: str = None,
|
||||||
|
in_pssh: str = None):
|
||||||
|
|
||||||
# Exit if no device
|
# Exit if no device
|
||||||
if wvd is None:
|
if wvd is None:
|
||||||
@ -25,12 +26,15 @@ def decrypt_crunchyroll(wvd: str = None, license_curl_headers: dict = None, mpd_
|
|||||||
input_pssh = input(f"\nPSSH not found! Input PSSH: ")
|
input_pssh = input(f"\nPSSH not found! Input PSSH: ")
|
||||||
|
|
||||||
# Ask for PSSH if just keys function
|
# Ask for PSSH if just keys function
|
||||||
if mpd_url is None:
|
if mpd_url is None and in_pssh is None:
|
||||||
# Ask for PSSH if web-dl not selected:
|
# Ask for PSSH if web-dl not selected:
|
||||||
input_pssh = input(f"\nPSSH: ")
|
input_pssh = input(f"\nPSSH: ")
|
||||||
|
|
||||||
# prepare pssh
|
# prepare pssh
|
||||||
|
if in_pssh is None:
|
||||||
pssh = PSSH(input_pssh)
|
pssh = PSSH(input_pssh)
|
||||||
|
if in_pssh is not None:
|
||||||
|
pssh = PSSH(in_pssh)
|
||||||
|
|
||||||
# load device
|
# load device
|
||||||
device = Device.load(wvd)
|
device = Device.load(wvd)
|
||||||
@ -93,17 +97,21 @@ def decrypt_crunchyroll(wvd: str = None, license_curl_headers: dict = None, mpd_
|
|||||||
cdm.close(session_id)
|
cdm.close(session_id)
|
||||||
|
|
||||||
# Cache the keys
|
# Cache the keys
|
||||||
|
if in_pssh is None:
|
||||||
Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys)
|
Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys)
|
||||||
|
if in_pssh is not None:
|
||||||
|
Helpers.cache_key.cache_keys(pssh=in_pssh, keys=returned_keys)
|
||||||
|
|
||||||
# Print out the keys
|
# Print out the keys
|
||||||
print(f'\nKeys:\n{returned_keys}')
|
print(f'\nKeys:\n{returned_keys}')
|
||||||
|
|
||||||
# Return the keys for future ripper use.
|
# Return the keys for future ripper use.
|
||||||
return mp4decrypt_keys
|
return mp4decrypt_keys, returned_keys
|
||||||
|
|
||||||
|
|
||||||
# Defining remote decrypt function for Crunchyroll
|
# Defining remote decrypt function for Crunchyroll
|
||||||
def decrypt_crunchyroll_remotely(api_key: str = None, license_curl_headers: dict = None, mpd_url: str = None):
|
def decrypt_crunchyroll_remotely(api_key: str = None, license_curl_headers: dict = None, mpd_url: str = None,
|
||||||
|
in_pssh: str = None):
|
||||||
|
|
||||||
# Exit if no device
|
# Exit if no device
|
||||||
if api_key is None:
|
if api_key is None:
|
||||||
@ -116,7 +124,7 @@ def decrypt_crunchyroll_remotely(api_key: str = None, license_curl_headers: dict
|
|||||||
api_device = "CDM"
|
api_device = "CDM"
|
||||||
|
|
||||||
# Try getting pssh via MPD URL if web-dl
|
# Try getting pssh via MPD URL if web-dl
|
||||||
if mpd_url is not None:
|
if mpd_url is not None and in_pssh is None:
|
||||||
input_pssh = Helpers.mpd_parse.parse_pssh(mpd_url)
|
input_pssh = Helpers.mpd_parse.parse_pssh(mpd_url)
|
||||||
if input_pssh is not None:
|
if input_pssh is not None:
|
||||||
print(f'\nPSSH found: {input_pssh}')
|
print(f'\nPSSH found: {input_pssh}')
|
||||||
@ -124,10 +132,13 @@ def decrypt_crunchyroll_remotely(api_key: str = None, license_curl_headers: dict
|
|||||||
input_pssh = input(f"\nPSSH not found! Input PSSH: ")
|
input_pssh = input(f"\nPSSH not found! Input PSSH: ")
|
||||||
|
|
||||||
# Ask for PSSH if just keys function
|
# Ask for PSSH if just keys function
|
||||||
if mpd_url is None:
|
if mpd_url is None and in_pssh is None:
|
||||||
# Ask for PSSH if web-dl not selected:
|
# Ask for PSSH if web-dl not selected:
|
||||||
input_pssh = input(f"\nPSSH: ")
|
input_pssh = input(f"\nPSSH: ")
|
||||||
|
|
||||||
|
if in_pssh is not None:
|
||||||
|
input_pssh = in_pssh
|
||||||
|
|
||||||
# Set headers for API key
|
# Set headers for API key
|
||||||
api_key_headers = {
|
api_key_headers = {
|
||||||
"X-Secret-Key": api_key
|
"X-Secret-Key": api_key
|
||||||
@ -198,4 +209,4 @@ def decrypt_crunchyroll_remotely(api_key: str = None, license_curl_headers: dict
|
|||||||
requests.get(url=f'{api_url}/{api_device}/close/{session_id}', headers=api_key_headers)
|
requests.get(url=f'{api_url}/{api_device}/close/{session_id}', headers=api_key_headers)
|
||||||
|
|
||||||
# return mp4decrypt keys
|
# return mp4decrypt keys
|
||||||
return mp4decrypt_keys
|
return mp4decrypt_keys, returned_keys
|
||||||
|
@ -10,7 +10,8 @@ import Helpers
|
|||||||
|
|
||||||
|
|
||||||
# Defining decrypt function for generic services
|
# Defining decrypt function for generic services
|
||||||
def decrypt_generic(wvd: str = None, license_curl_headers: dict = None, mpd_url: str = None):
|
def decrypt_generic(wvd: str = None, license_curl_headers: dict = None, mpd_url: str = None,
|
||||||
|
in_pssh: str = None, in_license_url: str = None):
|
||||||
|
|
||||||
# Exit if no device
|
# Exit if no device
|
||||||
if wvd is None:
|
if wvd is None:
|
||||||
@ -25,16 +26,22 @@ def decrypt_generic(wvd: str = None, license_curl_headers: dict = None, mpd_url:
|
|||||||
input_pssh = input(f"\nPSSH not found! Input PSSH: ")
|
input_pssh = input(f"\nPSSH not found! Input PSSH: ")
|
||||||
|
|
||||||
# Ask for PSSH if just keys function
|
# Ask for PSSH if just keys function
|
||||||
if mpd_url is None:
|
if mpd_url is None and in_pssh is None:
|
||||||
# Ask for PSSH if web-dl not selected:
|
# Ask for PSSH if web-dl not selected:
|
||||||
input_pssh = input(f"\nPSSH: ")
|
input_pssh = input(f"\nPSSH: ")
|
||||||
|
|
||||||
|
|
||||||
# prepare pssh
|
# prepare pssh
|
||||||
|
if in_pssh is None:
|
||||||
pssh = PSSH(input_pssh)
|
pssh = PSSH(input_pssh)
|
||||||
|
if in_pssh is not None:
|
||||||
|
pssh = PSSH(in_pssh)
|
||||||
|
|
||||||
# Ask for license URL
|
# Ask for license URL
|
||||||
|
if in_license_url is None:
|
||||||
license_url = input(f"\nLicense URL: ")
|
license_url = input(f"\nLicense URL: ")
|
||||||
|
if in_license_url is not None:
|
||||||
|
license_url = in_license_url
|
||||||
|
|
||||||
# load device
|
# load device
|
||||||
device = Device.load(wvd)
|
device = Device.load(wvd)
|
||||||
@ -97,16 +104,21 @@ def decrypt_generic(wvd: str = None, license_curl_headers: dict = None, mpd_url:
|
|||||||
cdm.close(session_id)
|
cdm.close(session_id)
|
||||||
|
|
||||||
# Cache the keys
|
# Cache the keys
|
||||||
|
if in_pssh is None:
|
||||||
Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys)
|
Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys)
|
||||||
|
if in_pssh is not None:
|
||||||
|
Helpers.cache_key.cache_keys(pssh=in_pssh, keys=returned_keys)
|
||||||
|
|
||||||
# Print out the keys
|
# Print out the keys
|
||||||
print(f'\nKeys:\n{returned_keys}')
|
print(f'\nKeys:\n{returned_keys}')
|
||||||
|
|
||||||
# Return the keys for future ripper use.
|
# Return the keys for future ripper use.
|
||||||
return mp4decrypt_keys
|
return mp4decrypt_keys, returned_keys
|
||||||
|
|
||||||
|
|
||||||
# Defining remote decrypt function for generic services
|
# Defining remote decrypt function for generic services
|
||||||
def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = None, mpd_url: str = None):
|
def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = None, mpd_url: str = None,
|
||||||
|
in_pssh: str = None, in_license_url: str = None):
|
||||||
|
|
||||||
# Exit if no API key
|
# Exit if no API key
|
||||||
if api_key is None:
|
if api_key is None:
|
||||||
@ -119,7 +131,7 @@ def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = N
|
|||||||
api_device = "CDM"
|
api_device = "CDM"
|
||||||
|
|
||||||
# Try getting pssh via MPD URL if web-dl
|
# Try getting pssh via MPD URL if web-dl
|
||||||
if mpd_url is not None:
|
if mpd_url is not None and in_pssh is None:
|
||||||
input_pssh = Helpers.mpd_parse.parse_pssh(mpd_url)
|
input_pssh = Helpers.mpd_parse.parse_pssh(mpd_url)
|
||||||
if input_pssh is not None:
|
if input_pssh is not None:
|
||||||
print(f'\nPSSH found: {input_pssh}')
|
print(f'\nPSSH found: {input_pssh}')
|
||||||
@ -127,12 +139,18 @@ def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = N
|
|||||||
input_pssh = input(f"\nPSSH not found! Input PSSH: ")
|
input_pssh = input(f"\nPSSH not found! Input PSSH: ")
|
||||||
|
|
||||||
# Ask for PSSH if just keys function
|
# Ask for PSSH if just keys function
|
||||||
if mpd_url is None:
|
if mpd_url is None and in_pssh is None:
|
||||||
# Ask for PSSH if web-dl not selected:
|
# Ask for PSSH if web-dl not selected:
|
||||||
input_pssh = input(f"\nPSSH: ")
|
input_pssh = input(f"\nPSSH: ")
|
||||||
|
|
||||||
|
if in_pssh is not None:
|
||||||
|
input_pssh = in_pssh
|
||||||
|
|
||||||
# Ask for license URL
|
# Ask for license URL
|
||||||
|
if in_license_url is None:
|
||||||
input_license_url = input(f"\nLicense URL: ")
|
input_license_url = input(f"\nLicense URL: ")
|
||||||
|
if in_license_url is not None:
|
||||||
|
input_license_url = in_license_url
|
||||||
|
|
||||||
# Set headers for API key
|
# Set headers for API key
|
||||||
api_key_headers = {
|
api_key_headers = {
|
||||||
@ -197,6 +215,7 @@ def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = N
|
|||||||
# Cache the keys
|
# Cache the keys
|
||||||
Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys)
|
Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys)
|
||||||
|
|
||||||
|
|
||||||
# Print out keys
|
# Print out keys
|
||||||
print(f'\nKeys:\n{returned_keys}')
|
print(f'\nKeys:\n{returned_keys}')
|
||||||
|
|
||||||
@ -204,4 +223,4 @@ def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = N
|
|||||||
requests.get(url=f'{api_url}/{api_device}/close/{session_id}', headers=api_key_headers)
|
requests.get(url=f'{api_url}/{api_device}/close/{session_id}', headers=api_key_headers)
|
||||||
|
|
||||||
# Return mp4decrypt keys
|
# Return mp4decrypt keys
|
||||||
return mp4decrypt_keys
|
return mp4decrypt_keys, returned_keys
|
||||||
|
@ -10,7 +10,8 @@ import Helpers
|
|||||||
|
|
||||||
|
|
||||||
# Defining decrypt function for YouTube
|
# Defining decrypt function for YouTube
|
||||||
def decrypt_youtube(wvd: str = None, license_curl_headers: dict = None, license_curl_cookies: dict = None, license_curl_json: dict = None):
|
def decrypt_youtube(wvd: str = None, license_curl_headers: dict = None, license_curl_cookies: dict = None, license_curl_json: dict = None,
|
||||||
|
in_license_url: str = None):
|
||||||
|
|
||||||
# Exit if no device
|
# Exit if no device
|
||||||
if wvd is None:
|
if wvd is None:
|
||||||
@ -19,8 +20,11 @@ def decrypt_youtube(wvd: str = None, license_curl_headers: dict = None, license_
|
|||||||
# prepare pssh
|
# prepare pssh
|
||||||
pssh = PSSH("AAAAQXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAACEiGVlUX01FRElBOjZlMzI4ZWQxYjQ5YmYyMWZI49yVmwY=")
|
pssh = PSSH("AAAAQXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAACEiGVlUX01FRElBOjZlMzI4ZWQxYjQ5YmYyMWZI49yVmwY=")
|
||||||
|
|
||||||
# Ask for the license URL
|
# Ask for license URL
|
||||||
license_url = input("License URL: ")
|
if in_license_url is None:
|
||||||
|
license_url = input(f"\nLicense URL: ")
|
||||||
|
if in_license_url is not None:
|
||||||
|
license_url = in_license_url
|
||||||
|
|
||||||
# Print a new line between PSSH/License URL and keys
|
# Print a new line between PSSH/License URL and keys
|
||||||
print("\n")
|
print("\n")
|
||||||
@ -81,11 +85,12 @@ def decrypt_youtube(wvd: str = None, license_curl_headers: dict = None, license_
|
|||||||
print(f'Keys:\n{returned_keys}')
|
print(f'Keys:\n{returned_keys}')
|
||||||
|
|
||||||
# Return the keys for future ripper use.
|
# Return the keys for future ripper use.
|
||||||
return mp4decrypt_keys
|
return mp4decrypt_keys, returned_keys
|
||||||
|
|
||||||
|
|
||||||
# Defining remote decrypt function for YouTube
|
# Defining remote decrypt function for YouTube
|
||||||
def decrypt_youtube_remotely(api_key: str = None, license_curl_headers: dict = None, license_curl_json: dict = None, license_curl_cookies: dict = None):
|
def decrypt_youtube_remotely(api_key: str = None, license_curl_headers: dict = None, license_curl_json: dict = None, license_curl_cookies: dict = None,
|
||||||
|
in_license_url: str = None):
|
||||||
|
|
||||||
# Exit if no API key
|
# Exit if no API key
|
||||||
if api_key is None:
|
if api_key is None:
|
||||||
@ -98,7 +103,10 @@ def decrypt_youtube_remotely(api_key: str = None, license_curl_headers: dict = N
|
|||||||
api_device = "CDM"
|
api_device = "CDM"
|
||||||
|
|
||||||
# Ask for License URL
|
# Ask for License URL
|
||||||
input_license_url = input("License URL: ")
|
if in_license_url is None:
|
||||||
|
input_license_url = input(f"\nLicense URL: ")
|
||||||
|
if in_license_url is not None:
|
||||||
|
input_license_url = in_license_url
|
||||||
|
|
||||||
# Print a line between license URL and keys
|
# Print a line between license URL and keys
|
||||||
print("\n")
|
print("\n")
|
||||||
@ -177,4 +185,4 @@ def decrypt_youtube_remotely(api_key: str = None, license_curl_headers: dict = N
|
|||||||
requests.get(url=f'{api_url}/{api_device}/close/{session_id}', headers=api_key_headers)
|
requests.get(url=f'{api_url}/{api_device}/close/{session_id}', headers=api_key_headers)
|
||||||
|
|
||||||
# Return mp4decrypt keys
|
# Return mp4decrypt keys
|
||||||
return mp4decrypt_keys
|
return mp4decrypt_keys, returned_keys
|
||||||
|
@ -3,13 +3,12 @@ headers = {
|
|||||||
'Accept': '*/*',
|
'Accept': '*/*',
|
||||||
'Accept-Language': 'en-US,en;q=0.5',
|
'Accept-Language': 'en-US,en;q=0.5',
|
||||||
# 'Accept-Encoding': 'gzip, deflate, br',
|
# 'Accept-Encoding': 'gzip, deflate, br',
|
||||||
'Content-Type': 'application/octet-stream',
|
|
||||||
'DNT': '1',
|
'DNT': '1',
|
||||||
|
'Connection': 'keep-alive',
|
||||||
'Sec-Fetch-Dest': 'empty',
|
'Sec-Fetch-Dest': 'empty',
|
||||||
'Sec-Fetch-Mode': 'cors',
|
'Sec-Fetch-Mode': 'cors',
|
||||||
'Sec-Fetch-Site': 'same-site',
|
'Sec-Fetch-Site': 'cross-site',
|
||||||
'Sec-GPC': '1',
|
'Sec-GPC': '1',
|
||||||
'Connection': 'keep-alive',
|
|
||||||
# Requests doesn't support trailers
|
# Requests doesn't support trailers
|
||||||
# 'TE': 'trailers',
|
# 'TE': 'trailers',
|
||||||
}
|
}
|
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
@ -21,6 +21,7 @@ services.add_argument('--crunchyroll', action='store_true', help="Decrypt Crunch
|
|||||||
services.add_argument('--crunchyroll-remote', action='store_true', help="Decrypt Crunchyroll remotely")
|
services.add_argument('--crunchyroll-remote', action='store_true', help="Decrypt Crunchyroll remotely")
|
||||||
services.add_argument('--youtube', action='store_true', help="Decrypt YouTube")
|
services.add_argument('--youtube', action='store_true', help="Decrypt YouTube")
|
||||||
services.add_argument('--youtube-remote', action='store_true', help="Decrypt YouTube remotely")
|
services.add_argument('--youtube-remote', action='store_true', help="Decrypt YouTube remotely")
|
||||||
|
services.add_argument('--generic', action='store_true', help="Decrypt generic services")
|
||||||
services.add_argument('--generic-remote', action='store_true', help="Decrypt generic services remotely")
|
services.add_argument('--generic-remote', action='store_true', help="Decrypt generic services remotely")
|
||||||
|
|
||||||
# Add web download switch
|
# Add web download switch
|
||||||
@ -79,7 +80,7 @@ elif switches.generic_remote:
|
|||||||
Sites.Generic.decrypt_generic_remotely(api_key=api_key, license_curl_headers=license_curl.headers)
|
Sites.Generic.decrypt_generic_remotely(api_key=api_key, license_curl_headers=license_curl.headers)
|
||||||
|
|
||||||
|
|
||||||
else:
|
elif switches.generic:
|
||||||
# If no switch is provided, perform a default action
|
# If no switch is provided, perform a default action
|
||||||
if switches.web_dl:
|
if switches.web_dl:
|
||||||
mpd = input("MPD URL: ")
|
mpd = input("MPD URL: ")
|
||||||
@ -87,3 +88,6 @@ else:
|
|||||||
print(f'Saved at {file[0]}')
|
print(f'Saved at {file[0]}')
|
||||||
else:
|
else:
|
||||||
Sites.Generic.decrypt_generic(wvd=device, license_curl_headers=license_curl.headers)
|
Sites.Generic.decrypt_generic(wvd=device, license_curl_headers=license_curl.headers)
|
||||||
|
|
||||||
|
else:
|
||||||
|
Helpers.gui.start_gui(wvd=device, api_key=api_key)
|
Loading…
x
Reference in New Issue
Block a user