mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-05-01 00:08:47 +02:00
Compare commits
2 Commits
22ac81a069
...
61c9a938b3
Author | SHA1 | Date | |
---|---|---|---|
|
61c9a938b3 | ||
|
fd8394bc50 |
@ -2122,23 +2122,23 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
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 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
|
|
||||||
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 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
|
|
||||||
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 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
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 sts:
|
if not player_url:
|
||||||
# Attempt to extract from player
|
error_msg = 'Cannot extract signature timestamp without player url'
|
||||||
if player_url is None:
|
|
||||||
error_msg = 'Cannot extract signature timestamp without player_url.'
|
|
||||||
if fatal:
|
if fatal:
|
||||||
raise ExtractorError(error_msg)
|
raise ExtractorError(error_msg)
|
||||||
self.report_warning(error_msg)
|
self.report_warning(error_msg)
|
||||||
return
|
return None
|
||||||
code = self._load_player(video_id, player_url, fatal=fatal)
|
|
||||||
if code:
|
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(
|
sts = int_or_none(self._search_regex(
|
||||||
r'(?:signatureTimestamp|sts)\s*:\s*(?P<sts>[0-9]{5})', code,
|
r'(?:signatureTimestamp|sts)\s*:\s*(?P<sts>[0-9]{5})', code,
|
||||||
'JS player signature timestamp', group='sts', fatal=fatal))
|
'JS player signature timestamp', group='sts', fatal=fatal))
|
||||||
|
if sts:
|
||||||
|
self._store_player_data_to_cache('sts', player_url, sts)
|
||||||
|
|
||||||
return sts
|
return sts
|
||||||
|
|
||||||
def _mark_watched(self, video_id, player_responses):
|
def _mark_watched(self, video_id, player_responses):
|
||||||
@ -3234,12 +3238,16 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
fmt_url = url_or_none(try_get(sc, lambda x: x['url'][0]))
|
fmt_url = url_or_none(try_get(sc, lambda x: x['url'][0]))
|
||||||
encrypted_sig = try_get(sc, lambda x: x['s'][0])
|
encrypted_sig = try_get(sc, lambda x: x['s'][0])
|
||||||
if not all((sc, fmt_url, player_url, encrypted_sig)):
|
if not all((sc, fmt_url, player_url, encrypted_sig)):
|
||||||
self.report_warning(
|
msg = f'Some {client_name} client https formats have been skipped as they are missing a url. '
|
||||||
f'Some {client_name} client https formats have been skipped as they are missing a url. '
|
if client_name == 'web':
|
||||||
f'{"Your account" if self.is_authenticated else "The current session"} may have '
|
msg += 'YouTube is forcing SABR streaming for this client. '
|
||||||
f'the SSAP (server-side ads) experiment which interferes with yt-dlp. '
|
else:
|
||||||
f'Please see https://github.com/yt-dlp/yt-dlp/issues/12482 for more details.',
|
msg += (
|
||||||
video_id, only_once=True)
|
f'YouTube may have enabled the SABR-only or Server-Side Ad Placement experiment for '
|
||||||
|
f'{"your account" if self.is_authenticated else "the current session"}. '
|
||||||
|
)
|
||||||
|
msg += 'See https://github.com/yt-dlp/yt-dlp/issues/12482 for more details'
|
||||||
|
self.report_warning(msg, video_id, only_once=True)
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
fmt_url += '&{}={}'.format(
|
fmt_url += '&{}={}'.format(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user