mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2026-06-17 08:14:38 +00:00
[ie/youtube:tab] Fix flat playlist metadata extraction (#16965)
Closes #13879, Closes #16665, Closes #16952 Authored by: bashonly
This commit is contained in:
parent
8902f6ba8c
commit
ad6b5f4b35
@ -333,20 +333,58 @@ class YoutubeTabBaseInfoExtractor(YoutubeBaseInfoExtractor):
|
||||
only_once=True)
|
||||
return
|
||||
|
||||
lockup_mdvm = traverse_obj(view_model, ('metadata', 'lockupMetadataViewModel', {dict}))
|
||||
content_mdvm = traverse_obj(lockup_mdvm, ('metadata', 'contentMetadataViewModel', {dict}))
|
||||
|
||||
thumbnail_badge_view_models = traverse_obj(view_model, (
|
||||
'contentImage', 'thumbnailViewModel', 'overlays', ..., (
|
||||
('thumbnailBottomOverlayViewModel', 'badges'),
|
||||
('thumbnailOverlayBadgeViewModel', 'thumbnailBadges'),
|
||||
), ..., 'thumbnailBadgeViewModel', {dict}))
|
||||
duration_text = traverse_obj(thumbnail_badge_view_models, (..., 'text', {str.lower}, any))
|
||||
thumbnail_badge_styles = traverse_obj(thumbnail_badge_view_models, (..., 'badgeStyle', {str}))
|
||||
|
||||
channel_info = traverse_obj(content_mdvm, (
|
||||
'metadataRows', ..., 'metadataParts',
|
||||
lambda _, v: v['text']['commandRuns'][0]['onTap']['innertubeCommand']['browseEndpoint']['browseId'],
|
||||
'text', any, {
|
||||
'channel': ('content', {str}),
|
||||
'channel_id': ('commandRuns', 0, 'onTap', 'innertubeCommand', 'browseEndpoint', 'browseId', {self.ucid_or_none}),
|
||||
'uploader': ('content', {str}),
|
||||
'uploader_id': ('commandRuns', 0, 'onTap', 'innertubeCommand', 'browseEndpoint', 'canonicalBaseUrl', {self.handle_from_url}),
|
||||
}))
|
||||
|
||||
views_and_time = traverse_obj(content_mdvm, (
|
||||
'metadataRows', lambda _, v: 'accessibilityLabel' in v['metadataParts'][-1],
|
||||
'metadataParts', ...))
|
||||
relative_time_text = traverse_obj(views_and_time, (-1, 'text', 'content', {str.lower}))
|
||||
|
||||
badge_styles = traverse_obj(content_mdvm, (
|
||||
'metadataRows', ..., 'badges', ..., 'badgeViewModel', 'badgeStyle', {str}))
|
||||
|
||||
return self.url_result(
|
||||
url, ie, content_id,
|
||||
title=traverse_obj(view_model, (
|
||||
'metadata', 'lockupMetadataViewModel', 'title', 'content', {str})),
|
||||
title=traverse_obj(lockup_mdvm, ('title', 'content', {str})),
|
||||
thumbnails=self._extract_thumbnails(view_model, (
|
||||
'contentImage', *thumb_keys, 'thumbnailViewModel', 'image'), final_key='sources'),
|
||||
duration=traverse_obj(view_model, (
|
||||
'contentImage', 'thumbnailViewModel', 'overlays', ...,
|
||||
(('thumbnailBottomOverlayViewModel', 'badges'), ('thumbnailOverlayBadgeViewModel', 'thumbnailBadges')),
|
||||
..., 'thumbnailBadgeViewModel', 'text', {parse_duration}, any)),
|
||||
timestamp=(traverse_obj(view_model, (
|
||||
'metadata', 'lockupMetadataViewModel', 'metadata', 'contentMetadataViewModel', 'metadataRows',
|
||||
..., 'metadataParts', ..., 'text', 'content', {lambda t: self._parse_time_text(t, report_failure=False)}, any))
|
||||
if self._configuration_arg('approximate_date', ie_key=YoutubeTabIE) else None))
|
||||
duration=parse_duration(duration_text),
|
||||
view_count=(
|
||||
traverse_obj(views_and_time, (0, 'text', 'content', {parse_count}))
|
||||
# view_count isn't always available; only extract if this metadataRow is 2 metadataParts
|
||||
if len(views_and_time) == 2 else None),
|
||||
timestamp=(
|
||||
self._parse_time_text(relative_time_text, report_failure=False)
|
||||
if self._configuration_arg('approximate_date', ie_key=YoutubeTabIE) else None),
|
||||
live_status=(
|
||||
'is_upcoming' if duration_text == 'upcoming'
|
||||
else 'is_live' if 'THUMBNAIL_OVERLAY_BADGE_STYLE_LIVE' in thumbnail_badge_styles
|
||||
else 'was_live' if relative_time_text and 'streamed' in relative_time_text
|
||||
else None),
|
||||
# XXX: We cannot assume 'public' since we have no way to differentiate from 'unlisted'
|
||||
availability=self._availability(needs_subscription='BADGE_MEMBERS_ONLY' in badge_styles),
|
||||
channel_url=format_field(channel_info, 'channel_id', 'https://www.youtube.com/channel/%s', default=None),
|
||||
uploader_url=format_field(channel_info, 'uploader_id', 'https://www.youtube.com/%s', default=None),
|
||||
**channel_info)
|
||||
|
||||
def _rich_entries(self, rich_grid_renderer):
|
||||
if lockup_view_model := traverse_obj(rich_grid_renderer, ('content', 'lockupViewModel', {dict})):
|
||||
@ -1588,7 +1626,7 @@ class YoutubeTabIE(YoutubeTabBaseInfoExtractor):
|
||||
'playlist_count': 50,
|
||||
'expected_warnings': ['YouTube Music is not directly supported'],
|
||||
}, {
|
||||
# TODO: investigate test failing on differing channel*/uploader*/view_count
|
||||
# YoutubeTab_25: use to test _extract_lockup_view_model
|
||||
'note': 'unlisted single video playlist',
|
||||
'url': 'https://www.youtube.com/playlist?list=PLt5yu3-wZAlQLfIN0MMgp0wVV6MP3bM4_',
|
||||
'info_dict': {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user