mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-05-21 17:55:44 -05:00
[ie/youtube] Cache signature timestamps (#13047)
Closes #12825 Authored by: bashonly
This commit is contained in:
parent
fd8394bc50
commit
61c9a938b3
1 changed files with 34 additions and 30 deletions
|
@ -2122,23 +2122,23 @@ def inner(*args, **kwargs):
|
||||||
return ret
|
return ret
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
def _load_nsig_code_from_cache(self, player_url):
|
def _load_player_data_from_cache(self, name, player_url):
|
||||||
cache_id = ('youtube-nsig', self._player_js_cache_key(player_url))
|
cache_id = (f'youtube-{name}', self._player_js_cache_key(player_url))
|
||||||
|
|
||||||
if func_code := self._player_cache.get(cache_id):
|
if data := self._player_cache.get(cache_id):
|
||||||
return func_code
|
return data
|
||||||
|
|
||||||
func_code = self.cache.load(*cache_id, min_ver='2025.03.31')
|
data = self.cache.load(*cache_id, min_ver='2025.03.31')
|
||||||
if func_code:
|
if data:
|
||||||
self._player_cache[cache_id] = func_code
|
self._player_cache[cache_id] = data
|
||||||
|
|
||||||
return func_code
|
return data
|
||||||
|
|
||||||
def _store_nsig_code_to_cache(self, player_url, func_code):
|
def _store_player_data_to_cache(self, name, player_url, data):
|
||||||
cache_id = ('youtube-nsig', self._player_js_cache_key(player_url))
|
cache_id = (f'youtube-{name}', self._player_js_cache_key(player_url))
|
||||||
if cache_id not in self._player_cache:
|
if cache_id not in self._player_cache:
|
||||||
self.cache.store(*cache_id, func_code)
|
self.cache.store(*cache_id, data)
|
||||||
self._player_cache[cache_id] = func_code
|
self._player_cache[cache_id] = data
|
||||||
|
|
||||||
def _decrypt_signature(self, s, video_id, player_url):
|
def _decrypt_signature(self, s, video_id, player_url):
|
||||||
"""Turn the encrypted s field into a working signature"""
|
"""Turn the encrypted s field into a working signature"""
|
||||||
|
@ -2181,7 +2181,7 @@ def _decrypt_nsig(self, s, video_id, player_url):
|
||||||
|
|
||||||
self.write_debug(f'Decrypted nsig {s} => {ret}')
|
self.write_debug(f'Decrypted nsig {s} => {ret}')
|
||||||
# Only cache nsig func JS code to disk if successful, and only once
|
# Only cache nsig func JS code to disk if successful, and only once
|
||||||
self._store_nsig_code_to_cache(player_url, func_code)
|
self._store_player_data_to_cache('nsig', player_url, func_code)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def _extract_n_function_name(self, jscode, player_url=None):
|
def _extract_n_function_name(self, jscode, player_url=None):
|
||||||
|
@ -2300,7 +2300,7 @@ def _fixup_n_function_code(self, argnames, nsig_code, jscode, player_url):
|
||||||
|
|
||||||
def _extract_n_function_code(self, video_id, player_url):
|
def _extract_n_function_code(self, video_id, player_url):
|
||||||
player_id = self._extract_player_info(player_url)
|
player_id = self._extract_player_info(player_url)
|
||||||
func_code = self._load_nsig_code_from_cache(player_url)
|
func_code = self._load_player_data_from_cache('nsig', player_url)
|
||||||
jscode = func_code or self._load_player(video_id, player_url)
|
jscode = func_code or self._load_player(video_id, player_url)
|
||||||
jsi = JSInterpreter(jscode)
|
jsi = JSInterpreter(jscode)
|
||||||
|
|
||||||
|
@ -2336,23 +2336,27 @@ def _extract_signature_timestamp(self, video_id, player_url, ytcfg=None, fatal=F
|
||||||
Extract signatureTimestamp (sts)
|
Extract signatureTimestamp (sts)
|
||||||
Required to tell API what sig/player version is in use.
|
Required to tell API what sig/player version is in use.
|
||||||
"""
|
"""
|
||||||
sts = None
|
if sts := traverse_obj(ytcfg, ('STS', {int_or_none})):
|
||||||
if isinstance(ytcfg, dict):
|
return sts
|
||||||
sts = int_or_none(ytcfg.get('STS'))
|
|
||||||
|
if not player_url:
|
||||||
|
error_msg = 'Cannot extract signature timestamp without player url'
|
||||||
|
if fatal:
|
||||||
|
raise ExtractorError(error_msg)
|
||||||
|
self.report_warning(error_msg)
|
||||||
|
return None
|
||||||
|
|
||||||
|
sts = self._load_player_data_from_cache('sts', player_url)
|
||||||
|
if sts:
|
||||||
|
return sts
|
||||||
|
|
||||||
|
if code := self._load_player(video_id, player_url, fatal=fatal):
|
||||||
|
sts = int_or_none(self._search_regex(
|
||||||
|
r'(?:signatureTimestamp|sts)\s*:\s*(?P<sts>[0-9]{5})', code,
|
||||||
|
'JS player signature timestamp', group='sts', fatal=fatal))
|
||||||
|
if sts:
|
||||||
|
self._store_player_data_to_cache('sts', player_url, sts)
|
||||||
|
|
||||||
if not sts:
|
|
||||||
# Attempt to extract from player
|
|
||||||
if player_url is None:
|
|
||||||
error_msg = 'Cannot extract signature timestamp without player_url.'
|
|
||||||
if fatal:
|
|
||||||
raise ExtractorError(error_msg)
|
|
||||||
self.report_warning(error_msg)
|
|
||||||
return
|
|
||||||
code = self._load_player(video_id, player_url, fatal=fatal)
|
|
||||||
if code:
|
|
||||||
sts = int_or_none(self._search_regex(
|
|
||||||
r'(?:signatureTimestamp|sts)\s*:\s*(?P<sts>[0-9]{5})', code,
|
|
||||||
'JS player signature timestamp', group='sts', fatal=fatal))
|
|
||||||
return sts
|
return sts
|
||||||
|
|
||||||
def _mark_watched(self, video_id, player_responses):
|
def _mark_watched(self, video_id, player_responses):
|
||||||
|
|
Loading…
Reference in a new issue