Skip to content

Commit 680069a

Browse files
committed
[YouTube] Improve n-sig function extraction for player aa3fc80b
Resolves #33123
1 parent 4a31290 commit 680069a

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

test/test_youtube_signature.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,10 @@
346346
'https://www.youtube.com/s/player/8a8ac953/tv-player-es6.vflset/tv-player-es6.js',
347347
'MiBYeXx_vRREbiCCmh', 'RtZYMVvmkE0JE',
348348
),
349+
(
350+
'https://www.youtube.com/s/player/aa3fc80b/player_ias.vflset/en_US/base.js',
351+
'0qY9dal2uzOnOGwa-48hha', 'VSh1KDfQMk-eag',
352+
),
349353
]
350354

351355

youtube_dl/extractor/youtube.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1878,6 +1878,20 @@ def _decrypt_nsig(self, n, video_id, player_url):
18781878

18791879
def _extract_n_function_name(self, jscode):
18801880
func_name, idx = None, None
1881+
1882+
def generic_n_function_search(func_name=None):
1883+
return self._search_regex(
1884+
r'''(?xs)
1885+
(?:(?<=[^\w$])|^) # instead of \b, which ignores $
1886+
(?P<name>%s)\s*=\s*function\((?!\d)[a-zA-Z\d_$]+\)
1887+
\s*\{(?:(?!};).)+?(?:
1888+
["']enhanced_except_ |
1889+
return\s*(?P<q>"|')[a-zA-Z\d-]+_w8_(?P=q)\s*\+\s*[\w$]+
1890+
)
1891+
''' % (func_name or r'(?!\d)[a-zA-Z\d_$]+',), jscode,
1892+
'Initial JS player n function name', group='name',
1893+
default=None if func_name else NO_DEFAULT)
1894+
18811895
# these special cases are redundant and probably obsolete (2025-04):
18821896
# they make the tests run ~10% faster without fallback warnings
18831897
r"""
@@ -1918,26 +1932,22 @@ def _extract_n_function_name(self, jscode):
19181932
(?(idx)|\[\s*)(?P<nfunc>(?!\d)[\w$]+)(?(idx)|\s*\])
19191933
\s*?[;\n]
19201934
''', jscode):
1921-
func_name = self._search_regex(
1935+
fn = self._search_regex(
19221936
r'[;,]\s*(function\s+)?({0})(?(1)|\s*=\s*function)\s*\((?!\d)[\w$]+\)\s*\{1}(?!\s*return\s)'.format(
19231937
re.escape(m.group('nfunc')), '{'),
19241938
jscode, 'Initial JS player n function name (2)', group=2, default=None)
1925-
if func_name:
1939+
if fn:
1940+
func_name = fn
19261941
idx = m.group('idx')
1927-
break
1942+
if generic_n_function_search(func_name):
1943+
# don't look any further
1944+
break
19281945

19291946
# thx bashonly: yt-dlp/yt-dlp/pull/10611
19301947
if not func_name:
19311948
self.report_warning('Falling back to generic n function search', only_once=True)
1932-
return self._search_regex(
1933-
r'''(?xs)
1934-
(?:(?<=[^\w$])|^) # instead of \b, which ignores $
1935-
(?P<name>(?!\d)[a-zA-Z\d_$]+)\s*=\s*function\((?!\d)[a-zA-Z\d_$]+\)
1936-
\s*\{(?:(?!};).)+?(?:
1937-
["']enhanced_except_ |
1938-
return\s*(?P<q>"|')[a-zA-Z\d-]+_w8_(?P=q)\s*\+\s*[\w$]+
1939-
)
1940-
''', jscode, 'Initial JS player n function name', group='name')
1949+
return generic_n_function_search()
1950+
19411951
if not idx:
19421952
return func_name
19431953

0 commit comments

Comments
 (0)