[FEATURE] Dedicated embed_thumbnail plugin

This commit is contained in:
Jesse Bannon 2023-07-23 23:35:11 -07:00
parent 50eefb80cf
commit e0ea9a59ed
4 changed files with 90 additions and 0 deletions

View file

@ -8,6 +8,7 @@ from ytdl_sub.downloaders.url.url import UrlDownloader
from ytdl_sub.plugins.audio_extract import AudioExtractPlugin
from ytdl_sub.plugins.chapters import ChaptersPlugin
from ytdl_sub.plugins.date_range import DateRangePlugin
from ytdl_sub.plugins.embed_thumbnail import EmbedThumbnailPlugin
from ytdl_sub.plugins.file_convert import FileConvertPlugin
from ytdl_sub.plugins.internal.view import ViewPlugin
from ytdl_sub.plugins.match_filters import MatchFiltersPlugin
@ -107,6 +108,7 @@ class PluginMapping:
"_view": ViewPlugin,
"audio_extract": AudioExtractPlugin,
"date_range": DateRangePlugin,
"embed_thumbnail": EmbedThumbnailPlugin,
"file_convert": FileConvertPlugin,
"match_filters": MatchFiltersPlugin,
"music_tags": MusicTagsPlugin,

View file

@ -0,0 +1,81 @@
from typing import Optional
from ytdl_sub.config.preset_options import OptionsValidator
from ytdl_sub.entries.entry import Entry
from ytdl_sub.plugins.plugin import Plugin
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.utils.thumbnail import convert_download_thumbnail
from ytdl_sub.validators.validators import BoolValidator
logger = Logger.get("embed_thumbnail")
class EmbedThumbnailOptions(BoolValidator, OptionsValidator):
"""
Whether to embed thumbnails to the audio/video file or not.
Usage:
.. code-block:: yaml
presets:
my_example_preset:
embed_thumbnail: True
"""
class EmbedThumbnailPlugin(Plugin[EmbedThumbnailOptions]):
plugin_options_type = EmbedThumbnailOptions
@property
def _embed_thumbnail(self) -> bool:
return self.plugin_options.value
def post_process_entry(self, entry: Entry) -> Optional[FileMetadata]:
"""
Maybe embed the thumbnail
"""
if not self._embed_thumbnail:
return None
if entry.ext == "webm":
logger.warning("webm does not support embedded thumbnails, skipping")
return None
if not self.is_dry_run:
# convert the entry thumbnail so it is embedded as jpg
convert_download_thumbnail(entry=entry)
file_path = entry.get_download_file_path()
thumbnail_path = entry.get_download_thumbnail_path()
tmp_file_path = FFMPEG.tmp_file_path(file_path)
try:
FFMPEG.run(
[
"-i",
file_path,
"-i",
thumbnail_path,
"-map",
"0",
"-map",
"1",
"-dn", # ignore data streams
"-c",
"-copy",
"-c:v:1",
entry.thumbnail_ext,
"-disposition:v:1",
"attached_pic",
"-bitexact", # for reproducibility
tmp_file_path,
]
)
FileHandler.move(tmp_file_path, file_path)
finally:
FileHandler.delete(tmp_file_path)
return FileMetadata("Embedded thumbnail")

View file

@ -149,6 +149,11 @@ class MusicTagsPlugin(Plugin[MusicTagsOptions]):
setattr(audio_file, tag_name, tag_value[0])
if self.plugin_options.embed_thumbnail:
logger.warning(
"music_tags.embed_thumbnail is now deprecated. Use the dedicated "
"embed_thumbnail plugin instead"
)
# convert the entry thumbnail so it is embedded as jpg
convert_download_thumbnail(entry=entry)

View file

@ -11,6 +11,8 @@ def single_song_preset_dict(output_directory):
"preset": "single",
# test multi-tags
"music_tags": {"embed_thumbnail": True, "tags": {"genres": ["multi_tag_1", "multi_tag_2"]}},
# test the new embed_thumbnail plugin
"embed_thumbnail": True,
# download the worst format so it is fast
"ytdl_options": {
"format": "worst[ext=mp4]",