[FEATURE] Add custom ffmpeg post processing
This commit is contained in:
parent
2edfffcc5f
commit
77638a7214
1 changed files with 54 additions and 6 deletions
|
|
@ -5,11 +5,17 @@ from typing import Optional
|
||||||
|
|
||||||
from ytdl_sub.entries.entry import Entry
|
from ytdl_sub.entries.entry import Entry
|
||||||
from ytdl_sub.entries.variables.kwargs import EXT
|
from ytdl_sub.entries.variables.kwargs import EXT
|
||||||
from ytdl_sub.plugins.plugin import Plugin
|
from ytdl_sub.plugins.plugin import Plugin, PluginPriority
|
||||||
from ytdl_sub.plugins.plugin import PluginOptions
|
from ytdl_sub.plugins.plugin import PluginOptions
|
||||||
from ytdl_sub.utils.exceptions import FileNotDownloadedException
|
from ytdl_sub.utils.exceptions import FileNotDownloadedException
|
||||||
from ytdl_sub.utils.file_handler import FileMetadata
|
from ytdl_sub.utils.file_handler import FileMetadata
|
||||||
from ytdl_sub.validators.audo_codec_validator import FileTypeValidator
|
from ytdl_sub.validators.audo_codec_validator import FileTypeValidator
|
||||||
|
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
|
||||||
|
from ytdl_sub.validators.string_select_validator import StringSelectValidator
|
||||||
|
|
||||||
|
|
||||||
|
class FileConvertWithValidator(StringSelectValidator):
|
||||||
|
_select_values = {"yt-dlp", "ffmpeg"}
|
||||||
|
|
||||||
|
|
||||||
class FileConvertOptions(PluginOptions):
|
class FileConvertOptions(PluginOptions):
|
||||||
|
|
@ -24,9 +30,12 @@ class FileConvertOptions(PluginOptions):
|
||||||
my_example_preset:
|
my_example_preset:
|
||||||
file_convert:
|
file_convert:
|
||||||
convert_to: "mp4"
|
convert_to: "mp4"
|
||||||
|
convert_with: "custom"
|
||||||
|
ffmpeg_post_process_args: "asfd"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_required_keys = {"convert_to"}
|
_required_keys = {"convert_to"}
|
||||||
|
_optional_keys = {"convert_with", "ffmpeg_post_process_args"}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def partial_validate(cls, name: str, value: Any) -> None:
|
def partial_validate(cls, name: str, value: Any) -> None:
|
||||||
|
|
@ -39,7 +48,14 @@ class FileConvertOptions(PluginOptions):
|
||||||
|
|
||||||
def __init__(self, name, value):
|
def __init__(self, name, value):
|
||||||
super().__init__(name, value)
|
super().__init__(name, value)
|
||||||
self._convert_to = self._validate_key(key="convert_to", validator=FileTypeValidator).value
|
self._convert_to: str = self._validate_key(key="convert_to", validator=FileTypeValidator).value
|
||||||
|
self._convert_with: str = self._validate_key_if_present(key="convert_with", validator=FileConvertWithValidator, default="yt-dlp").value
|
||||||
|
self._ffmpeg_post_process_args: Optional[str] = self._validate_key_if_present(key="ffmpeg_post_process_args", validator=OverridesStringFormatterValidator)
|
||||||
|
|
||||||
|
if self._convert_to == "ffmpeg" and not self._ffmpeg_post_process_args:
|
||||||
|
raise self._validation_exception(
|
||||||
|
"Must specify 'ffmpeg_post_process_args' if 'convert_with' is set to ffmpeg"
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def convert_to(self) -> str:
|
def convert_to(self) -> str:
|
||||||
|
|
@ -51,9 +67,38 @@ class FileConvertOptions(PluginOptions):
|
||||||
"""
|
"""
|
||||||
return self._convert_to
|
return self._convert_to
|
||||||
|
|
||||||
|
@property
|
||||||
|
def convert_with(self) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Optional. Supports ``yt-dlp`` and ``ffmpeg``. ``yt-dlp`` will convert files within
|
||||||
|
yt-dlp whereas ``ffmpeg`` specifies it will be converted using a custom command specified
|
||||||
|
with ``ffmpeg_post_process_args``. Defaults to ``yt-dlp``.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return self._convert_with
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ffmpeg_post_process_args(self) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Optional. ffmpeg args to post-process an entry file with. The args will be inserted in the
|
||||||
|
form of:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
ffmpeg -i input_file.ext {ffmpeg_post_process_args) output_file.output_ext
|
||||||
|
|
||||||
|
The output file will use the extension specified in ``convert_to``. Post-processing args
|
||||||
|
can still be set with ``convert_with`` set to ``yt-dlp``.
|
||||||
|
"""
|
||||||
|
return self._ffmpeg_post_process_args
|
||||||
|
|
||||||
|
|
||||||
class FileConvertPlugin(Plugin[FileConvertOptions]):
|
class FileConvertPlugin(Plugin[FileConvertOptions]):
|
||||||
plugin_options_type = FileConvertOptions
|
plugin_options_type = FileConvertOptions
|
||||||
|
# Perform this after regex
|
||||||
|
priority: PluginPriority = PluginPriority(
|
||||||
|
modify_entry=PluginPriority.MODIFY_ENTRY_AFTER_SPLIT + 1
|
||||||
|
)
|
||||||
|
|
||||||
def ytdl_options(self) -> Optional[Dict]:
|
def ytdl_options(self) -> Optional[Dict]:
|
||||||
"""
|
"""
|
||||||
|
|
@ -88,10 +133,13 @@ class FileConvertPlugin(Plugin[FileConvertOptions]):
|
||||||
If the audio file is not found
|
If the audio file is not found
|
||||||
"""
|
"""
|
||||||
new_ext = self.plugin_options.convert_to
|
new_ext = self.plugin_options.convert_to
|
||||||
converted_video_file = entry.get_download_file_path().removesuffix(entry.ext) + new_ext
|
converted_video_file_path = entry.get_download_file_path().removesuffix(entry.ext) + new_ext
|
||||||
if not self.is_dry_run:
|
if self.plugin_options.convert_with == "yt-dlp":
|
||||||
if not os.path.isfile(converted_video_file):
|
if not self.is_dry_run:
|
||||||
raise FileNotDownloadedException("Failed to find the converted video file")
|
if not os.path.isfile(converted_video_file_path):
|
||||||
|
raise FileNotDownloadedException("Failed to find the converted video file")
|
||||||
|
else: # ffmpeg
|
||||||
|
|
||||||
|
|
||||||
if entry.ext != new_ext:
|
if entry.ext != new_ext:
|
||||||
entry.add_kwargs(
|
entry.add_kwargs(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue