[FEATURE] square_thumbnail plugin

This commit is contained in:
Jesse Bannon 2025-06-18 21:49:25 -07:00
parent f6bce88ebd
commit 701358b880
2 changed files with 80 additions and 0 deletions

View file

@ -24,6 +24,7 @@ from ytdl_sub.plugins.music_tags import MusicTagsPlugin
from ytdl_sub.plugins.nfo_tags import NfoTagsPlugin from ytdl_sub.plugins.nfo_tags import NfoTagsPlugin
from ytdl_sub.plugins.output_directory_nfo_tags import OutputDirectoryNfoTagsPlugin from ytdl_sub.plugins.output_directory_nfo_tags import OutputDirectoryNfoTagsPlugin
from ytdl_sub.plugins.split_by_chapters import SplitByChaptersPlugin from ytdl_sub.plugins.split_by_chapters import SplitByChaptersPlugin
from ytdl_sub.plugins.square_thumbnail import SquareThumbnailPlugin
from ytdl_sub.plugins.static_nfo_tags import StaticNfoTagsPlugin from ytdl_sub.plugins.static_nfo_tags import StaticNfoTagsPlugin
from ytdl_sub.plugins.subtitles import SubtitlesPlugin from ytdl_sub.plugins.subtitles import SubtitlesPlugin
from ytdl_sub.plugins.throttle_protection import ThrottleProtectionPlugin from ytdl_sub.plugins.throttle_protection import ThrottleProtectionPlugin
@ -40,6 +41,7 @@ class PluginMapping:
"audio_extract": AudioExtractPlugin, "audio_extract": AudioExtractPlugin,
"date_range": DateRangePlugin, "date_range": DateRangePlugin,
"embed_thumbnail": EmbedThumbnailPlugin, "embed_thumbnail": EmbedThumbnailPlugin,
"square_thumbnail": SquareThumbnailPlugin,
"file_convert": FileConvertPlugin, "file_convert": FileConvertPlugin,
"format": FormatPlugin, "format": FormatPlugin,
"match_filters": MatchFiltersPlugin, "match_filters": MatchFiltersPlugin,
@ -86,6 +88,7 @@ class PluginMapping:
VideoTagsPlugin, VideoTagsPlugin,
NfoTagsPlugin, NfoTagsPlugin,
StaticNfoTagsPlugin, StaticNfoTagsPlugin,
SquareThumbnailPlugin,
EmbedThumbnailPlugin, EmbedThumbnailPlugin,
] ]

View file

@ -0,0 +1,77 @@
from typing import List
from typing import Optional
from ytdl_sub.config.plugin.plugin import Plugin
from ytdl_sub.config.validators.options import OptionsValidator
from ytdl_sub.entries.entry import Entry
from ytdl_sub.utils.ffmpeg import FFMPEG
from ytdl_sub.utils.file_handler import FileHandler
from ytdl_sub.utils.file_handler import FileMetadata
from ytdl_sub.utils.logger import Logger
from ytdl_sub.validators.string_formatter_validators import OverridesBooleanFormatterValidator
logger = Logger.get("square-thumbnail")
class SquareThumbnailOptions(OverridesBooleanFormatterValidator, OptionsValidator):
"""
Whether to make thumbnails square. Supports both file and embedded-based thumbnails. Ideal
for representing audio albums.
:Usage:
.. code-block:: yaml
square_thumbnail: True
"""
class SquareThumbnailPlugin(Plugin[SquareThumbnailOptions]):
plugin_options_type = SquareThumbnailOptions
@property
def _square_thumbnail(self) -> bool:
return self.overrides.evaluate_boolean(self.plugin_options)
@classmethod
def _convert_to_square_thumbnail(cls, entry: Entry) -> None:
thumbnail_path = entry.get_download_thumbnail_path()
tmp_file_path = FFMPEG.tmp_file_path(thumbnail_path)
try:
ffmpeg_args: List[str] = [
"-i",
thumbnail_path,
"-c:v"
"mjpeg"
"-qmin"
"1"
"-qscale:v"
"1"
"-vf"
"crop=min(iw\\,ih):min(iw\\,ih)"
"-bitexact", # for reproducibility
tmp_file_path,
]
FFMPEG.run(ffmpeg_args)
FileHandler.move(tmp_file_path, thumbnail_path)
finally:
FileHandler.delete(tmp_file_path)
def post_process_entry(self, entry: Entry) -> Optional[FileMetadata]:
"""
Maybe make the thumbnail square
"""
if not self._square_thumbnail:
return None
if not self.is_dry_run:
if not entry.is_thumbnail_downloaded():
logger.warning(
"Cannot make a square thumbnail for '%s' because it is not available",
entry.title,
)
return None
self._convert_to_square_thumbnail(entry)
return FileMetadata("Square thumbnail")