From ecb94d6cc35141a550499b68f8da991c4c80d849 Mon Sep 17 00:00:00 2001 From: Tontonnow <122251963+Tontonnow@users.noreply.github.com> Date: Fri, 27 Oct 2023 17:05:55 +0800 Subject: [PATCH] Add files via upload --- iqy.py | 296 ++++++++++++++++++++++++ main.py | 54 +++++ requirements.txt | 17 ++ tx.py | 586 +++++++++++++++++++++++++++++++++++++++++++++++ yk.py | 251 ++++++++++++++++++++ 5 files changed, 1204 insertions(+) create mode 100644 iqy.py create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 tx.py create mode 100644 yk.py diff --git a/iqy.py b/iqy.py new file mode 100644 index 0000000..6ff7c5d --- /dev/null +++ b/iqy.py @@ -0,0 +1,296 @@ +import base64 +import json +import time +from urllib import parse +import requests +from tabulate import tabulate +from pywidevineb.L3.cdm import deviceconfig +from pywidevineb.L3.decrypt.wvdecryptcustom import WvDecrypt +from tools import dealck, md5, get_size, get_pssh + + +def get_key(pssh): + LicenseUrl = "https://drml.video.iqiyi.com/drm/widevine?ve=0" + wvdecrypt = WvDecrypt(init_data_b64=pssh, device=deviceconfig.device_android_generic) + widevine_license = requests.post(url=LicenseUrl, data=wvdecrypt.get_challenge()) + license_b64 = base64.b64encode(widevine_license.content) + wvdecrypt.update_license(license_b64) + correct, keys = wvdecrypt.start_process() + for key in keys: + print('--key ' + key) + key_string = ' '.join([f"--key {key}" for key in keys]) + return key_string + + +class iqy: + def __init__(self, aqy): + self.ck = aqy + ckjson = dealck(aqy) + self.P00003 = ckjson.get('P00003', "1008611") + self.pck = ckjson.get('P00001') + self.dfp = ckjson.get('__dfp', "").split("@")[0] + self.QC005 = ckjson.get('QC005', "") + self.requests = requests.Session() + + self.requests.headers.update({ + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "Cookie": self.ck, + }) + self.bop = f"{{\"version\":\"10.0\",\"dfp\":\"{self.dfp}\",\"b_ft1\":8}}" + + @staticmethod + def parse(shareurl): + try: + url = "https://iface2.iqiyi.com/video/3.0/v_play" + params = { + "app_k": "20168006319fc9e201facfbd7c2278b7", + "app_v": "8.9.5", + "platform_id": "10", + "dev_os": "8.0.1", + "dev_ua": "Android", + "net_sts": "1", + "secure_p": "GPhone", + "secure_v": "1", + "dev_hw": "{\"cpu\":0,\"gpu\":\"\",\"mem\":\"\"}", + "app_t": "0", + "h5_url": shareurl + } + response = requests.get(url, params=params) + data = response.json() + pid = data['play_pid'] + aid = data['play_aid'] + tvid = data['play_tvid'] + Album = data['album'] + Title = Album['_t'] + Cid = Album['_cid'] + return pid, aid, tvid, Title, Cid + except Exception as e: + print(e) + return None, None, None, None, None + + @staticmethod + def get_avlistinfo(title, albumId, cid, pid): + rets = [] + page = 1 + size = 200 + + def getlist6(): + url = "https://pcw-api.iqiyi.com/album/source/svlistinfo" + params = { + "cid": "6", + "sourceid": pid, + "timelist": ",".join([str(i) for i in range(2000, 2026)]), + } + response = requests.get(url, params=params) + data = response.json()['data'] + for a, b in data.items(): + for i in b: + ret = { + "album": title, + "name": i['name'], + "tvId": i['tvId'], + } + rets.append(ret) + + def getlist(): + aid = albumId + url = "https://pcw-api.iqiyi.com/albums/album/avlistinfo" + params = { + "aid": aid, + "page": page, + "size": size + } + response = requests.get(url, params=params).json() + if response['code'] != 'A00000': + return None + data = response['data'] + total = data['total'] + if total > size: + for i in range(2, total // size + 2): + params['page'] = i + response = requests.get(url, params=params).json() + data['epsodelist'].extend(response['data']['epsodelist']) + for i in data['epsodelist']: + ret = { + "album": title, + "name": i['name'], + "tvId": i['tvId'], + } + rets.append(ret) + + if cid == 1: + ret = { + "album": title, + "name": title, + "tvId": albumId, + } + rets.append(ret) + elif cid == 6: + getlist6() + else: + getlist() + return rets + + def get_param(self, tvid="", vid=""): + tm = str(int(time.time() * 1000)) + authKey = md5("d41d8cd98f00b204e9800998ecf8427e" + tm + str(tvid)) + params = { + "tvid": tvid, + "bid": "600", + "vid": "", + "src": "01010031010000000000", + "vt": "0", + "rs": "1", + "uid": self.P00003, + "ori": "pcw", + "ps": "0", + "k_uid": "dc7c8156286e94182d2843ada4ef6050", + "pt": "0", + "d": "0", + "s": "", + "lid": "0", + "cf": "0", + "ct": "0", + "authKey": authKey, + "k_tag": "1", + "dfp": self.dfp, + "locale": "zh_cn", + "pck": self.pck, + "k_err_retries": "0", + "up": "", + "sr": "1", + "qd_v": "5", + "tm": tm, + "qdy": "u", + "qds": "0", + "ppt": "0", + "k_ft1": "706436220846084", + "k_ft4": "1162321298202628", + "k_ft2": "262335", + "k_ft5": "134217729", + "k_ft6": "128", + "k_ft7": "688390148", + "fr_300": "120_120_120_120_120_120", + "fr_500": "120_120_120_120_120_120", + "fr_600": "120_120_120_120_120_120", + "fr_800": "120_120_120_120_120_120", + "fr_1020": "120_120_120_120_120_120", + } + dash = f'/dash?' + for a, b in params.items(): + dash += f"{a}={b}&" + dash = dash[:-1] + "&bop=" + parse.quote(self.bop) + "&ut=14" + vf = md5(dash + "tle8orw4vetejc62int3uewiniecr18i") + dash += f"&vf={vf}" + return dash + + def get_dash(self, tvid="", vid=""): + params = self.get_param(tvid=tvid, vid=vid) + url = "https://cache.video.iqiyi.com" + params + res = self.requests.get(url) + return res.json() + + def run(self, url=None): + url = input("请输入爱奇艺分享链接:") if url is None else url + pid, aid, tvid, title, cid = self.parse(url) + if pid is None: + print("解析失败") + return + avlist = self.get_avlistinfo(title, aid, cid, pid) + if avlist is None: + print("获取列表失败") + return + table = tabulate(avlist, headers="keys", tablefmt="grid", showindex=range(1, len(avlist) + 1)) + print(table) + index = input("请输入序号:") + index = index.split(",") + for i in index: + if i.isdigit(): + i = int(i) + if i > len(avlist): + print("序号错误") + continue + tvId = avlist[i - 1]['tvId'] + name = avlist[i - 1]['name'] + ctitle = avlist[i - 1]['album'] + print(f"正在获取{ctitle} {name}的m3u8") + response = self.get_dash(tvid=tvId) + try: + if response['data']['boss_ts']['code'] != 'A00000': + print(f'获取m3u8失败\n') + print(response['data']['boss_ts']['msg']) + continue + except: + pass + data = response['data'] + program = data['program'] + if 'video' not in program: + print("无视频") + continue + video = program['video'] + audio = program['audio'] + stl = program.get("stl", []) + ''' + list = [] + for a in video: + scrsz = a.get('scrsz', '') + size = a['vsize'] + vid = a['vid'] + list.append((scrsz, vid, size)) + list.sort(key=lambda x: x[-1], reverse=True) + tb = tabulate(list, headers=["分辨率", "vid", "大小"], tablefmt="grid", + showindex=range(1, len(list) + 1)) + print(tb) + index = input("请输入序号:") + index = index.split(",") + for i in index: + vid = list[int(i) - 1][1] + response = self.get_dash(tvid=tvId, vid=vid) + try: + if response['data']['boss_ts']['code'] != 'A00000': + print(f'获取m3u8失败\n') + print(response['data']['boss_ts']['msg']) + continue + except: + pass + data = response['data'] + program = data['program'] + if 'video' not in program: + print("无视频") + continue + video = program['video'] + ''' + for a in video: + try: + scrsz = a.get('scrsz', '') + vsize = get_size(a['vsize']) + m3u8data = a['m3u8'] + fr = str(a['fr']) + name = name + "_" + scrsz + "_" + vsize + "_" + fr + 'fps' + name = name.replace(' ', '_') + file = f"./chache/{name}.m3u8" + savepath = f"./download/iqy/{ctitle}" + with open(file, 'w') as f: + f.write(m3u8data) + if m3u8data.startswith('{"payload"'): + m3u8data = json.loads(m3u8data) + init = m3u8data['payload']['wm_a']['audio_track1']['codec_init'] + pssh = get_pssh(init) + key_string = get_key(pssh) + cmd = f"N_m3u8DL-RE.exe \"{file} \" --tmp-dir ./cache --save-name \"{name}\" --save-dir \"{savepath}\" --thread-count 16 --download-retry-count 30 --auto-select --check-segments-count " + key_string + " --decryption-binary-path ./mp4decrypt.exe -M format=mp4" + else: + cmd = f"N_m3u8DL-RE.exe \"{file} \" --tmp-dir ./cache --save-name \"{name}\" --save-dir \"{savepath}\" --thread-count 16 --download-retry-count 30 --auto-select --check-segments-count " + with open(f"{ctitle}.bat", 'a', encoding='gbk') as f: + f.write(cmd) + f.write("\n") + print(f"获取{name}成功") + except: + continue + else: + continue + + +if __name__ == '__main__': + ck = "" + iq = iqy(ck) + iq.run() diff --git a/main.py b/main.py new file mode 100644 index 0000000..a06f920 --- /dev/null +++ b/main.py @@ -0,0 +1,54 @@ +import base64 +import hashlib +import json +import random +import time +from urllib import parse +from pathlib import Path +from urllib.parse import parse_qsl, urlsplit +from Crypto.Cipher import AES +from Crypto.Util.Padding import pad, unpad +from Cryptodome.Random import get_random_bytes +from Cryptodome.Random import random +from Cryptodome.Cipher import PKCS1_OAEP, AES +from Cryptodome.Hash import CMAC, SHA256, HMAC, SHA1 +from Cryptodome.PublicKey import RSA +from Cryptodome.Signature import pss +from Cryptodome.Util import Padding +from google.protobuf.message import DecodeError +from google.protobuf import text_format +import logging +import yaml +from tabulate import tabulate +from wasmer_compiler_cranelift import Compiler +from wasmer import Store, Type, Function, Memory, Module, ImportObject, engine, Instance, Table +from pywidevineb.L3.cdm import deviceconfig +from pywidevineb.L3.decrypt.wvdecryptcustom import WvDecrypt +import re, requests, time, json +from hashlib import md5 +import base64 +from tools import rsa_dec, aes_decrypt, djb2Hash, b64decode, sha1withrsa, check_file, get_config +from tx import TX +from iqy import iqy +from yk import YouKu + +if __name__ == '__main__': + check_file() + config = get_config() + txck = config["txck"] + yk = config["yk"] + aqy = config["aqy"] + tx = TX(txck) + iq = iqy(aqy) + youku = YouKu(yk) + while True: + url = input("请输入视频链接:") + if "v.qq.com" in url: + tx.run(url) + elif "iqiyi.com" in url: + iq.run(url) + elif "youku.com" in url: + youku.start(url) + else: + print("暂不支持该链接") + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..ab06cd5 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,17 @@ +certifi==2023.7.22 +charset-normalizer==3.3.1 +idna==3.4 +Nuitka==1.8.4 +ordered-set==4.1.0 +protobuf==3.20.0 +pycryptodome==3.19.0 +pycryptodomex==3.19.0 +pyperclip==1.8.2 +PyYAML==6.0.1 +requests==2.31.0 +tabulate==0.9.0 +urllib3==2.0.7 +wasmer==1.1.0 +wasmer_compiler_cranelift==1.1.0 +xmltodict==0.13.0 +zstandard==0.21.0 diff --git a/tx.py b/tx.py new file mode 100644 index 0000000..e4c79f6 --- /dev/null +++ b/tx.py @@ -0,0 +1,586 @@ +import base64 +import hashlib +import json +import random +import time +from pathlib import Path +from urllib.parse import parse_qsl, urlsplit +import requests +from Crypto.Cipher import AES +from Crypto.Util.Padding import pad, unpad +from tabulate import tabulate +from wasmer_compiler_cranelift import Compiler +from wasmer import Store, Type, Function, Memory, Module, ImportObject, engine, Instance, Table +from pywidevine.L3.cdm import deviceconfig +from pywidevine.L3.decrypt.wvdecryptcustom import WvDecrypt + +from tools import rsa_dec, aes_decrypt, djb2Hash, b64decode, sha1withrsa, updata_yaml, dealck, get_size + + +class Txckey: + def __init__(self): + appCodeName = 'Mozilla' + appName = 'Netscape' + appVersion = 'Win32' + platform = 'Win32', + self.appCodeName = appCodeName + self.appName = appName + self.appVersion = appVersion + self.platform = platform + self.userAgent = "mozilla/5.0 (windows nt 10.0; win64; x64) applewebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" + self.key = "2A5AA60178AA6C8DA662E443773A6C4E" + self.iv = "CFAC216FAA2D396013575D4055C63350" + self.ptrs = [] + self.pr = None + self.table = None + self.memory = None + self.func = None + wasmBinaryFile = "data:application/octet-stream;base64," \ + "AGFzbQEAAAABwgEbYAF/AX9gAn9/AGADf39/AGACf38Bf2ABfwBgA39/fwF/YAAAYAR/fn9/AX9gA39/fgF/YAZ/f35" \ + "/fn8Bf2AFf39/f38AYAZ/fH9/f38Bf2ADf39+AGAEf39/fwBgAn9+AGAGf39/f39/AX9gAAF+YAR/f39+AGAEf39/fwF" \ + "/YAABfGAAAX9gCn9/f39/f39/f38Bf2ACfH8BfGAIf39/f39/f38AYAl/f39/f39/f38Bf2AFf39" \ + "/f38Bf2ACfn8BfwIpBANoYzIDNkdqAAYDaGMyA3h1WAACA2hjMgMyZmIAEwNoYzIDRWpXAAADV1YOAQAEAAoCAAEDAgACDwEAAwYAAQECAAQEAAAACwQDCAUMABABAAUCABESAQEAAAECAQACAA0BAhQVFgAAFwwDAgoBABgHAAACBgQZAAkCDRoBAgABAgQFAXABCQkFBgEBgAKAAgYIAX8BQcCUBAsHTw0DY3NwAgADSk9qAE0Db3RtAD0DZ0RwAAsDNHlUAQADdENqAB0DMnpRABwDYlc4ADwDWU9kAE4DWmhuAB8DSmpGAE8DWVRpABEDNTVCAEgJDgEAQQELCBQjDUlRIDMkCrCWAlbaAQEBfyMAQRBrIgIgADYCDCACIAE3AwAgAigCDCACKQMAPAAAIAIgAikDAEIIiDcDACACKAIMIAIpAwA8AAEgAiACKQMAQgiINwMAIAIoAgwgAikDADwAAiACIAIpAwBCCIg3AwAgAigCDCACKQMAPAADIAIgAikDAEIIiDcDACACKAIMIAIpAwA8AAQgAiACKQMAQgiINwMAIAIoAgwgAikDADwABSACIAIpAwBCCIg3AwAgAigCDCACKQMAPAAGIAIgAikDAEIIiDcDACACKAIMIAIpAwA8AAcLNQEBfyMAQRBrIgIkACACIAA2AgwgAiABNgIIIAIoAgghACACKAIMEBYgADYCBCACQRBqJAALDQAgABATGkHv////Bws8AQF/IwBBEGsiASQAIAEgADYCDCABKAIMIgAgAUELaiABQQpqECsjAEEQayAANgIMIAAQISABQRBqJAALNwEBfyMAQRBrIgEkACABIAA2AgwCfyABKAIMIgAQP0EBcQRAIAAQJgwBCyAAEBoLIAFBEGokAAtvAQF/IwBBgAJrIgUkAAJAIAIgA0wNACAEQYDABHENACAFIAFB/wFxIAIgA2siA0GAAiADQYACSSIBGxAqGiABRQRAA0AgACAFQYACEFkgA0GAAmsiA0H/AUsNAAsLIAAgBSADEFkLIAVBgAJqJAALhAEBAX8jAEEQayIDJAAgAyAANgIMIAMgATYCCCADIAI2AgQgAygCBCgCAEEEakGAEEkEQCADKAIMIAMoAgQoAgBqIAMoAggiAEEYdCAAQYD+A3FBCHRyIABBCHZBgP4DcSAAQRh2cnI2AgAgAygCBCI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gACABOgAAIAAgAmoiA0EBayABOgAAIAJBA0kNACAAIAE6AAIgACABOgABIANBA2sgAToAACADQQJrIAE6AAAgAkEHSQ0AIAAgAToAAyADQQRrIAE6AAAgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgE2AgAgAyACIARrQXxxIgRqIgJBBGsgATYCACAEQQlJDQAgAyABNgIIIAMgATYCBCACQQhrIAE2AgAgAkEMayABNgIAIARBGUkNACADIAE2AhggAyABNgIUIAMgATYCECADIAE2AgwgAkEQayABNgIAIAJBFGsgATYCACACQRhrIAE2AgAgAkEcayABNgIAIAQgA0EEcUEYciIEayICQSBJDQAgAa1CgYCAgBB+IQUgAyAEaiEBA0AgASAFNwMYIAEgBTcDECABIAU3AwggASAFNwMAIAFBIGohASACQSBrIgJBH0sNAAsLIAALigEBAX8jAEEQayIDJAAgAyAANgIMIAMgATYCCCADIAI2AgQjAEEQayIAIAMoAgwiATYCCCAAKAIIGiMAQRBrIgAkACAAIAE2AgggACgCCCECIwBBEGsiASQAIAEgAjYCDCMAQRBrIgIgASgCDDYCDCACKAIMGiABQRBqJAAgAEEQaiQAIANBEGokAAsiAQF/IwBBEGsiASQAIAEgADYCDCABKAIMEDEgAUEQaiQAC5AcAQF/IwBB8AFrIgQkACAEIAA2AuwBIAQgATYC6AEgBCACNgLkASAEIAM3A9gBIARBADYCVCAEKQPYAUIAUgRAIAQpA9gBQsD/////B1YEQBAAAAsgBCAEKALsASgCADYClAEgBCAEKALsASgCBDYCkAEgBCAEKALsASgCCDYCjAEgBCAEKALsASgCDDYCiAEgBCAEKALsASgCEDYChAEgBCAEKALsASgCFDYCgAEgBCAEKALsASgCGDYCfCAEIAQoAuwBKAIcNgJ4IAQgBCgC7AEoAiA2AnQgBCAEKALsASgCJDYCcCAEIAQoAuwBKAIoNgJsIAQgBCgC7AEoAiw2AmggBCAEKALsASgCMDYCZCAEIAQoAuwBKAI0NgJgIAQgBCgC7AEoAjg2AlwgBCAEKALsASgCPDYCWANAIAQpA9gBQsAAVARAIARBEGoiAEIANwMAIABBOGpCADcDACAAQTBqQgA3AwAgAEEoakI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gBUL///////////8AgyIDQoCAgICAgMCAPH0gA0KAgICAgIDA/8MAfVQEQCAFQgSGIARCPIiEIQMgBEL//////////w+DIgRCgYCAgICAgIAIWgRAIANCgYCAgICAgIDAAHwhAgwCCyADQoCAgICAgICAQH0hAiAEQoCAgICAgICACFINASACIANCAYN8IQIMAQsgBFAgA0KAgICAgIDA//8AVCADQoCAgICAgMD//wBRG0UEQCAFQgSGIARCPIiEQv////////8Dg0KAgICAgICA/P8AhCECDAELQoCAgICAgID4/wAhAiADQv///////7//wwBWDQBCACECIANCMIinIglBkfcASQ0AIABBEGohASAEIQIgBUL///////8/g0KAgICAgIDAAIQiAyEGAkAgCUGB9wBrIghBwABxBEAgAiAIQUBqrYYhBkIAIQIMAQsgCEUNACAGIAitIgeGIAJBwAAgCGutiIQhBiACIAeGIQILIAEgAjcDACABIAY3AwgCQEGB+AAgCWsiAUHAAHEEQCADIAFBQGqtiCEEQgAhAwwBCyABRQ0AIANBwAAgAWuthiAEIAGtIgKIhCEEIAMgAoghAwsgACAENwMAIAAgAzcDCCAAQQhqKQMAQgSGIAApAwAiBEI8iIQhAiAAKQMQIABBGGopAwCEQgBSrSAEQv//////////D4OEIgRCgYCAgICAgIAIWgRAIAJCAXwhAgwBCyAEQoCAgICAgICACFINACACQgGDIAJ8IQILIABBIGokACACIAVCgICAgICAgICAf4OEvzkDAAvYAgEHfyMAQRBrIgYkACAGQQhqIQcjAEEgayIEJAAjAEEQayIDJAAjAEEQayIFIAE2AgwgAyAFKAIMNgIMIwBBEGsiBSABIAJqNgIMIAMgBSgCDDYCCCAEQRhqIgIgA0EMaigCADYCACACIANBCGooAgA2AgQgA0EQaiQAIAQoAhghAyAEKAIcIQgjAEEQayICIAA2AgwgAigCDCEJIAIkACAIIANrIQUgAyAIRwRAIAkgAyAFEFYLIAIgAyAFajYCDCACIAUgCWo2AgggBEEQaiIDIAJBDGooAgA2AgAgAyACQQhqKAIANgIEIAJBEGokACAEIAEgBCgCECMAQRBrIgIgATYCDCACKAIMa2o2AgwgBCAAIAQoAhQgAiAANgIMIAIoAgx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PCRBTIABBiBFqQgA3AwAgAEGAEWpCADcDACAAQgA3A/gQIABCADcD8BACQCAAKALYEUGAEEsEQCAEQa0IEDAgAEEBNgLcEQwBCyAAQUBrIgNBAEGAEBAqGiAAQegQaiIFQbAJKQAANwAAIABBwBBqIgFBGGpBhgkpAAA3AAAgAUEQakH+CCkAADcAACABQQhqQfYIKQAANwAAIAFB7ggpAAA3AAAgAEGUEWoiAhAsIQsgAhAerSEfIwBB0ABrIgIkACACIAM2AkwgAiAAQThqNgJIIAIgCzYCRCACIB83AzggAkG8CTYCNCACQhA3AyggAkEANgIkIAIgBTYCICACIAE2AhwgAkIANwMQIAIpAzhCb1YEQBAAAAsgAigCTCIBIQMgAikDOCIfpyABaiEFIAIoAkQhCyACKAI0IQwgAikDKCEgIAIoAiQhEiACKAIgIRMgAigCHCEUIwBBkANrIgEkACABIAM2AowDIAEgBTYCiAMgAUEANgKEAyABIAs2AoADIAEgHzcD+AIgASAMNgL0AiABICA3A+gCIAEgEjYC5AIgASATNgLgAiABIBQ2AtwCIAEoAuACIQUgASgC3AIhDCMAQSBrIgMkACADIAFBEGoiCzYCHCADQsAANwMQIAMgBTYCDCADIAw2AgggAygCHCADKQMQIAMoAgwgAygCCEH4DigCACgCABEHABogA0EgaiQAIwBBEGsiAyQAIAMgAUHQAGoiBTYCDCADIAs2AgggAygCDCADKAIIQewOKAIAKAIAEQMAGiADQRBqJAAgC0HAABAXIAUgASgC9AIgASkD6AIQJSABQQhqIgsgASkD6AIQBCAFIAtCCBAlIAEoAowDIQwgASgCgAMhEiABKQP4AiEfIAEoAuACIRMgASgC3AIhFCMAQTBrIgMkACADIAw2AiwgAyASNgIoIAMgHzcDICADIBM2AhwgA0IBNwMQIAMgFDYCDCADKAIsIAMoAiggAykDICADKAIcIAMpAxAgAygCDEH4DigCACgCBBEJABogA0EwaiQAIAUgASgCjAMgASkD+AIQJSALIAEpA/gCEAQgBSALQggQJSABKAKIAyELIwBBEGsiAyQAIAMgBTYCDCADIAs2AgggAygCDCADKAIIQewOKAIAKAIIEQMAGiADQRBqJAAgBUGAAhAXIAEoAoQDBEAgASgChANCEDc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" + if wasmBinaryFile.startswith("data:application/octet-stream;base64,"): + wasm_file = base64.b64decode(wasmBinaryFile.split(",")[1]) + else: + wasm_file = Path(wasmBinaryFile).read_bytes() + self.wasm_file = wasm_file + self.store = Store(engine.JIT(Compiler)) + self.module = Module(self.store, self.wasm_file) + self.import_object = ImportObject() + self.register() + self.asm = Instance(self.module, self.import_object) + self.exports = self.asm.exports + self.gen_export_object() + self.gen_func() + + def gen_func(self): + func = { + "free": self.func["k"], + "malloc": self.func["j"], + } + self.func.update(func) + + def gen_func(self): + func = { + "free": self.func["2zQ"], + "malloc": self.func["tCj"], + } + self.func.update(func) + + def malloc(self, length): + ptr = self.func["malloc"](length) + self.ptrs.append(ptr) + return ptr + + def free(self, ptr): + if isinstance(ptr, list): + for i in ptr: + self.free(i) + else: + self.func['free'](ptr) + + def free_all(self): + self.free(self.ptrs) + self.ptrs = [] + + def ccall(self, func_name: str, returnType: 'type', *args): + def convertReturnValue(_ptr: int): + if returnType == str: + return self.UTF8ToString(_ptr) + elif returnType == bool: + return bool(returnType) + return _ptr + + stack = 0 + _args = [] + for arg in args: + if isinstance(arg, str): + max_write_length = len(arg) + 64 + ptr = self.malloc(max_write_length) + if len(arg) >= 30: + self.pr = ptr + self.stringToUTF8(arg, ptr, max_write_length) + _args.append(ptr) + elif isinstance(arg, list): + max_write_length = len(arg) + 8 + ptr = self.malloc(max_write_length) + self.writeArrayToMemory(arg, ptr, max_write_length) + _args.append(ptr) + else: + _args.append(arg) + ptr = self.func[func_name](*_args) + ret = convertReturnValue(ptr) + return ret + + @staticmethod + def _abort(): + pass + + def _emscripten_memcpy_big(self, dest: int, src: int, num: int = None): + if num is None: + num = len(self.memory.uint8_view()) - 1 + self.memory.uint8_view()[dest:dest + num] = self.memory.uint8_view()[src:src + num] + + def _emscripten_resize_heap(self, param_0: int) -> int: + return 0 + + def gettm(self) -> 'f64': + return float(time.time()) + + def EjW(self, param_0: int) -> int: + return 0 + + def gen_import_object(self): + a = { + "6Gj": Function(self.store, self._abort), + "xuX": Function(self.store, self._emscripten_memcpy_big), + "2fb": Function(self.store, self.gettm), + "EjW": Function(self.store, self.EjW), + } + tximport = { + "hc2": a, + } + return tximport + + def gen_export_object(self): + func = dict() + for (k, v) in self.exports: + if isinstance(v, Function): + func[k] = v + elif isinstance(v, Memory): + setattr(self, "memory", v) + elif isinstance(v, Table): + setattr(self, "table", v) + # print(k, v.type) + self.func = func + + def register(self): + for i in self.gen_import_object(): + self.import_object.register(i, self.gen_import_object()[i]) + + def stringToUTF8(self, data: str, ptr: int, max_write_length: int): + _data = data.encode('utf-8') + write_length = len(_data) + if write_length == 0: + self.memory.uint8_view()[ptr] = 0 + _data = _data + b'\0' * (max_write_length - write_length) + uint8 = self.memory.uint8_view(offset=ptr) + uint8[0:max_write_length] = _data + + def UTF8ToString(self, ptr: int) -> str: + if ptr > 0: + _memory = self.memory.uint8_view(offset=ptr) + data = [] + index = 0 + while _memory[index] != 0: + data.append(_memory[index]) + index += 1 + return bytes(data).decode('utf-8') + else: + return '' + + def writeArrayToMemory(self, array: list, ptr: int, max_write_length: int): + array = array + [0] * (max_write_length - len(array)) + self.memory.uint8_view()[ptr, ptr + max_write_length] = array + + def __del__(self): + self.free_all() + del self.ptrs + + def gen_key(self, *args): + return self.ccall("otm", str, *args) + + def ckey(self, ): + pass + + def aesenc(self, data: str): + key = bytes.fromhex(self.key) + iv = bytes.fromhex(self.iv) + cipher = AES.new(key, AES.MODE_CBC, iv) + data = pad(data.encode('utf-8'), 16) + return cipher.encrypt(data).hex().upper() + + def aesdec(self, data: str, key=None, iv=None): + key = bytes.fromhex(self.key) + iv = bytes.fromhex(self.iv) + cipher = AES.new(key, AES.MODE_CBC, iv) + data = bytes.fromhex(data) + return unpad(cipher.decrypt(data), 16).decode('utf-8') + + @staticmethod + def get_hash(s): + h = 0 + for c in s: + h = (h << 5) - h + ord(c) + return str(h & 0xffffffff) + + def ckey81(self, vid, tm, appVer='3.5.57', guid='52f0ea142b32b633', platform="10201", + url="https://v.qq.com/x/cover/mzc00200b4jsdq6/l00469csvi7.html"): + url = url[0:48] + navigator = self.userAgent[0:48] + appCodeName = self.appCodeName + appName = self.appName + platforma = self.platform + s = "|" + "|".join( + [vid, tm, "mg3c3b04ba", appVer, guid, platform, url, navigator, url, appCodeName, appName, platforma, + "00"]) + "|" + s = "|" + self.get_hash(s) + s + return s + + @staticmethod + def roundstr(mun: int = 32): + return ''.join(random.sample('ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba1234567890', mun)) + + @staticmethod + def md5str(a: str): + return hashlib.md5(a.encode()).hexdigest() + + def ckey85(self, vid, appVer="1.26.3", guid="", platform="10201", + h38=""): + data = { + "vid": vid, + "nonce": "", + "rand": "", + "appVer": appVer, + "guid": guid, + "platform": platform, + } + ts = str(int(time.time())) + data["ts"] = ts + nonce = self.roundstr(11) + rand = self.md5str(nonce + "1234")[:8] + data["rand"] = rand + data["nonce"] = nonce + ckey = json.dumps(data, separators=(',', ':')) + enc = self.aesenc(ckey) + ckey = "--01" + enc + return ckey + + def ckey92(self, tm, vid, appVer="1.28.2", guid="", h38="", + url="https://v.qq.com/x/cover/mzc002006w8m6hk/u0047t48n6f.html", platform=10201, + l="{\"cp\":\"59zexbw7hg\",\"csal\":[\"m5h0zchrh5\"]}", r="{\"ea\":3,\"spa\":1,\"hwdrm\":4,\"hwacc\":1}"): + url = url[0:48] + s = url + "|mozilla/5.0 (windows nt 10.0; win64; x64) applew|https://v.qq.com/channel/tv|Mozilla|Netscape|Win32" + data = [platform, appVer, vid, "", guid, s, l, + r, h38, int(tm)] + ckey = self.gen_key(*data).split('|') + for i in ckey: + if ckey.count(i) == 1: + ckey = i + break + if i == ckey[-1]: + ckey = ckey[5] + return ckey + + +class TX: + + def __init__(self, ck): + self.ckey = Txckey() + self.guid = None + self.h38 = None + self.ck = ck + self.key = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOG98XlIossYaXk4RHWOZutQEo1wvC4GHMNFBsYhGVbJgPVAF7SM6rPIkC/efoJ9qHYPcYGhh5LdB/FZkBkj8neeKT76+7CZkMYoolYS5gGLg4IgxTDS7uVoKMRLXQSKJxfEGLDlGKZ+oqQmW7hVUMTsYnsn+6WTk+P4FRTWO2uPAgMBAAECgYBKBbDS5mCLXFvppeu86I8TBlSvEJKEPPjdhxrriRr3/GdPBE9BoxurDE9LgxfUzkOZQwMjUMZWACiEmavIsqLkvM2Ld7WCQ6oiO739xZkQsgX/M0X7f1lcldLB2kHEsglWWexGoK68KD99HufHK+6QAnIL+AVhpE7cDXCmtK++AQJBAPGO6as8+3Vnm10ruCPt23FmrZlxpKA5LVzW9m0adPFWbPMJJFvI0oI9eJVhMYa9uFcRhdO0YSyrkUKvoAS7OIECQQDvPPWvy719Z5cIjE2yFh4DKS5JRZnPZZia2XGnOotbwEt6SFFFqASyR5xfh+1gjbaJ/6mQlli0YWvjWK8ylRwPAkEA4epkFffBwer1Pi0+WbQCcUuzfnfvnL389ABDloSQ7ImE+cQKEiF+57nwBd1RwY+8UQodXIMuAuYuw+yXPvWOgQJAJyPQBjzM+ZFTEmDx7SrVKis4mWA7s8SpXNwqTfO0DQS+1Hi0YzMD4a75lF+GpH9K1/Tt5uvSA2DU59MAhsQCXQJABelyNLFk6bf4n8CYAlOCZ7JCh3pUfbZ5mkuj6VmROzjXzRrT9B/tezNK7nEeUstVTiwl/DMXYCCwVXkLCvq9Bw==\n" + "-----END RSA PRIVATE KEY-----\n" + self.logintoken = { + "access_token": "", + "appid": "", + "vusession": "", + "openid": "", + "vuserid": "", + "video_guid": "", + "main_login": "" + } + self.headers = { + "User-Agent": self.ckey.userAgent, + "Referer": "https://v.qq.com", + "Cookie": self.ck, + } + self.re = requests.session() + self.re.headers.update(self.headers) + self.login() + + def login(self): + cookie = dealck(self.ck) + for i in self.logintoken: + self.logintoken[i] = cookie.get(i) or cookie.get("vqq_" + i) + self.h38 = cookie.get("_qimei_h38", "") + self.guid = cookie.get("video_guid", "") + url = 'https://access.video.qq.com/user/auth_refresh' + params = { + "vappid": "11059694", + "vsecret": "fdf61a6be0aad57132bc5cdf78ac30145b6cd2c1470b0cfe", + "type": "qq", + "g_tk": "", + "g_vstk": djb2Hash(self.logintoken["vusession"]), + "g_actk": djb2Hash(self.logintoken["access_token"]), + "_": str(int(time.time() * 1000)), + } + data = self.re.get(url, params=params).text + data = json.loads(data.split("=")[1]) + access_token = data["access_token"] + vusession = data["vusession"] + self.ck = self.ck.replace(self.logintoken["access_token"], access_token) + self.ck = self.ck.replace(self.logintoken["vusession"], vusession) + ck=self.ck.replace("vqq_", "") + self.logintoken["access_token"] = access_token + self.logintoken["vusession"] = vusession + self.headers = { + "User-Agent": self.ckey.userAgent, + "Referer": "https://v.qq.com", + "Cookie": ck, + } + self.re.headers.update(self.headers) + updata_yaml("txck", self.ck) + + def wv(self, pssh, lic_url): + def ke(): + wvdecrypt = WvDecrypt(init_data_b64=pssh, cert_data_b64="", + device=deviceconfig.device_android_generic) + bcert_b64 = wvdecrypt.get_challenge() + lrs = sha1withrsa(self.key, bcert_b64) + data = [ + 10201, + "1.28.2", + "", + "", + self.guid, + "https://v.qq.com/x/cover/v2098lbuihuqs11/u00315w|mozilla/5.0 (windows nt 10.0; win64; x64) applew|https://v.qq.com/|Mozilla|Netscape|Win32", + '{"cp":"59zexbw7hg","csal":["m5h0zchrh5"],"lrs":"' + lrs + '"}', + '{"ea":3,"spa":1}', + self.h38, + int(time.time()) + ] + ckey = self.ckey.gen_key(*data).split('|')[5] + url = lic_url.split("?")[0] + dic["ckey"] = ckey + dic["encrypt_ver"] = "9.2" + dic['app_ver'] = "1.28.2" + self.re.headers["Referer"] = "https://v.qq.com/" + widevine_license = self.re.post(url=url, data=bcert_b64, + params=dic) + data = widevine_license.json() + code = data["code"] + if code != 0: + print(data) + return None + data = data["anc"] + data = self.dec_res(data, 2) + ke(data) + + dic = dict(parse_qsl(urlsplit(lic_url).query)) + dic["version"] = "1" + ke() + + def dec_res(self, data: str, c=1): + data = json.loads(b64decode(data)) + rc = b64decode(data["rc"]) + aanc = b64decode(data["aanc"]) + anc = b64decode(data["anc"]) + key, iv = eval(rsa_dec(self.key, rc))["algo_params"] + algo_list = eval(aes_decrypt(key.encode(), aanc, iv.encode()).decode())["algo_list"] + key, iv = algo_list[0]["algo_params"] + if c == 1: + data = json.loads(aes_decrypt(key.encode(), anc, iv.encode()).decode()) + else: + data = base64.b64encode(aes_decrypt(key.encode(), anc, iv.encode())).decode() + return data + + def get(self, vid=None, url="https://v.qq.com/x/cover/mzc002007qle9m2/x0047r3k6wy.html", defn="hdr10"): + vid = url.split("/")[-1].split(".")[0] if vid is None else vid + tm = int(time.time()) + ckey = self.ckey.ckey92(tm=tm, vid=vid, guid=self.guid, h38=self.h38, url=url) + params = { + "vid": vid, + "defn": defn, + "ehost": url, + "refer": url, + "platform": "10201", + "guid": self.guid, + "cKey": ckey, + "logintoken": json.dumps(self.logintoken, separators=(',', ':')), + "tm": tm, + "charge": "0", + "otype": "ojson", + "defnpayver": "3", + "spau": "1", + "spaudio": "0", + "spwm": "1", + "sphls": "2", + "host": "v.qq.com", + "sphttps": "1", + "encryptVer": "9.2", + "clip": "4", + "flowid": "", + "sdtfrom": "v1010", + "appVer": "1.28.2", + "unid": "", + "auth_from": "", + "auth_ext": "", + "fhdswitch": "0", + "dtype": "3", + "spsrt": "2", + "lang_code": "0", + "spvvpay": "1", + "spadseg": "3", + "spav1": "15", + "hevclv": "33", + "spsfrhdr": "0", + "spvideo": "0", + "spm3u8tag": "67", + "spmasterm3u8": "3", + "drm": "40" + } + response = self.re.get("https://h5vv6.video.qq.com/getinfo", params=params) + data = response.json() + if "anc" in data: + anc = data["anc"] + data = self.dec_res(anc) + return data + + @staticmethod + def get_list(url): + def get_video_data(data, ret=[]): + cookies = { + "appid": "wxa75efa648b60994b", + "vversion_name": "8.2.95.1", + "video_bucketid": "4", + "video_omgid": "" + } + params = { + "video_appid": "3000002", + "guid": "", + "vplatform": "5", + "callerid": "3000002" + } + headers = { + "Accept-Encoding": "gzip,compress,br,deflate", + "Connection": "keep-alive", + "Host": "pbaccess.video.qq.com", + "Referer": "https://servicewechat.com/wxa75efa648b60994b/629/page-frame.html", + "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.42(0x18002a2e) NetType/WIFI Language/zh_CN", + "content-type": "application/json" + } + url = "https://pbaccess.video.qq.com/trpc.universal_backend_service.page_server_rpc.PageServer/GetPageData" + response = requests.post(url, headers=headers, cookies=cookies, params=params, data=data) + response_data = response.json() + module_list_datas = response_data['data']['module_list_datas'] + for module_list_data in module_list_datas: + module_data = module_list_data['module_datas'][0] + if module_data['module_params']['module_type'] == "episode_list": + has_next = module_data['module_params']['has_next'] + item_datas = module_data['item_data_lists']['item_datas'] + for item_data in item_datas: + item_type = item_data['item_type'] + if int(item_type) == 23: + print(item_data['item_params']['sub_title']) + continue + item_params = item_data['item_params'] + play_type = item_params['play_type'] + if int(play_type) != 1: + continue + cover_c_title = item_params['cover_c_title'] + play_title = item_params['play_title'] + vid = item_params['vid'] + # defn = eval(item_params['defn']) + # defn = sorted(defn.items(), key=lambda x: x[1], reverse=True) + ret.append([cover_c_title, play_title, vid]) + if has_next == "true": + next_page_context = module_data['module_params']['next_page_context'] + data = { + "page_params": { + "page_type": "detail_operation", + "cid": "", + "page_id": "vsite_episode_list", + "page_context": next_page_context, + } + } + get_video_data(json.dumps(data, separators=(',', ':')), ret) + else: + break + return ret + + cid = url.split("/")[5].split(".")[0] + data = { + "page_params": { + "page_type": "video_detail", + "cid": cid + } + } + + data = get_video_data(json.dumps(data, separators=(',', ':'))) + return data + + def run(self, url=None): + url = input("输入url:") if url is None else url + list = self.get_list(url) + print(tabulate(list, headers=['cover_c_title', 'play_title', 'vid'], tablefmt="grid", + showindex=range(1, len(list) + 1))) + + c = input("选择清晰度,多个用逗号隔开:") + c = c.split(",") + for i in c: + viddeodata = list[int(i) - 1] + c_title, title, vid = viddeodata + data = self.get(vid=vid, url=url) + fi = data['fl']['fi'] + defn = [] + for f in fi: + cname = f['cname'] + name = f['name'] + fs = f['fs'] + size = get_size(fs) + fn = f['id'] + defn.append([fn, name, cname, size, fs]) + defn.sort(key=lambda x: x[-1], reverse=True) + print(tabulate(defn, headers=['id', 'fn', 'cname', 'size', "rsize"], tablefmt="grid", + showindex=range(1, len(defn) + 1))) + c = input("选择清晰度,多个用逗号隔开:") + c = c.split(",") + for i in c: + fn = defn[int(i) - 1][1] + rr = self.get(vid, url, fn) if fn != "hdr10" else data + vi = rr['vl']['vi'][0] + ui = vi['ul']['ui'] + enc = vi.get("enc") + if enc == "1": + if "ckc" in vi: + lic_url = vi['ckc'] + m3u8 = rr['play']['audiolist'][0]['m3u8'] + pssh = m3u8.split("base64,")[1].split('",')[0] + print(pssh) + print("不支持wv") + #key = self.wv(pssh, lic_url) + elif "base" in vi: + tm = data['tm'] + base = vi['base'] + linkvid = vi['lnk'] + appVer = "1.28.2" + platform = 10201 + print("不支持chacha20") + ''' + ckey = {"ChaCha20KeyBase64":"AAAAAA==","ChaCha20NonceBase64":"AAAAAA=="} + ChaCha20KeyBase64 = ckey["ChaCha20KeyBase64"] + ChaCha20NonceBase64 = ckey["ChaCha20NonceBase64"] + if ChaCha20KeyBase64.find("AAAAAA") != -1: + return None + ''' + continue + m3u8url = "" + for a in ui: + m3u8url = a['url'] + m3u8url = m3u8url if not m3u8url.endswith("/") else m3u8url + a['hls']['pt'] + break + savepath = f"./download/tx/{c_title}/" + cmd = f"N_m3u8DL-RE.exe \"{m3u8url} \" --tmp-dir ./cache --save-name \"{title}\" --save-dir \"{savepath}\" --thread-count 16 --download-retry-count 30 --auto-select --check-segments-count " + with open("{}.bat".format(c_title), "a", encoding="utf-8") as f: + f.write("chcp 65001\n") + f.write(cmd) + f.write("\n") + print(f"已生成下载脚本{c_title}.bat 请运行下载") + + +if __name__ == '__main__': + ck = "" + tx = TX(ck) + tx.run() diff --git a/yk.py b/yk.py new file mode 100644 index 0000000..2957fd9 --- /dev/null +++ b/yk.py @@ -0,0 +1,251 @@ +import os +import re, requests, time, json +from hashlib import md5 +from urllib.parse import parse_qsl, urlsplit +import base64 +from Crypto.Cipher import AES +from tabulate import tabulate +from pywidevineb.L3.cdm import deviceconfig +from pywidevineb.L3.decrypt.wvdecryptcustom import WvDecrypt +from tools import get_pssh, dealck + +requests = requests.Session() + + +class YouKu: + def __init__(self, cookie): + self.cookie = dealck(cookie) + self.r = "xWrtQpP4Z4RsrRCY" + self.R = "aq1mVooivzaolmJY5NrQ3A==" + self.key = "" + self.headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", + } + requests.headers.update(self.headers) + requests.cookies.update(self.cookie) + + def youku_sign(self, t, data, token): + appKey = '24679788' # 固定值 + '''token值在cookie中''' + sign = token + '&' + t + '&' + appKey + '&' + data + md = md5() + md.update(sign.encode('UTF-8')) + sign = md.hexdigest() + return sign + + def utid(self): + json_cookie = requests.cookies.get_dict() + requests.cookies.clear() + requests.cookies.update(json_cookie) + utid = json_cookie.get("cna") + token = json_cookie.get("_m_h5_tk").split("_")[0] + return {"utid": utid, "token": token} + + # 若直接在首页小窗口上复制的视频网址,是重定向的网址。 + def redirect(self, url): + headers = { + "referer": "https://www.youku.com/", + "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", + } + resp = requests.get(url=url) + return resp.url + + def page_parser(self, url): + vid = re.findall(r"id_(.*?)\.html", url)[0] + url = "https://openapi.youku.com/v2/videos/show.json" + params = { + "client_id": "53e6cc67237fc59a", + "package": "com.huawei.hwvplayer.youku", + "ext": "show", + "video_id": vid + } + try: + response = requests.get(url, params=params).json() + showid = response["show"]["id"] + return {"current_showid": showid, "videoId": 0, "vid": vid} + except Exception as e: + print(f"获取showid失败:{e}") + print(f"[red]获取showid失败[/red]") + + def get_emb(self, videoId): + emb = base64.b64encode(("%swww.youku.com/" % videoId).encode('utf-8')).decode('utf-8') + return emb + + # 这个函数用来获取元素的第一个值 + def takeOne(self, elem): + return float(elem[0]) + + def m3u8_url(self, t, params_data, sign): + url = "https://acs.youku.com/h5/mtop.youku.play.ups.appinfo.get/1.1/" + + params = { + "jsv": "2.5.8", + "appKey": "24679788", + "t": t, + "sign": sign, + "api": "mtop.youku.play.ups.appinfo.get", + "v": "1.1", + "timeout": "20000", + "YKPid": "20160317PLF000211", + "YKLoginRequest": "true", + "AntiFlood": "true", + "AntiCreep": "true", + "type": "jsonp", + "dataType": "jsonp", + "callback": "mtopjsonp1", + "data": params_data, + } + resp = requests.get(url=url, params=params) + result = resp.text + # print(result) + data = json.loads(result[12:-1]) + # print(data) + ret = data["ret"] + video_lists = [] + if ret == ["SUCCESS::调用成功"]: + stream = data["data"]["data"]["stream"] + title = data["data"]["data"]["video"]["title"] + print("解析成功:") + for video in stream: + m3u8_url = video["m3u8_url"] + width = video["width"] + height = video["height"] + size = video["size"] + size = '{:.1f}'.format(float(size) / 1048576) + drm_type = video["drm_type"] + if video['drm_type'] == "default": + key = "" + elif drm_type == "cbcs": + license_url = video["stream_ext"]["uri"] + key = self.get_cbcs_key(license_url, m3u8_url) + if key[0]: + key = key[1][0] + else: + encryptR_server = video['encryptR_server'] + copyright_key = video['stream_ext']['copyright_key'] + key = self.copyrightDRM(self.r, encryptR_server, copyright_key) + video_lists.append([title, size + "M", f"{width}x{height}", drm_type, key, m3u8_url]) + tb = tabulate([[*video_lists[i][:5]] for i in range(len(video_lists))], + headers=["标题", "分辨率", "视频大小", "drm_type", "base64key"], tablefmt="pretty", + showindex=range(1, len(video_lists) + 1)) + ch = input(f"{tb}\n请输入要下载的视频序号:") + ch = ch.split(",") + for i in ch: + title, size, resolution, drm_type, key, m3u8_url = video_lists[int(i) - 1] + savename = f"{title}_{resolution}_{size}" + savepath = os.path.join(os.getcwd(), "/download/yk") + rm3u8_url = m3u8_url.replace("%", "%%") + common_args = f"N_m3u8DL-RE.exe \"{rm3u8_url}\" --tmp-dir ./cache --save-name \"{title}\" --save-dir \"{savepath}\" --thread-count 16 --download-retry-count 30 --auto-select --check-segments-count" + if drm_type == "default": + cmd = common_args + elif drm_type == "cbcs": + cmd = f"{common_args} --key {key} -M format=mp4" + else: + txt = f''' + #OUT,{savepath} + #DECMETHOD,ECB + #KEY,{key} + {title}_{resolution}_{size},{m3u8_url} + ''' + with open("{}.txt".format(title), "a", encoding="gbk") as f: + f.write(txt) + print("下载链接已生成") + continue + with open("{}.bat".format(title), "a", encoding="gbk") as f: + f.write(cmd) + f.write("\n") + print("下载链接已生成") + elif ret == ["FAIL_SYS_ILLEGAL_ACCESS::非法请求"]: + print("请求参数错误") + elif ret == ["FAIL_SYS_TOKEN_EXOIRED::令牌过期"]: + print("Cookie过期") + return 10086 + else: + print(ret[0]) + return 0 + + def copyrightDRM(self, r, encryptR_server, copyright_key): + crypto_1 = AES.new(r.encode(), AES.MODE_ECB) + key_2 = crypto_1.decrypt(base64.b64decode(encryptR_server)) + crypto_2 = AES.new(key_2, AES.MODE_ECB) + return base64.b64encode(base64.b64decode(crypto_2.decrypt(base64.b64decode(copyright_key)))).decode() + + def get_cbcs_key(self, license_url, m3u8_url): + headers = { + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82" + } + m3u8data = requests.get(m3u8_url, headers=headers).text + key_url = re.findall(r"URI=\"(.*?)\"", m3u8data)[0] + response = requests.get(key_url, headers=headers).text + pssh = response.split("data:text/plain;base64,").pop().split('",')[0] + wvdecrypt = WvDecrypt(init_data_b64=pssh, cert_data_b64="", device=deviceconfig.device_android_generic) + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.82", + } + dic = dict(parse_qsl(urlsplit(license_url).query)) + url = license_url.split("?")[0] + dic["licenseRequest"] = base64.b64encode(wvdecrypt.get_challenge()).decode() + dic["drmType"] = "widevine" + response = requests.post(url, data=dic, headers=headers) + license_b64 = response.json()["data"] + wvdecrypt.update_license(license_b64) + Correct, keyswvdecrypt = wvdecrypt.start_process() + if Correct: + return Correct, keyswvdecrypt + + def get(self, url): + t = str(int(time.time() * 1000)) + user_info = self.utid() + userid = user_info["utid"] + page_info = self.page_parser(url) + emb = self.get_emb(page_info["videoId"]) + steal_params = { + "ccode": "0502", + "utid": userid, + "version": "9.4.39", + "ckey": "DIl58SLFxFNndSV1GFNnMQVYkx1PP5tKe1siZu/86PR1u/Wh1Ptd+WOZsHHWxysSfAOhNJpdVWsdVJNsfJ8Sxd8WKVvNfAS8aS8fAOzYARzPyPc3JvtnPHjTdKfESTdnuTW6ZPvk2pNDh4uFzotgdMEFkzQ5wZVXl2Pf1/Y6hLK0OnCNxBj3+nb0v72gZ6b0td+WOZsHHWxysSo/0y9D2K42SaB8Y/+aD2K42SaB8Y/+ahU+WOZsHcrxysooUeND", + "client_ip": "192.168.1.1", + "client_ts": 1698373135 + } + biz_params = { + "vid": page_info["vid"], + "h265": 1, + "preferClarity": 4, + "media_type": "standard,subtitle", + "app_ver": "9.4.39", + "extag": "EXT-X-PRIVINF", + "play_ability": 16782592, + "master_m3u8": 1, + "drm_type": 19, + "key_index": "web01", + "encryptR_client": self.R, + "skh": 1, + "last_clarity": 5, + "clarity_chg_ts": 1689341442 + } + ad_params = { + "vip": 1, + } + params_data = { + "steal_params": json.dumps(steal_params), + "biz_params": json.dumps(biz_params), + "ad_params": json.dumps(ad_params), + } + params_data = json.dumps(params_data) + sign = self.youku_sign(t, params_data, user_info["token"]) + return self.m3u8_url(t, params_data, sign) + + def start(self, url=None): + url = input("请输入视频链接:") if url is None else url + url = self.redirect(url) + for i in range(3): + ret = self.get(url) + if ret: + continue + break + + +if __name__ == '__main__': + cookie ="" + youku = YouKu(cookie) + youku.start()