X-Git-Url: https://code.delx.au/youtube-cgi/blobdiff_plain/82fdab23ffe472c92e879cbb4325919e2aa7ea4d..65cb4de6f3758821f7e7e096ced5e2b21273b8a4:/youtube.cgi diff --git a/youtube.cgi b/youtube.cgi index d6273ba..2ad3b70 100755 --- a/youtube.cgi +++ b/youtube.cgi @@ -35,14 +35,6 @@ QUALITIES = { "small": 1, } -JS_BROWSER_STUB = """ -var window={}; -var document={}; -window.location={}; -var navigator={}; -""" - - class VideoUnavailable(Exception): pass @@ -140,8 +132,8 @@ def get_player_config(doc): return json.loads(line[p1:p2]) def extract_js(script): - PREFIX = "(function(){" - SUFFIX = "})();\n" + PREFIX = "var _yt_player={};(function(g){var window=this;" + SUFFIX = ";})(_yt_player);\n" assert script.startswith(PREFIX) assert script.endswith(SUFFIX) @@ -156,28 +148,59 @@ def find_func_name(script): func_name = match.groups()[0] return func_name -def decode_signature(js_url, s): +def decode_signature(js_url, signature): script = urlopen(js_url).read() func_name = find_func_name(script) + params = { + "func_name": func_name, + "signature": json.dumps(signature), + "code": json.dumps(extract_js(script)), + } p = subprocess.Popen( - "js", + "nodejs", shell=True, close_fds=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE ) - w = p.stdin.write - w(JS_BROWSER_STUB) - w(extract_js(script)) - w("console.log(%s('%s'));\n" % (func_name, s)) + js_decode_script = (""" + var vm = require('vm'); + + var sandbox = { + location: { + hash: '', + href: '', + protocol: 'http:' + }, + history: { + pushState: function(){} + }, + document: {}, + navigator: { + userAgent: '' + }, + signature: %(signature)s, + transformed_signature: null, + g: function(){} // this is _yt_player + }; + sandbox.window = sandbox; + + var code_string = %(code)s + ';'; + var exec_string = 'transformed_signature = %(func_name)s(signature);'; + vm.runInNewContext(code_string + exec_string, sandbox); + + console.log(sandbox.transformed_signature); + """ % params) + + p.stdin.write(js_decode_script) p.stdin.close() - signature = p.stdout.read().strip() + transformed_signature = p.stdout.read().strip() if p.wait() != 0: raise Exception("js failed to execute: %d" % p.returncode) - return signature + return transformed_signature def get_best_video(player_config): url_data_list = player_config["args"]["url_encoded_fmt_stream_map"].split(",")