aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcoletdjnz <colethedj@protonmail.com>2021-12-24 03:42:02 +0000
committerGitHub <noreply@github.com>2021-12-24 03:42:02 +0000
commita709d87335fb33be0e94a6292f5c6f094b266541 (patch)
treeff733962d2218952bc8d100e41ecccd4748ed1e8
parent774a46c53dc75eae68d11abdc40b7fe7e1e828ca (diff)
downloadhypervideo-pre-a709d87335fb33be0e94a6292f5c6f094b266541.tar.lz
hypervideo-pre-a709d87335fb33be0e94a6292f5c6f094b266541.tar.xz
hypervideo-pre-a709d87335fb33be0e94a6292f5c6f094b266541.zip
[youtube:tab] Extract video thumbnails from playlist (#2096)
closes #1184 Co-Authored-by: coletdjnz, pukkandan
-rw-r--r--yt_dlp/extractor/youtube.py73
1 files changed, 34 insertions, 39 deletions
diff --git a/yt_dlp/extractor/youtube.py b/yt_dlp/extractor/youtube.py
index 1f5009399..d79ee414b 100644
--- a/yt_dlp/extractor/youtube.py
+++ b/yt_dlp/extractor/youtube.py
@@ -668,6 +668,30 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
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
def extract_relative_time(relative_time_text):
"""
Extracts a relative time from string and converts to dt object
@@ -783,6 +807,8 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
overlay_style = traverse_obj(
renderer, ('thumbnailOverlays', ..., 'thumbnailOverlayTimeStatusRenderer', 'style'), get_all=False, expected_type=str)
badges = self._extract_badges(renderer)
+ thumbnails = self._extract_thumbnails(renderer, 'thumbnail')
+
return {
'_type': 'url',
'ie_key': YoutubeIE.ie_key(),
@@ -794,6 +820,7 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
'view_count': view_count,
'uploader': uploader,
'channel_id': channel_id,
+ 'thumbnails': thumbnails,
'upload_date': strftime_or_none(timestamp, '%Y%m%d'),
'live_status': ('is_upcoming' if scheduled_timestamp is not None
else 'was_live' if 'streamed' in time_text.lower()
@@ -2903,25 +2930,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
if f.get('vcodec') != 'none':
f['stretched_ratio'] = ratio
break
-
- 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')),
- })
+ thumbnails = self._extract_thumbnails((video_details, microformats), (..., ..., 'thumbnail'))
thumbnail_url = search_meta(['og:image', 'twitter:image'])
if thumbnail_url:
thumbnails.append({
@@ -3584,7 +3593,6 @@ class YoutubeTabBaseInfoExtractor(YoutubeBaseInfoExtractor):
def _extract_from_tabs(self, item_id, ytcfg, data, tabs):
playlist_id = title = description = channel_url = channel_name = channel_id = None
- thumbnails_list = []
tags = []
selected_tab = self._extract_selected_tab(tabs)
@@ -3603,26 +3611,13 @@ class YoutubeTabBaseInfoExtractor(YoutubeBaseInfoExtractor):
description = renderer.get('description', '')
playlist_id = channel_id
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 = []
- for t in thumbnails_list:
- if not isinstance(t, dict):
- continue
- thumbnail_url = url_or_none(t.get('url'))
- if not thumbnail_url:
- continue
- thumbnails.append({
- 'url': thumbnail_url,
- 'width': int_or_none(t.get('width')),
- 'height': int_or_none(t.get('height')),
- })
+ thumbnails = (
+ self._extract_thumbnails(renderer, 'avatar')
+ or self._extract_thumbnails(
+ self._extract_sidebar_info_renderer(data, 'playlistSidebarPrimaryInfoRenderer'),
+ ('thumbnailRenderer', 'playlistVideoThumbnailRenderer', 'thumbnail')))
+
if playlist_id is None:
playlist_id = item_id
if title is None: