[youtube:tab] Extract video thumbnails from playlist (#2096)

closes #1184
Co-Authored-by: coletdjnz, pukkandan
This commit is contained in:
coletdjnz 2021-12-24 03:42:02 +00:00 committed by GitHub
parent 774a46c53d
commit a709d87335
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -667,6 +667,30 @@ def _get_text(data, *path_list, max_runs=None):
if text: if text:
return text return text
@staticmethod
def _extract_thumbnails(data, *path_list):
"""
Extract thumbnails from thumbnails dict
@param path_list: path list to level that contains 'thumbnails' key
"""
thumbnails = []
for path in path_list or [()]:
for thumbnail in traverse_obj(data, (*variadic(path), 'thumbnails', ...), default=[]):
thumbnail_url = url_or_none(thumbnail.get('url'))
if not thumbnail_url:
continue
# Sometimes youtube gives a wrong thumbnail URL. See:
# https://github.com/yt-dlp/yt-dlp/issues/233
# https://github.com/ytdl-org/youtube-dl/issues/28023
if 'maxresdefault' in thumbnail_url:
thumbnail_url = thumbnail_url.split('?')[0]
thumbnails.append({
'url': thumbnail_url,
'height': int_or_none(thumbnail.get('height')),
'width': int_or_none(thumbnail.get('width')),
})
return thumbnails
@staticmethod @staticmethod
def extract_relative_time(relative_time_text): def extract_relative_time(relative_time_text):
""" """
@ -783,6 +807,8 @@ def _extract_video(self, renderer):
overlay_style = traverse_obj( overlay_style = traverse_obj(
renderer, ('thumbnailOverlays', ..., 'thumbnailOverlayTimeStatusRenderer', 'style'), get_all=False, expected_type=str) renderer, ('thumbnailOverlays', ..., 'thumbnailOverlayTimeStatusRenderer', 'style'), get_all=False, expected_type=str)
badges = self._extract_badges(renderer) badges = self._extract_badges(renderer)
thumbnails = self._extract_thumbnails(renderer, 'thumbnail')
return { return {
'_type': 'url', '_type': 'url',
'ie_key': YoutubeIE.ie_key(), 'ie_key': YoutubeIE.ie_key(),
@ -794,6 +820,7 @@ def _extract_video(self, renderer):
'view_count': view_count, 'view_count': view_count,
'uploader': uploader, 'uploader': uploader,
'channel_id': channel_id, 'channel_id': channel_id,
'thumbnails': thumbnails,
'upload_date': strftime_or_none(timestamp, '%Y%m%d'), 'upload_date': strftime_or_none(timestamp, '%Y%m%d'),
'live_status': ('is_upcoming' if scheduled_timestamp is not None 'live_status': ('is_upcoming' if scheduled_timestamp is not None
else 'was_live' if 'streamed' in time_text.lower() else 'was_live' if 'streamed' in time_text.lower()
@ -2903,25 +2930,7 @@ def feed_entry(name):
if f.get('vcodec') != 'none': if f.get('vcodec') != 'none':
f['stretched_ratio'] = ratio f['stretched_ratio'] = ratio
break break
thumbnails = self._extract_thumbnails((video_details, microformats), (..., ..., 'thumbnail'))
thumbnails = []
thumbnail_dicts = traverse_obj(
(video_details, microformats), (..., ..., 'thumbnail', 'thumbnails', ...),
expected_type=dict, default=[])
for thumbnail in thumbnail_dicts:
thumbnail_url = thumbnail.get('url')
if not thumbnail_url:
continue
# Sometimes youtube gives a wrong thumbnail URL. See:
# https://github.com/yt-dlp/yt-dlp/issues/233
# https://github.com/ytdl-org/youtube-dl/issues/28023
if 'maxresdefault' in thumbnail_url:
thumbnail_url = thumbnail_url.split('?')[0]
thumbnails.append({
'url': thumbnail_url,
'height': int_or_none(thumbnail.get('height')),
'width': int_or_none(thumbnail.get('width')),
})
thumbnail_url = search_meta(['og:image', 'twitter:image']) thumbnail_url = search_meta(['og:image', 'twitter:image'])
if thumbnail_url: if thumbnail_url:
thumbnails.append({ thumbnails.append({
@ -3584,7 +3593,6 @@ def _extract_uploader(cls, data):
def _extract_from_tabs(self, item_id, ytcfg, data, tabs): def _extract_from_tabs(self, item_id, ytcfg, data, tabs):
playlist_id = title = description = channel_url = channel_name = channel_id = None playlist_id = title = description = channel_url = channel_name = channel_id = None
thumbnails_list = []
tags = [] tags = []
selected_tab = self._extract_selected_tab(tabs) selected_tab = self._extract_selected_tab(tabs)
@ -3603,26 +3611,13 @@ def _extract_from_tabs(self, item_id, ytcfg, data, tabs):
description = renderer.get('description', '') description = renderer.get('description', '')
playlist_id = channel_id playlist_id = channel_id
tags = renderer.get('keywords', '').split() tags = renderer.get('keywords', '').split()
thumbnails_list = (
try_get(renderer, lambda x: x['avatar']['thumbnails'], list)
or try_get(
self._extract_sidebar_info_renderer(data, 'playlistSidebarPrimaryInfoRenderer'),
lambda x: x['thumbnailRenderer']['playlistVideoThumbnailRenderer']['thumbnail']['thumbnails'],
list)
or [])
thumbnails = [] thumbnails = (
for t in thumbnails_list: self._extract_thumbnails(renderer, 'avatar')
if not isinstance(t, dict): or self._extract_thumbnails(
continue self._extract_sidebar_info_renderer(data, 'playlistSidebarPrimaryInfoRenderer'),
thumbnail_url = url_or_none(t.get('url')) ('thumbnailRenderer', 'playlistVideoThumbnailRenderer', 'thumbnail')))
if not thumbnail_url:
continue
thumbnails.append({
'url': thumbnail_url,
'width': int_or_none(t.get('width')),
'height': int_or_none(t.get('height')),
})
if playlist_id is None: if playlist_id is None:
playlist_id = item_id playlist_id = item_id
if title is None: if title is None: