From 5d0cd0e86323853c78e132d70fd085446c3fd100 Mon Sep 17 00:00:00 2001 From: MoojMidge <56883549+MoojMidge@users.noreply.github.com> Date: Fri, 15 Nov 2024 15:43:01 +1100 Subject: [PATCH] Re-enable player request clients that require specific OAuth tokens --- .../youtube/client/request_client.py | 27 ++++++++++++++++--- .../youtube_plugin/youtube/client/youtube.py | 27 ++++++++++--------- .../youtube/helper/stream_info.py | 25 ++++++++++------- 3 files changed, 52 insertions(+), 27 deletions(-) diff --git a/resources/lib/youtube_plugin/youtube/client/request_client.py b/resources/lib/youtube_plugin/youtube/client/request_client.py index 1f535f47e..4aec2b0a3 100644 --- a/resources/lib/youtube_plugin/youtube/client/request_client.py +++ b/resources/lib/youtube_plugin/youtube/client/request_client.py @@ -88,7 +88,7 @@ class YouTubeRequestClient(BaseRequestsClass): # Limited subtitle availability 'android_testsuite': { '_id': 30, - '_disabled': True, + '_auth_required': 'tv', '_query_subtitles': True, 'json': { 'params': _PLAYER_PARAMS['android_testsuite'], @@ -117,7 +117,7 @@ class YouTubeRequestClient(BaseRequestsClass): # Limited subtitle availability 'android_youtube_tv': { '_id': 29, - '_disabled': True, + '_auth_required': 'tv', '_query_subtitles': True, 'json': { 'params': _PLAYER_PARAMS['android'], @@ -204,6 +204,7 @@ class YouTubeRequestClient(BaseRequestsClass): }, 'media_connect_frontend': { '_id': 95, + '_auth_required': 'tv', '_query_subtitles': True, 'json': { 'context': { @@ -261,6 +262,7 @@ class YouTubeRequestClient(BaseRequestsClass): }, '_common': { '_access_token': None, + '_access_token_tv': None, 'json': { 'contentCheckOk': True, 'context': { @@ -292,7 +294,7 @@ class YouTubeRequestClient(BaseRequestsClass): 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', - 'Authorization': 'Bearer {_access_token}', + 'Authorization': None, }, 'params': { 'key': ValueError, @@ -387,13 +389,29 @@ def build_client(cls, client_name=None, data=None): if template_id in values: values[template_id] = template.format(**client) + has_auth = False try: params = client['params'] - if client.get('_access_token'): + auth_required = client.get('_auth_required') + if auth_required == 'tv': + auth_token = client.get('_access_token_tv') + else: + auth_token = client.get('_access_token') + + if auth_token: + headers = client['headers'] + if 'Authorization' in headers: + headers = headers.copy() + headers['Authorization'] = 'Bearer {0}'.format(auth_token) + client['headers'] = headers + has_auth = True + if 'key' in params: params = params.copy() del params['key'] client['params'] = params + elif auth_required: + return None else: headers = client['headers'] if 'Authorization' in headers: @@ -407,5 +425,6 @@ def build_client(cls, client_name=None, data=None): client['params'] = params except KeyError: pass + client['_has_auth'] = has_auth return client diff --git a/resources/lib/youtube_plugin/youtube/client/youtube.py b/resources/lib/youtube_plugin/youtube/client/youtube.py index 4ab1dc2de..863fa84c1 100644 --- a/resources/lib/youtube_plugin/youtube/client/youtube.py +++ b/resources/lib/youtube_plugin/youtube/client/youtube.py @@ -48,12 +48,12 @@ class YouTube(LoginClient): }, }, 3: { + '_auth_required': True, 'url': 'https://www.googleapis.com/youtube/v3/{_endpoint}', 'method': None, 'headers': { 'Host': 'www.googleapis.com', }, - 'auth_required': True, }, 'tv': { 'url': 'https://www.youtube.com/youtubei/v1/{_endpoint}', @@ -87,6 +87,7 @@ class YouTube(LoginClient): }, '_common': { '_access_token': None, + '_access_token_tv': None, 'json': { 'context': { 'client': { @@ -108,7 +109,7 @@ class YouTube(LoginClient): 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', - 'Authorization': 'Bearer {_access_token}', + 'Authorization': None, 'DNT': '1', 'User-Agent': ('Mozilla/5.0 (Linux; Android 10; SM-G981B)' ' AppleWebKit/537.36 (KHTML, like Gecko)' @@ -199,7 +200,8 @@ def get_streams(self, use_mpd=True): return StreamInfo( context, - access_token=(self._access_token or self._access_token_tv), + access_token=self._access_token, + access_token_tv=self._access_token_tv, ask_for_quality=ask_for_quality, audio_only=audio_only, use_mpd=use_mpd, @@ -2192,18 +2194,17 @@ def api_request(self, client_data['params'] = params abort = False - if no_login: - pass - # a config can decide if a token is allowed - elif self._access_token and self._config.get('token-allowed', True): - client_data['_access_token'] = self._access_token - elif self._access_token_tv: - client_data['_access_token'] = self._access_token_tv - # abort if authentication is required but not available for request - elif self.CLIENTS.get(version, {}).get('auth_required'): - abort = True + if not no_login: + # a config can decide if a token is allowed + if self._access_token and self._config.get('token-allowed', True): + client_data['_access_token'] = self._access_token + if self._access_token_tv: + client_data['_access_token_tv'] = self._access_token_tv client = self.build_client(version, client_data) + if not client: + client = {} + abort = True params = client.get('params') if 'key' in params: diff --git a/resources/lib/youtube_plugin/youtube/helper/stream_info.py b/resources/lib/youtube_plugin/youtube/helper/stream_info.py index 50044a8e2..6b3df2fcc 100644 --- a/resources/lib/youtube_plugin/youtube/helper/stream_info.py +++ b/resources/lib/youtube_plugin/youtube/helper/stream_info.py @@ -685,6 +685,7 @@ class StreamInfo(YouTubeRequestClient): def __init__(self, context, access_token='', + access_token_tv='', clients=None, ask_for_quality=False, audio_only=False, @@ -694,6 +695,7 @@ def __init__(self, self._context = context self._access_token = access_token + self._access_token_tv = access_token_tv self._ask_for_quality = ask_for_quality self._audio_only = audio_only self._language_base = kwargs.get('language', 'en_US')[0:2] @@ -716,6 +718,8 @@ def __init__(self, # Limited audio stream availability with some clients 'mpd': ( 'android_vr', + 'android_youtube_tv', + 'android_testsuite', ), # Progressive streams # Limited video and audio stream availability @@ -1392,12 +1396,13 @@ def load_stream_info(self, video_id): } abort = False - client_data = {'json': {'videoId': video_id}} - if self._access_token: - auth = True - client_data['_access_token'] = self._access_token - else: - auth = False + client_data = { + 'json': { + 'videoId': video_id, + }, + '_access_token': self._access_token, + '_access_token_tv': self._access_token_tv, + } for name, clients in self._client_groups.items(): if not clients: @@ -1423,7 +1428,7 @@ def load_stream_info(self, video_id): error_hook_kwargs={ 'video_id': video_id, 'client': client_name, - 'auth': bool(_client.get('_access_token')), + 'auth': _client.get('_has_auth', False), }, **_client ) or {} @@ -1467,7 +1472,7 @@ def load_stream_info(self, video_id): reason=reason or 'UNKNOWN', video_id=video_id, client=_client['_name'], - auth=auth, + auth=_client.get('_has_auth', False), ) ) compare_reason = reason.lower() @@ -1497,7 +1502,7 @@ def load_stream_info(self, video_id): .format( video_id=video_id, client=client_name, - auth=bool(_client.get('_access_token')), + auth=_client.get('_has_auth', False), ) ) if not self._selected_client: @@ -1686,7 +1691,7 @@ def load_stream_info(self, video_id): error_hook_kwargs={ 'video_id': video_id, 'client': client_name, - 'auth': bool(caption_client.get('_access_token')), + 'auth': _client.get('_has_auth', False), }, **caption_client )