1
0
mirror of https://github.com/ytdl-org/youtube-dl synced 2025-12-04 10:33:48 +00:00

[YouTube] Improve mark_watched()

Thx: Brett824, yt-dlp/yt-dlp#4146
This commit is contained in:
dirkf 2025-11-04 21:43:43 +00:00
parent 39378f7b5c
commit d65882a022

View File

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