Skip to content

Instantly share code, notes, and snippets.

@ivan
Created May 13, 2023 00:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivan/4e59370fe5b74fa0d9f0b3ea9c6266dd to your computer and use it in GitHub Desktop.
Save ivan/4e59370fe5b74fa0d9f0b3ea9c6266dd to your computer and use it in GitHub Desktop.
yt-dlp: use deno for nsig extraction
diff --git a/yt_dlp/extractor/youtube.py b/yt_dlp/extractor/youtube.py
index b9623cbf8..abe996273 100644
--- a/yt_dlp/extractor/youtube.py
+++ b/yt_dlp/extractor/youtube.py
@@ -19,6 +19,8 @@
import urllib.error
import urllib.parse
import urllib3
+import tempfile
+import subprocess
from .common import InfoExtractor, SearchInfoExtractor
from .openload import PhantomJSwrapper
@@ -29,6 +31,7 @@
NO_DEFAULT,
ExtractorError,
LazyList,
+ Popen,
UserNotLive,
bug_reports_message,
classproperty,
@@ -3106,18 +3109,37 @@ def _extract_n_function_code(self, video_id, player_url):
return jsi, player_id, func_code
def _extract_n_function_from_code(self, jsi, func_code):
+ args, func_body = func_code
func = jsi.extract_function_from_code(*func_code)
def extract_nsig(s):
+ tmp = tempfile.NamedTemporaryFile(prefix="yt-dlp-nsig-for-deno.", delete=False)
+ tmp.close()
+
+ jscode = f'console.log(function({", ".join(args)}) {{ {func_body} }}({s!r}));'
+ with open(tmp.name, 'w', encoding='utf-8') as f:
+ f.write(jscode)
+
try:
- ret = func([s])
- except JSInterpreter.Exception:
- raise
+ stdout, stderr, returncode = Popen.run(
+ ['deno', 'run', tmp.name],
+ timeout=10,
+ text=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
except Exception as e:
- raise JSInterpreter.Exception(traceback.format_exc(), cause=e)
+ raise ExtractorError('Executing JS failed: Unable to run Deno binary', cause=e)
+ finally:
+ os.remove(tmp.name)
+ if returncode:
+ raise ExtractorError(f'Executing JS failed with returncode {returncode}:\n{stderr.strip()}')
+
+ ret = stdout.strip()
if ret.startswith('enhanced_except_'):
- raise JSInterpreter.Exception('Signature function returned an exception')
+ raise Exception('Signature function returned an exception')
+
return ret
return extract_nsig
@ivan
Copy link
Author

ivan commented May 13, 2023

This is a patch for yt-dlp to do nsig extraction with deno, with the code largely stolen from https://github.com/cute-sakura/yt-dlp-YTNSigDeno/blob/a3c87533dc513b1ca6d16197d4f8fe9ea35cc35f/yt_dlp_plugins/extractor/yt_nsig_deno.py, which does it as a plugin instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment