浏览代码

[YouTube] Improve mark_watched()

Thx: Brett824, yt-dlp/yt-dlp#4146
dirkf 3 周之前
父节点
当前提交
d65882a022
共有 1 个文件被更改,包括 22 次插入19 次删除
  1. 22 19
      youtube_dl/extractor/youtube.py

+ 22 - 19
youtube_dl/extractor/youtube.py

@@ -2177,32 +2177,35 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
         return sts
 
     def _mark_watched(self, video_id, player_response):
-        playback_url = url_or_none(try_get(
-            player_response,
-            lambda x: x['playbackTracking']['videostatsPlaybackUrl']['baseUrl']))
-        if not playback_url:
-            return
-
         # cpn generation algorithm is reverse engineered from base.js.
         # In fact it works even with dummy cpn.
         CPN_ALPHABET = string.ascii_letters + string.digits + '-_'
         cpn = ''.join(CPN_ALPHABET[random.randint(0, 256) & 63] for _ in range(16))
 
-        # more consistent results setting it to right before the end
-        qs = parse_qs(playback_url)
-        video_length = '{0}'.format(float((qs.get('len') or ['1.5'])[0]) - 1)
+        for is_full, key in enumerate(('videostatsPlaybackUrl', 'videostatsWatchtimeUrl')):
+            label = 'fully ' if is_full > 0 else ''
 
-        playback_url = update_url_query(
-            playback_url, {
-                'ver': '2',
-                'cpn': cpn,
-                'cmt': video_length,
-                'el': 'detailpage',  # otherwise defaults to "shorts"
-            })
+            playback_url = traverse_obj(player_response, (
+                'playbackTracking'. key, 'baseUrl', T(url_or_none)))
+            if not playback_url:
+                self.report_warning('Unable to mark {0}watched'.format(label))
+                continue
+
+            # more consistent results setting it to right before the end
+            qs = parse_qs(playback_url)
+            video_length = '{0}'.format(float((qs.get('len') or ['1.5'])[0]) - 1)
+
+            playback_url = update_url_query(
+                playback_url, {
+                    'ver': '2',
+                    'cpn': cpn,
+                    'cmt': video_length,
+                    'el': 'detailpage',  # otherwise defaults to "shorts"
+                })
 
-        self._download_webpage(
-            playback_url, video_id, 'Marking watched',
-            'Unable to mark watched', fatal=False)
+            self._download_webpage(
+                playback_url, video_id, 'Marking {0}watched'.format(label),
+                'Unable to mark watched', fatal=False)
 
     @staticmethod
     def _extract_urls(webpage):