aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordirkf <fieldhouse@gmx.net>2025-11-04 21:43:43 +0000
committerdirkf <fieldhouse@gmx.net>2025-11-21 01:52:11 +0000
commitd65882a0220b5c7dd25b16b90ed6d273aac264d9 (patch)
treeb38894bddafb5f8c89acec3b935ee336717c2320
parent39378f7b5cdd6e11ff0ba6ec0f6b4a7788cfea9a (diff)
[YouTube] Improve mark_watched()
Thx: Brett824, yt-dlp/yt-dlp#4146
-rw-r--r--youtube_dl/extractor/youtube.py41
1 files changed, 22 insertions, 19 deletions
diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py
index c0b097fbe..4a61abcc5 100644
--- a/youtube_dl/extractor/youtube.py
+++ b/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):