]> jfr.im git - yt-dlp.git/commitdiff
[youtube] Fix session index extraction and headers for non-web player clients (#526)
authorcoletdjnz <redacted>
Sun, 18 Jul 2021 06:23:32 +0000 (18:23 +1200)
committerGitHub <redacted>
Sun, 18 Jul 2021 06:23:32 +0000 (06:23 +0000)
Fixes #522

yt_dlp/extractor/youtube.py

index e7ac41cb120a2db068ab5de90e67cb1617ea7ad8..027b219dd53abff23762dc02596c50c52b14d437 100644 (file)
@@ -416,6 +416,10 @@ def _ytcfg_get_safe(self, ytcfg, getter, expected_type=None, default_client='WEB
     def _extract_client_name(self, ytcfg, default_client='WEB'):
         return self._ytcfg_get_safe(ytcfg, lambda x: x['INNERTUBE_CLIENT_NAME'], compat_str, default_client)
 
+    @staticmethod
+    def _extract_session_index(ytcfg):
+        return int_or_none(try_get(ytcfg, lambda x: x['SESSION_INDEX']))
+
     def _extract_client_version(self, ytcfg, default_client='WEB'):
         return self._ytcfg_get_safe(ytcfg, lambda x: x['INNERTUBE_CLIENT_VERSION'], compat_str, default_client)
 
@@ -518,7 +522,7 @@ def _extract_ytcfg(self, video_id, webpage):
                 default='{}'), video_id, fatal=False) or {}
 
     def _generate_api_headers(self, ytcfg=None, identity_token=None, account_syncid=None,
-                              visitor_data=None, api_hostname=None, client='WEB'):
+                              visitor_data=None, api_hostname=None, client='WEB', session_index=None):
         origin = 'https://' + (api_hostname if api_hostname else self._get_innertube_host(client))
         headers = {
             'X-YouTube-Client-Name': compat_str(
@@ -533,9 +537,10 @@ def _generate_api_headers(self, ytcfg=None, identity_token=None, account_syncid=
             headers['X-Youtube-Identity-Token'] = identity_token
         if account_syncid:
             headers['X-Goog-PageId'] = account_syncid
-        session_index = try_get(ytcfg, lambda x: x['SESSION_INDEX'], compat_str)
-        if account_syncid or session_index:
-            headers['X-Goog-AuthUser'] = session_index or 0
+        if session_index is None and ytcfg:
+            session_index = self._extract_session_index(ytcfg)
+        if account_syncid or session_index is not None:
+            headers['X-Goog-AuthUser'] = session_index if session_index is not None else 0
         if visitor_data:
             headers['X-Goog-Visitor-Id'] = visitor_data
         auth = self._generate_sapisidhash_header(origin)
@@ -2294,8 +2299,8 @@ def _real_extract(self, url):
         ytcfg = self._extract_ytcfg(video_id, webpage) or self._get_default_ytcfg()
         identity_token = self._extract_identity_token(webpage, video_id)
         syncid = self._extract_account_syncid(ytcfg)
-        headers = self._generate_api_headers(ytcfg, identity_token, syncid)
-
+        session_index = self._extract_session_index(ytcfg)
+        headers = self._generate_api_headers(ytcfg, identity_token, syncid, session_index=session_index)
         player_url = self._extract_player_url(ytcfg, webpage)
 
         player_client = self._configuration_arg('player_client', [''])[0]
@@ -2336,7 +2341,7 @@ def get_text(x):
 
             ytm_headers = self._generate_api_headers(
                 ytm_cfg, identity_token, syncid,
-                client=ytm_client)
+                client=ytm_client, session_index=session_index)
             ytm_query = {'videoId': video_id}
             ytm_query.update(self._generate_player_context(sts))
 
@@ -2365,7 +2370,8 @@ def get_text(x):
                     self.report_warning('Falling back to android client for player API.')
                 yt_client = 'ANDROID'
                 ytpcfg = {}
-                ytp_headers = self._generate_api_headers(ytpcfg, identity_token, syncid, yt_client)
+                ytp_headers = self._generate_api_headers(ytpcfg, identity_token, syncid,
+                                                         client=yt_client, session_index=session_index)
 
             yt_query = {'videoId': video_id}
             yt_query.update(self._generate_player_context(sts))
@@ -2418,7 +2424,8 @@ def get_text(x):
                         ytcfg_age = {}
 
                     ytage_headers = self._generate_api_headers(
-                        ytcfg_age, identity_token, syncid, client=yt_client)
+                        ytcfg_age, identity_token, syncid,
+                        client=yt_client, session_index=session_index)
                     yt_age_query = {'videoId': video_id}
                     yt_age_query.update(self._generate_player_context(sts))
                     pr = self._extract_response(