From 9e38b273b7ac942e7e9fc05a651ed810ab7d30ba Mon Sep 17 00:00:00 2001 From: Simon Sawicki Date: Thu, 5 Jun 2025 23:50:58 +0200 Subject: [PATCH] [ie/youtube] Rework nsig function name extraction (#13403) Closes #13401 Authored by: Grub4K --- test/test_youtube_signature.py | 8 ++++++++ yt_dlp/extractor/youtube/_video.py | 28 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/test/test_youtube_signature.py b/test/test_youtube_signature.py index 3f777aed7a..3336b6bfff 100644 --- a/test/test_youtube_signature.py +++ b/test/test_youtube_signature.py @@ -320,6 +320,14 @@ _NSIG_TESTS = [ 'https://www.youtube.com/s/player/59b252b9/player_ias.vflset/en_US/base.js', 'D3XWVpYgwhLLKNK4AGX', 'aZrQ1qWJ5yv5h', ), + ( + 'https://www.youtube.com/s/player/fc2a56a5/player_ias.vflset/en_US/base.js', + 'qTKWg_Il804jd2kAC', 'OtUAm2W6gyzJjB9u', + ), + ( + 'https://www.youtube.com/s/player/fc2a56a5/tv-player-ias.vflset/tv-player-ias.js', + 'qTKWg_Il804jd2kAC', 'OtUAm2W6gyzJjB9u', + ), ] diff --git a/yt_dlp/extractor/youtube/_video.py b/yt_dlp/extractor/youtube/_video.py index d82225718c..0b53756dc4 100644 --- a/yt_dlp/extractor/youtube/_video.py +++ b/yt_dlp/extractor/youtube/_video.py @@ -2229,20 +2229,20 @@ class YoutubeIE(YoutubeBaseInfoExtractor): def _extract_n_function_name(self, jscode, player_url=None): varname, global_list = self._interpret_player_js_global_var(jscode, player_url) if debug_str := traverse_obj(global_list, (lambda _, v: v.endswith('-_w8_'), any)): - funcname = self._search_regex( - r'''(?xs) - [;\n](?: - (?Pfunction\s+)| - (?:var\s+)? - )(?P[a-zA-Z0-9_$]+)\s*(?(f)|=\s*function\s*) - \((?P[a-zA-Z0-9_$]+)\)\s*\{ - (?:(?!\}[;\n]).)+ - \}\s*catch\(\s*[a-zA-Z0-9_$]+\s*\)\s* - \{\s*return\s+%s\[%d\]\s*\+\s*(?P=argname)\s*\}\s*return\s+[^}]+\}[;\n] - ''' % (re.escape(varname), global_list.index(debug_str)), - jscode, 'nsig function name', group='funcname', default=None) - if funcname: - return funcname + pattern = r'''(?x) + \{\s*return\s+%s\[%d\]\s*\+\s*(?P[a-zA-Z0-9_$]+)\s*\} + ''' % (re.escape(varname), global_list.index(debug_str)) + if match := re.search(pattern, jscode): + pattern = r'''(?x) + \{\s*\)%s\(\s* + (?: + (?P[a-zA-Z0-9_$]+)\s*noitcnuf\s* + |noitcnuf\s*=\s*(?P[a-zA-Z0-9_$]+)(?:\s+rav)? + )[;\n] + ''' % re.escape(match.group('argname')[::-1]) + if match := re.search(pattern, jscode[match.start()::-1]): + a, b = match.group('funcname_a', 'funcname_b') + return (a or b)[::-1] self.write_debug(join_nonempty( 'Initial search was unable to find nsig function name', player_url and f' player = {player_url}', delim='\n'), only_once=True)