diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index 5985d2ec76..c44a661a70 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -306,6 +306,7 @@ class YoutubeDL: unless writeinfojson is also given writeannotations: Write the video annotations to a .annotations.xml file writethumbnail: Write the thumbnail image to a file + thumbnail_format: Format code of thumbnail to write allow_playlist_files: Whether to write playlists' description, infojson etc also to disk when using the 'write*' options write_all_thumbnails: Write all thumbnail formats to files @@ -4442,9 +4443,24 @@ class YoutubeDL: def _write_thumbnails(self, label, info_dict, filename, thumb_filename_base=None): """ Write thumbnails to file and return list of (thumb_filename, final_thumb_filename); or None if error """ write_all = self.params.get('write_all_thumbnails', False) + write_any = write_all or self.params.get('writethumbnail', False) thumbnails, ret = [], [] - if write_all or self.params.get('writethumbnail', False): - thumbnails = info_dict.get('thumbnails') or [] + + if write_any: + all_thumbnails = info_dict.get('thumbnails') or [] + thumbnail_id = self.params.get('thumbnail_format') + if thumbnail_id and not write_all: + for t in all_thumbnails: + if t.get('id') == thumbnail_id: + thumbnails.append(t) + break + else: + self.raise_no_formats( + info_dict, msg=('Invalid thumbnail ID specified. Use --list-thumbnails to see available IDs'), + ) + else: + thumbnails = all_thumbnails + if not thumbnails: self.to_screen(f'[info] There are no {label} thumbnails to download') return ret diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py index f705bed1bf..4fa5e22377 100644 --- a/yt_dlp/__init__.py +++ b/yt_dlp/__init__.py @@ -883,6 +883,7 @@ def parse_options(argv=None): 'clean_infojson': opts.clean_infojson, 'getcomments': opts.getcomments, 'writethumbnail': opts.writethumbnail is True, + 'thumbnail_format': opts.thumbnail_format, 'write_all_thumbnails': opts.writethumbnail == 'all', 'writelink': opts.writelink, 'writeurllink': opts.writeurllink, diff --git a/yt_dlp/options.py b/yt_dlp/options.py index 13ba445df3..c024d5fb6f 100644 --- a/yt_dlp/options.py +++ b/yt_dlp/options.py @@ -1578,6 +1578,10 @@ def create_parser(): '--no-write-thumbnail', action='store_false', dest='writethumbnail', help='Do not write thumbnail image to disk (default)') + thumbnail.add_option( + '--thumbnail-format', + metavar='format', dest='thumbnail_format', + help='Format code of thumbnail to write to disk') thumbnail.add_option( '--write-all-thumbnails', action='store_const', dest='writethumbnail', const='all', diff --git a/yt_dlp/postprocessor/embedthumbnail.py b/yt_dlp/postprocessor/embedthumbnail.py index 39e8826c6f..28484ff6a2 100644 --- a/yt_dlp/postprocessor/embedthumbnail.py +++ b/yt_dlp/postprocessor/embedthumbnail.py @@ -62,7 +62,10 @@ class EmbedThumbnailPP(FFmpegPostProcessor): self.to_screen('There aren\'t any thumbnails to embed') return [], info - idx = next((-i for i, t in enumerate(info['thumbnails'][::-1], 1) if t.get('filepath')), None) + if self._downloader and (fmt := self._downloader.params.get('thumbnail_format')): + idx = next((i for i, t in enumerate(info['thumbnails']) if t.get('id') == fmt and t.get('filepath')), None) + else: + idx = next((-i for i, t in enumerate(info['thumbnails'][::-1], 1) if t.get('filepath')), None) if idx is None: self.to_screen('There are no thumbnails on disk') return [], info