From 2ce47440a9dfc3dddf1da04ea9fecb0588e80bc1 Mon Sep 17 00:00:00 2001 From: James Bunton Date: Tue, 4 Feb 2020 01:42:05 +1100 Subject: [PATCH] Fix for Google changes --- youtube.cgi | 55 ++++++++++++++++++++--------------------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/youtube.cgi b/youtube.cgi index ef7b608..c9937b7 100755 --- a/youtube.cgi +++ b/youtube.cgi @@ -150,9 +150,10 @@ def extract_js(script): def find_func_name(script): FUNC_NAME = R"([a-zA-Z0-9$]+)" + DECODE_URI_COMPONENT = R"(\(decodeURIComponent)?" FUNC_PARAMS = R"(\([a-zA-Z,\.]+\.s\))" TERMINATOR = R"[,;\)]" - PATTERN = FUNC_NAME + FUNC_PARAMS + TERMINATOR + PATTERN = FUNC_NAME + DECODE_URI_COMPONENT + FUNC_PARAMS + TERMINATOR match = re.search(PATTERN, script) func_name = match.groups()[0] @@ -202,24 +203,10 @@ def decode_signature(js_url, signature): sandbox.window = sandbox; const code_string = %(code)s + ';'; - const exec_string = 'transformed_signature = %(func_name)s("", "MARKER", signature);'; + const exec_string = 'transformed_signature = %(func_name)s(signature);'; vm.runInNewContext(code_string + exec_string, sandbox); - function findSignature(obj) { - if (typeof obj !== 'object') { - return; - } - for (const [key, value] of Object.entries(obj)) { - if (key === 'MARKER') { - return value; - } - const result = findSignature(value); - if (result) { - return result; - } - } - } - console.log(findSignature(sandbox.transformed_signature)); + console.log(sandbox.transformed_signature); """ % params) p.stdin.write(js_decode_script.encode("utf-8")) @@ -233,19 +220,19 @@ def decode_signature(js_url, signature): return transformed_signature def get_best_video(player_config): - url_data_list = player_config["args"]["url_encoded_fmt_stream_map"].split(",") js_url = player_config["assets"]["js"] + player_args = player_config["args"] + player_response = json.loads(player_args["player_response"]) + formats = player_response["streamingData"]["formats"] + best_url = None best_quality = None best_extension = None - for url_data in url_data_list: - url_data = urllib.parse.parse_qs(url_data) - mimetype = url_data["type"][0].split(";")[0] - quality = url_data["quality"][0] + for format_data in formats: + mimetype = format_data["mimeType"].split(";")[0] + quality = format_data["quality"] - if "stereo3d" in url_data: - continue if quality not in QUALITIES: continue if mimetype not in MIMETYPES: @@ -257,17 +244,17 @@ def get_best_video(player_config): if best_quality is not None and quality < best_quality: continue - video_url = url_data["url"][0] - if "sig" in url_data: - signature = url_data["sig"][0] - elif "s" in url_data: - signature = decode_signature(js_url, url_data["s"][0]) - else: - signature = None - - if signature: - sp = url_data.get("sp", ["signature"])[0] + if "cipher" in format_data: + cipher = urllib.parse.parse_qs(format_data["cipher"]) + video_url = cipher["url"][0] + if "sig" in cipher: + signature = cipher["sig"][0] + elif "s" in cipher: + signature = decode_signature(js_url, cipher["s"][0]) + sp = cipher.get("sp", ["signature"])[0] video_url = append_to_qs(video_url, {sp: signature}) + else: + video_url = format_data["url"] best_url = video_url best_quality = quality -- 2.39.2