[ie/youtube] Player client maintenance (#17261)

* Add visionos to logged-out default clients
* Add POT policy for android_vr
* Use tv_downgraded for VR fallback client
* Move back to web from web_safari in defaults

Closes #14997
Closes #15583
Closes #15756
Closes #15798
Closes #16064
Closes #17143
Closes #17232
Closes #17252

Authored by: bashonly
This commit is contained in:
bashonly
2026-07-20 23:36:39 +00:00
committed by GitHub
parent 93ceb95cdf
commit 69ea200067
3 changed files with 33 additions and 9 deletions
+12 -7
View File
@@ -140,13 +140,13 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
_RETURN_TYPE = 'video' # XXX: How to handle multifeed?
_SUBTITLE_FORMATS = ('json3', 'srv1', 'srv2', 'srv3', 'ttml', 'srt', 'vtt')
_DEFAULT_CLIENTS = ('android_vr', 'web_safari')
_DEFAULT_JSLESS_CLIENTS = ('android_vr',)
_DEFAULT_AUTHED_CLIENTS = ('tv_downgraded', 'web_safari')
_DEFAULT_CLIENTS = ('visionos', 'android_vr', 'web')
_DEFAULT_JSLESS_CLIENTS = ('visionos', 'android_vr')
_DEFAULT_AUTHED_CLIENTS = ('tv_downgraded', 'web')
# Premium does not require POT (except for subtitles)
_DEFAULT_PREMIUM_CLIENTS = ('tv_downgraded', 'web_creator')
_DEFAULT_PREMIUM_CLIENTS = ('tv_downgraded', 'web_creator', 'web')
_WEBPAGE_CLIENTS = ('web', 'web_safari')
_DEFAULT_WEBPAGE_CLIENT = 'web_safari'
_DEFAULT_WEBPAGE_CLIENT = 'web'
_GEO_BYPASS = False
@@ -2904,6 +2904,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
def _is_unplayable(player_response):
return traverse_obj(player_response, ('playabilityStatus', 'status')) == 'UNPLAYABLE'
@staticmethod
def _is_error_response(player_response):
return traverse_obj(player_response, ('playabilityStatus', 'status')) == 'ERROR'
def _extract_player_response(self, client, video_id, webpage_ytcfg, player_ytcfg, player_url, initial_pr, visitor_data, data_sync_id, po_token):
headers = self.generate_api_headers(
ytcfg=player_ytcfg,
@@ -3137,12 +3141,13 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
if (
# Is this a "made for kids" video that can't be downloaded with android_vr/visionos?
client in {'android_vr', 'visionos'} and self._is_unplayable(pr)
client in {'android_vr', 'visionos'}
and (self._is_unplayable(pr) or self._is_error_response(pr))
and webpage and 'made for kids' in webpage
# ...and is a JS runtime is available?
and any(p.is_available() for p in self._jsc_director.providers.values())
):
append_client('web_embedded')
append_client('tv_downgraded')
# web_embedded can work around age-gate and age-verification for some embeddable videos
if self._is_agegated(pr) and variant != 'web_embedded':