diff --git a/.vscode/launch.json b/.vscode/launch.json index 5c60f268..d013ba11 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -34,7 +34,8 @@ "YTP_TEMP_PATH": "${workspaceFolder}/var/tmp", "YTP_URL_HOST": "http://localhost:8081", "YTP_LOG_LEVEL": "DEBUG", - "YTP_DEBUG": "false", + "YTP_DEBUG": "true", + "YTP_YTDL_DEBUG": "true", } }, { diff --git a/app/library/DataStore.py b/app/library/DataStore.py index b38fa890..a0ea04a3 100644 --- a/app/library/DataStore.py +++ b/app/library/DataStore.py @@ -111,7 +111,7 @@ class DataStore: return None async def test(self) -> bool: - await self.connection.execute('SELECT "id" FROM "history" LIMIT 1').fetchone() + self.connection.execute('SELECT "id" FROM "history" LIMIT 1').fetchone() return True def _updateStoreItem(self, type: str, item: ItemDTO) -> None: diff --git a/app/library/Download.py b/app/library/Download.py index 99777f61..73034ee9 100644 --- a/app/library/Download.py +++ b/app/library/Download.py @@ -70,7 +70,7 @@ class Download: self.output_template_chapter = info.output_template_chapter self.output_template = info.output_template self.preset = info.preset - self.ytdl_opts = get_opts(self.preset, info.ytdlp_config if info.ytdlp_config else {}) + self.ytdl_opts = info.ytdlp_config if info.ytdlp_config else {} self.info = info self.id = info._id self.default_ytdl_opts = config.ytdl_options @@ -121,7 +121,7 @@ class Download: 'break_on_existing': True, 'progress_hooks': [self._progress_hook], 'postprocessor_hooks': [self._postprocessor_hook], - **mergeConfig(self.default_ytdl_opts, self.ytdl_opts), + **get_opts(self.preset, mergeConfig(self.default_ytdl_opts, self.ytdl_opts)), } if 'format' not in params and self.default_ytdl_opts.get('format', None): diff --git a/app/library/DownloadQueue.py b/app/library/DownloadQueue.py index 7f1b53e2..c92a89f9 100644 --- a/app/library/DownloadQueue.py +++ b/app/library/DownloadQueue.py @@ -209,7 +209,7 @@ class DownloadQueue: ): ytdlp_config = ytdlp_config if ytdlp_config else {} - LOG.info(f"Adding url '{url}' to folder '{folder}' with the following options 'Preset: {preset=}' 'Naming: {output_template}', 'Cookies: {ytdlp_cookies}' 'YTConfig: {ytdlp_config}'.") + LOG.info(f"Adding url '{url}' to folder '{folder}' with the following options 'Preset: {preset}' 'Naming: {output_template}', 'Cookies: {ytdlp_cookies}' 'YTConfig: {ytdlp_config}'.") if isinstance(ytdlp_config, str): try: diff --git a/app/library/Utils.py b/app/library/Utils.py index bb87df3c..c95cafe3 100644 --- a/app/library/Utils.py +++ b/app/library/Utils.py @@ -32,33 +32,33 @@ def get_opts(preset: str, ytdl_opts: dict) -> dict: opts = copy.deepcopy(ytdl_opts) if 'default' == preset: + LOG.debug("Using default preset.") return opts from .config import Config presets = Config.get_instance().presets - if preset not in presets: + found = False + for _preset in presets: + if _preset['name'] == preset: + found = True + preset_opts = _preset + break + + if not found: LOG.error(f"Preset '{preset}' is not defined in the presets.") return opts - preset_opts = presets[preset] - opts['format'] = preset_opts.get('format') if 'postprocessors' in preset_opts: - if 'postprocessors' not in opts: - opts['postprocessors'] = [] - - opts['postprocessors'].extend(preset_opts['postprocessors']) + opts['postprocessors'] = preset_opts['postprocessors'] if 'args' in preset_opts: - for ignored_key in IGNORED_KEYS: - for key, value in preset_opts['args'].items(): - if key == ignored_key: - continue - - opts[key] = value + for key, value in preset_opts['args'].items(): + opts[key] = value + LOG.debug(f"Using preset '{preset}', altered options: {opts}") return opts diff --git a/app/library/config.py b/app/library/config.py index 6abc5815..bcc87e82 100644 --- a/app/library/config.py +++ b/app/library/config.py @@ -66,43 +66,50 @@ class Config: ytdlp_version: str = YTDLP_VERSION tasks: list = [] presets: list = [ + {'name': 'default', 'format': 'default', 'postprocessors': [], + 'args': {}}, + {'name': 'Video - 1080p h264/acc', 'format': 'bv[height<=1080][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]', + 'args': {'format_sort': ['vcodec:h264'], }, }, + {'name': 'Video - 720p h264/acc', 'format': 'bv[height<=720][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]', + 'args': {'format_sort': ['vcodec:h264'], }, }, { - 'name': 'Default - Use default yt-dlp format', - 'format': 'default', - 'postprocessors': [], - 'args': {} - }, - # { - # 'name': 'Audio - Best audio [MP3]', - # 'format': 'bestaudio', - # 'postprocessors': [ - # {'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': 'best'}, - # {"key": "FFmpegThumbnailsConvertor", "format": "jpg", "when": "before_dl"}, - # {'key': 'FFmpegMetadata'}, - # {'key': 'EmbedThumbnail'}, - # ], - # 'args': { - # 'writethumbnail': True - # } - # }, - { - 'name': 'Video - 1080p h264/acc', - 'format': 'bv[height<=1080][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]', + 'name': 'Audio - Best audio [MP3]', + 'format': 'bestaudio/best', + 'postprocessors': [ + { + "key": "FFmpegExtractAudio", + "preferredcodec": "mp3", + "preferredquality": "5", + "nopostoverwrites": False + }, + { + "key": "FFmpegMetadata", + "add_chapters": True, + "add_metadata": True, + "add_infojson": "if_exists" + }, + { + "key": "EmbedThumbnail", + "already_have_thumbnail": False + }, + { + "key": "FFmpegConcat", + "only_multi_video": True, + "when": "playlist" + } + ], 'args': { - 'format_sort': [ - 'vcodec:h264' - ], - }, - }, - { - 'name': 'Video - 720p h264/acc', - 'format': 'bv[height<=720][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]', - 'args': { - 'format_sort': [ - 'vcodec:h264' - ], - }, - }, + "outtmpl": { + "pl_thumbnail": "" + }, + "ignoreerrors": "only_download", + "retries": 10, + "fragment_retries": 10, + "writethumbnail": True, + "extract_flat": "discard_in_playlist", + "final_ext": "mp3", + } + } ] _manual_vars: tuple = ('temp_path', 'config_path', 'download_path',) @@ -119,7 +126,7 @@ class Config: 'ytdlp_version', 'version', 'url_host', 'started', 'url_prefix', ) - @staticmethod + @ staticmethod def get_instance(): """ Static access method. """ return Config() if not Config.__instance else Config.__instance @@ -207,7 +214,7 @@ class Config: LOG.error(f"Error starting debugpy server at '0.0.0.0:{self.debugpy_port}'. {e}") optsFile: str = os.path.join(self.config_path, 'ytdlp.json') - if os.path.exists(optsFile) and os.path.getsize(optsFile) > 0: + if os.path.exists(optsFile) and os.path.getsize(optsFile) > 4: LOG.info(f"Loading yt-dlp custom options from '{optsFile}'.") (opts, status, error) = load_file(optsFile, dict) diff --git a/ui/components/History.vue b/ui/components/History.vue index 96abca3d..74f08611 100644 --- a/ui/components/History.vue +++ b/ui/components/History.vue @@ -101,12 +101,12 @@