mirror of
https://github.com/ytdl-org/youtube-dl.git
synced 2025-04-12 01:48:07 -05:00
[YouTube] Update signature extraction for players 643afba4
, 363db69b
This commit is contained in:
parent
087d865230
commit
c55dbf4838
@ -1709,6 +1709,18 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
' return %s\n') % (signature_id_tuple, expr_code)
|
' return %s\n') % (signature_id_tuple, expr_code)
|
||||||
self.to_screen('Extracted signature function:\n' + code)
|
self.to_screen('Extracted signature function:\n' + code)
|
||||||
|
|
||||||
|
def _extract_sig_fn(self, jsi, funcname):
|
||||||
|
var_ay = self._search_regex(
|
||||||
|
r'''(?:\*/|\{|\n|^)\s*(?:'[^']+'\s*;\s*)(var\s*[\w$]+\s*=\s*('|")(?:\\\2|(?!\2).)+\2\s*\.\s*split\(('|")\W+\3\))(?=\s*[,;])''',
|
||||||
|
jsi.code, 'useful values', default='')
|
||||||
|
|
||||||
|
sig_fn = jsi.extract_function_code(funcname)
|
||||||
|
|
||||||
|
if var_ay:
|
||||||
|
sig_fn = (sig_fn[0], ';\n'.join((var_ay, sig_fn[1])))
|
||||||
|
|
||||||
|
return sig_fn
|
||||||
|
|
||||||
def _parse_sig_js(self, jscode):
|
def _parse_sig_js(self, jscode):
|
||||||
# Examples where `sig` is funcname:
|
# Examples where `sig` is funcname:
|
||||||
# sig=function(a){a=a.split(""); ... ;return a.join("")};
|
# sig=function(a){a=a.split(""); ... ;return a.join("")};
|
||||||
@ -1734,8 +1746,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
jscode, 'Initial JS player signature function name', group='sig')
|
jscode, 'Initial JS player signature function name', group='sig')
|
||||||
|
|
||||||
jsi = JSInterpreter(jscode)
|
jsi = JSInterpreter(jscode)
|
||||||
initial_function = jsi.extract_function(funcname)
|
|
||||||
return lambda s: initial_function([s])
|
initial_function = self._extract_sig_fn(jsi, funcname)
|
||||||
|
|
||||||
|
func = jsi.extract_function_from_code(*initial_function)
|
||||||
|
|
||||||
|
return lambda s: func([s])
|
||||||
|
|
||||||
def _cached(self, func, *cache_id):
|
def _cached(self, func, *cache_id):
|
||||||
def inner(*args, **kwargs):
|
def inner(*args, **kwargs):
|
||||||
@ -1854,15 +1870,9 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
|
|
||||||
def _extract_n_function_code_jsi(self, video_id, jsi, player_id=None):
|
def _extract_n_function_code_jsi(self, video_id, jsi, player_id=None):
|
||||||
|
|
||||||
var_ay = self._search_regex(
|
|
||||||
r'(?:[;\s]|^)\s*(var\s*[\w$]+\s*=\s*"(?:\\"|[^"])+"\s*\.\s*split\("\W+"\))(?=\s*[,;])',
|
|
||||||
jsi.code, 'useful values', default='')
|
|
||||||
|
|
||||||
func_name = self._extract_n_function_name(jsi.code)
|
func_name = self._extract_n_function_name(jsi.code)
|
||||||
|
|
||||||
func_code = jsi.extract_function_code(func_name)
|
func_code = self._extract_sig_fn(jsi, func_name)
|
||||||
if var_ay:
|
|
||||||
func_code = (func_code[0], ';\n'.join((var_ay, func_code[1])))
|
|
||||||
|
|
||||||
if player_id:
|
if player_id:
|
||||||
self.cache.store('youtube-nsig', player_id, func_code)
|
self.cache.store('youtube-nsig', player_id, func_code)
|
||||||
|
@ -1368,19 +1368,21 @@ class JSInterpreter(object):
|
|||||||
code, _ = self._separate_at_paren(func_m.group('code')) # refine the match
|
code, _ = self._separate_at_paren(func_m.group('code')) # refine the match
|
||||||
return self.build_arglist(func_m.group('args')), code
|
return self.build_arglist(func_m.group('args')), code
|
||||||
|
|
||||||
def extract_function(self, funcname):
|
def extract_function(self, funcname, *global_stack):
|
||||||
return function_with_repr(
|
return function_with_repr(
|
||||||
self.extract_function_from_code(*self.extract_function_code(funcname)),
|
self.extract_function_from_code(*itertools.chain(
|
||||||
|
self.extract_function_code(funcname), global_stack)),
|
||||||
'F<%s>' % (funcname,))
|
'F<%s>' % (funcname,))
|
||||||
|
|
||||||
def extract_function_from_code(self, argnames, code, *global_stack):
|
def extract_function_from_code(self, argnames, code, *global_stack):
|
||||||
local_vars = {}
|
local_vars = {}
|
||||||
|
|
||||||
|
start = None
|
||||||
while True:
|
while True:
|
||||||
mobj = re.search(r'function\((?P<args>[^)]*)\)\s*{', code)
|
mobj = re.search(r'function\((?P<args>[^)]*)\)\s*{', code[start:])
|
||||||
if mobj is None:
|
if mobj is None:
|
||||||
break
|
break
|
||||||
start, body_start = mobj.span()
|
start, body_start = ((start or 0) + x for x in mobj.span())
|
||||||
body, remaining = self._separate_at_paren(code[body_start - 1:])
|
body, remaining = self._separate_at_paren(code[body_start - 1:])
|
||||||
name = self._named_object(local_vars, self.extract_function_from_code(
|
name = self._named_object(local_vars, self.extract_function_from_code(
|
||||||
[x.strip() for x in mobj.group('args').split(',')],
|
[x.strip() for x in mobj.group('args').split(',')],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user