[FEATURE] Dedicated embed_thumbnail plugin
This commit is contained in:
parent
50eefb80cf
commit
e0ea9a59ed
4 changed files with 90 additions and 0 deletions
|
|
@ -8,6 +8,7 @@ from ytdl_sub.downloaders.url.url import UrlDownloader
|
||||||
from ytdl_sub.plugins.audio_extract import AudioExtractPlugin
|
from ytdl_sub.plugins.audio_extract import AudioExtractPlugin
|
||||||
from ytdl_sub.plugins.chapters import ChaptersPlugin
|
from ytdl_sub.plugins.chapters import ChaptersPlugin
|
||||||
from ytdl_sub.plugins.date_range import DateRangePlugin
|
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.file_convert import FileConvertPlugin
|
||||||
from ytdl_sub.plugins.internal.view import ViewPlugin
|
from ytdl_sub.plugins.internal.view import ViewPlugin
|
||||||
from ytdl_sub.plugins.match_filters import MatchFiltersPlugin
|
from ytdl_sub.plugins.match_filters import MatchFiltersPlugin
|
||||||
|
|
@ -107,6 +108,7 @@ class PluginMapping:
|
||||||
"_view": ViewPlugin,
|
"_view": ViewPlugin,
|
||||||
"audio_extract": AudioExtractPlugin,
|
"audio_extract": AudioExtractPlugin,
|
||||||
"date_range": DateRangePlugin,
|
"date_range": DateRangePlugin,
|
||||||
|
"embed_thumbnail": EmbedThumbnailPlugin,
|
||||||
"file_convert": FileConvertPlugin,
|
"file_convert": FileConvertPlugin,
|
||||||
"match_filters": MatchFiltersPlugin,
|
"match_filters": MatchFiltersPlugin,
|
||||||
"music_tags": MusicTagsPlugin,
|
"music_tags": MusicTagsPlugin,
|
||||||
|
|
|
||||||
81
src/ytdl_sub/plugins/embed_thumbnail.py
Normal file
81
src/ytdl_sub/plugins/embed_thumbnail.py
Normal 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")
|
||||||
|
|
@ -149,6 +149,11 @@ class MusicTagsPlugin(Plugin[MusicTagsOptions]):
|
||||||
setattr(audio_file, tag_name, tag_value[0])
|
setattr(audio_file, tag_name, tag_value[0])
|
||||||
|
|
||||||
if self.plugin_options.embed_thumbnail:
|
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 the entry thumbnail so it is embedded as jpg
|
||||||
convert_download_thumbnail(entry=entry)
|
convert_download_thumbnail(entry=entry)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ def single_song_preset_dict(output_directory):
|
||||||
"preset": "single",
|
"preset": "single",
|
||||||
# test multi-tags
|
# test multi-tags
|
||||||
"music_tags": {"embed_thumbnail": True, "tags": {"genres": ["multi_tag_1", "multi_tag_2"]}},
|
"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
|
# download the worst format so it is fast
|
||||||
"ytdl_options": {
|
"ytdl_options": {
|
||||||
"format": "worst[ext=mp4]",
|
"format": "worst[ext=mp4]",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue