]> code.delx.au - youtube-cgi/blobdiff - youtube.cgi
changed script prefix/suffix
[youtube-cgi] / youtube.cgi
index d6273bae80b9eced9dae63abc52aa4727931c3c2..349842fb24b03f22789edfd1e38603bb9583e87c 100755 (executable)
@@ -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,56 @@ 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: {},
+            signature: %(signature)s,
+            transformed_signature: null
+        };
+        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(",")