mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2026-06-20 01:35:41 +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)
|
only_once=True)
|
||||||
return
|
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(
|
return self.url_result(
|
||||||
url, ie, content_id,
|
url, ie, content_id,
|
||||||
title=traverse_obj(view_model, (
|
title=traverse_obj(lockup_mdvm, ('title', 'content', {str})),
|
||||||
'metadata', 'lockupMetadataViewModel', 'title', 'content', {str})),
|
|
||||||
thumbnails=self._extract_thumbnails(view_model, (
|
thumbnails=self._extract_thumbnails(view_model, (
|
||||||
'contentImage', *thumb_keys, 'thumbnailViewModel', 'image'), final_key='sources'),
|
'contentImage', *thumb_keys, 'thumbnailViewModel', 'image'), final_key='sources'),
|
||||||
duration=traverse_obj(view_model, (
|
duration=parse_duration(duration_text),
|
||||||
'contentImage', 'thumbnailViewModel', 'overlays', ...,
|
view_count=(
|
||||||
(('thumbnailBottomOverlayViewModel', 'badges'), ('thumbnailOverlayBadgeViewModel', 'thumbnailBadges')),
|
traverse_obj(views_and_time, (0, 'text', 'content', {parse_count}))
|
||||||
..., 'thumbnailBadgeViewModel', 'text', {parse_duration}, any)),
|
# view_count isn't always available; only extract if this metadataRow is 2 metadataParts
|
||||||
timestamp=(traverse_obj(view_model, (
|
if len(views_and_time) == 2 else None),
|
||||||
'metadata', 'lockupMetadataViewModel', 'metadata', 'contentMetadataViewModel', 'metadataRows',
|
timestamp=(
|
||||||
..., 'metadataParts', ..., 'text', 'content', {lambda t: self._parse_time_text(t, report_failure=False)}, any))
|
self._parse_time_text(relative_time_text, report_failure=False)
|
||||||
if self._configuration_arg('approximate_date', ie_key=YoutubeTabIE) else None))
|
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):
|
def _rich_entries(self, rich_grid_renderer):
|
||||||
if lockup_view_model := traverse_obj(rich_grid_renderer, ('content', 'lockupViewModel', {dict})):
|
if lockup_view_model := traverse_obj(rich_grid_renderer, ('content', 'lockupViewModel', {dict})):
|
||||||
@ -1588,7 +1626,7 @@ class YoutubeTabIE(YoutubeTabBaseInfoExtractor):
|
|||||||
'playlist_count': 50,
|
'playlist_count': 50,
|
||||||
'expected_warnings': ['YouTube Music is not directly supported'],
|
'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',
|
'note': 'unlisted single video playlist',
|
||||||
'url': 'https://www.youtube.com/playlist?list=PLt5yu3-wZAlQLfIN0MMgp0wVV6MP3bM4_',
|
'url': 'https://www.youtube.com/playlist?list=PLt5yu3-wZAlQLfIN0MMgp0wVV6MP3bM4_',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user