From 2bee48cffdc027ec1644ea7929e2a22b39ad2978 Mon Sep 17 00:00:00 2001 From: Rico van Zelst Date: Thu, 8 May 2025 15:01:34 +0200 Subject: [PATCH] [ie/youtube] Make short views type an extractor argument - Add `short_views_type` as an extractor argument to address [#13122](https://github.com/yt-dlp/yt-dlp/issues/13122#issuecomment-2862720272) --- README.md | 1 + test/helper.py | 2 +- yt_dlp/extractor/common.py | 1 - yt_dlp/extractor/youtube/_video.py | 5 +++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a87b52832..2df467ab5 100644 --- a/README.md +++ b/README.md @@ -1806,6 +1806,7 @@ #### youtube * `visitor_data`: Overrides the Visitor Data used in Innertube API requests. This should be used with `player_skip=webpage,configs` and without cookies. Note: this may have adverse effects if used improperly. If a session from a browser is wanted, you should pass cookies instead (which contain the Visitor ID) * `po_token`: Proof of Origin (PO) Token(s) to use. Comma seperated list of PO Tokens in the format `CLIENT.CONTEXT+PO_TOKEN`, e.g. `youtube:po_token=web.gvs+XXX,web.player=XXX,web_safari.gvs+YYY`. Context can be either `gvs` (Google Video Server URLs) or `player` (Innertube player request) * `player_js_variant`: The player javascript variant to use for signature and nsig deciphering. The known variants are: `main`, `tce`, `tv`, `tv_es6`, `phone`, `tablet`. Only `main` is recommended as a possible workaround; the others are for debugging purposes. The default is to use what is prescribed by the site, and can be selected with `actual` +* `short_views_type`: The type of views to use for a short its view count. The available types are: `engaged` (default) and `seen`. #### youtubetab (YouTube playlists, channels, feeds, etc.) * `skip`: One or more of `webpage` (skip initial webpage download), `authcheck` (allow the download of playlists requiring authentication when no initial webpage is downloaded. This may cause unwanted behavior, see [#1122](https://github.com/yt-dlp/yt-dlp/pull/1122) for more details) diff --git a/test/helper.py b/test/helper.py index 5b6746f33..e4cb478e2 100644 --- a/test/helper.py +++ b/test/helper.py @@ -263,7 +263,7 @@ def expect_info_dict(self, got_dict, expected_dict): # NB: Keep in sync with the docstring of extractor/common.py 'id', 'ext', 'direct', 'display_id', 'title', 'alt_title', 'description', 'media_type', 'uploader', 'uploader_id', 'uploader_url', 'channel', 'channel_id', 'channel_url', 'channel_is_verified', - 'channel_follower_count', 'comment_count', 'view_count', 'concurrent_view_count', 'engaged_view_count', + 'channel_follower_count', 'comment_count', 'view_count', 'concurrent_view_count', 'like_count', 'dislike_count', 'repost_count', 'average_rating', 'age_limit', 'duration', 'thumbnail', 'heatmap', 'chapters', 'chapter', 'chapter_number', 'chapter_id', 'start_time', 'end_time', 'section_start', 'section_end', 'categories', 'tags', 'cast', 'composers', 'artists', 'album_artists', 'creators', 'genres', diff --git a/yt_dlp/extractor/common.py b/yt_dlp/extractor/common.py index 399fae74d..d5607296d 100644 --- a/yt_dlp/extractor/common.py +++ b/yt_dlp/extractor/common.py @@ -337,7 +337,6 @@ class InfoExtractor: duration: Length of the video in seconds, as an integer or float. view_count: How many users have watched the video on the platform. concurrent_view_count: How many users are currently watching the video on the platform. - engaged_view_count: How many engaged users have watched the video on the platform. like_count: Number of positive ratings of the video dislike_count: Number of negative ratings of the video repost_count: Number of reposts of the video diff --git a/yt_dlp/extractor/youtube/_video.py b/yt_dlp/extractor/youtube/_video.py index 8bab8e18c..21848a894 100644 --- a/yt_dlp/extractor/youtube/_video.py +++ b/yt_dlp/extractor/youtube/_video.py @@ -3999,6 +3999,8 @@ def process_language(container, base_url, lang_code, sub_name, query): 'toggleButtonViewModel', 'toggleButtonViewModel', 'defaultButtonViewModel', 'buttonViewModel', 'accessibilityText', {parse_count}), get_all=False) + short_views_type = self._configuration_arg('short_views_type', ['engaged'])[0].lower() + vcr = traverse_obj(vpir, ('viewCount', 'videoViewCountRenderer')) if vcr: vc = self._get_count(vcr, 'viewCount') @@ -4007,8 +4009,7 @@ def process_language(container, base_url, lang_code, sub_name, query): info['concurrent_view_count'] = vc elif info.get('view_count') is None: info['view_count'] = vc - elif get_first(microformats, 'isShortsEligible'): - info['engaged_view_count'] = info['view_count'] + elif get_first(microformats, 'isShortsEligible') and short_views_type == 'seen': info['view_count'] = vc vsir = get_first(contents, 'videoSecondaryInfoRenderer')