diff --git a/pyproject.toml b/pyproject.toml index 7473fa4..5fe8012 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -170,7 +170,7 @@ profile = "black" multi_line_output = 3 indent = 4 color_output = true -known_third_party = ["Crypto", "PySide6", "coloredlogs", "dataclasses_json", "ffmpeg", "m3u8", "mpegdash", "mutagen", "pathvalidate", "requests", "rich", "tidalapi", "typer"] +known_third_party = ["Crypto", "PySide6", "coloredlogs", "dataclasses_json", "ffmpeg", "helper", "m3u8", "mpegdash", "mutagen", "pathvalidate", "requests", "rich", "tidalapi", "typer"] [tool.mypy] # https://mypy.readthedocs.io/en/latest/config_file.html#using-a-pyproject-toml-file diff --git a/tidal_dl_ng/dialog.py b/tidal_dl_ng/dialog.py index b1901fd..34735a6 100644 --- a/tidal_dl_ng/dialog.py +++ b/tidal_dl_ng/dialog.py @@ -2,6 +2,7 @@ import os.path from enum import Enum from pathlib import Path +from helper.path import is_installed_ffmpeg from PySide6 import QtCore, QtGui, QtWidgets from tidalapi import Quality as QualityAudio @@ -86,19 +87,39 @@ class DialogPreferences(QtWidgets.QDialog): pixmapi: QtWidgets.QStyle.StandardPixmap = QtWidgets.QStyle.SP_MessageBoxQuestion self.icon = self.style().standardIcon(pixmapi) - self.parameters_checkboxes = [ - "lyrics_embed", - "lyrics_file", - "video_download", - "download_delay", - "video_convert_mp4", - ] - self.parameters_combo = [ - ("skip_existing", SkipExisting), - ("quality_audio", QualityAudio), - ("quality_video", QualityVideo), - ("metadata_cover_dimension", CoverDimensions), - ] + self._init_checkboxes() + self._init_comboboxes() + self._init_line_edit() + + # Create an instance of the GUI + self.ui = Ui_DialogSettings() + + # Run the .setupUi() method to show the GUI + self.ui.setupUi(self) + # Set data. + self.gui_populate() + self._init_signals() + + self.exec() + + def _init_signals(self): + self.ui.cb_video_convert_mp4.stateChanged.connect(self.on_cb_video_convert_mp4) + + def on_cb_video_convert_mp4(self, int): + if self.ui.cb_video_convert_mp4.isChecked(): + # Check if ffmpeg is in PATH otherwise show error message. + if not is_installed_ffmpeg(): + self.ui.cb_video_convert_mp4.setChecked(False) + self.ui.cb_video_convert_mp4.setCheckState(QtCore.Qt.CheckState.Unchecked) + QtWidgets.QMessageBox.critical( + self, + "FFmpeg not found!", + "Either FFmpeg is not installed on your computer or not set within " + "your PATH variable. You cannot activate this option until FFmpeg " + "is correctly installed and set to your environmental PATH variable.", + ) + + def _init_line_edit(self): self.parameters_line_edit = [ "download_base_path", "format_album", @@ -108,15 +129,22 @@ class DialogPreferences(QtWidgets.QDialog): "format_video", ] - # Create an instance of the GUI - self.ui = Ui_DialogSettings() + def _init_comboboxes(self): + self.parameters_combo = [ + ("skip_existing", SkipExisting), + ("quality_audio", QualityAudio), + ("quality_video", QualityVideo), + ("metadata_cover_dimension", CoverDimensions), + ] - # Run the .setupUi() method to show the GUI - self.ui.setupUi(self) - # Set data. - self.gui_populate() - - self.exec() + def _init_checkboxes(self): + self.parameters_checkboxes = [ + "lyrics_embed", + "lyrics_file", + "video_download", + "download_delay", + "video_convert_mp4", + ] def gui_populate(self): self.populate_checkboxes() @@ -190,7 +218,7 @@ class DialogPreferences(QtWidgets.QDialog): checkbox.setChecked(getattr(self.data, pn)) def accept(self): - # Get settings. TODO + # Get settings. self.to_settings() self.done(1) diff --git a/tidal_dl_ng/download.py b/tidal_dl_ng/download.py index 1ca62e5..2afdf20 100644 --- a/tidal_dl_ng/download.py +++ b/tidal_dl_ng/download.py @@ -29,7 +29,7 @@ from tidal_dl_ng.constants import ( ) from tidal_dl_ng.helper.decryption import decrypt_file, decrypt_security_token from tidal_dl_ng.helper.exceptions import MediaMissing, UnknownManifestFormat -from tidal_dl_ng.helper.path import check_file_exists, format_path_media, path_file_sanitize +from tidal_dl_ng.helper.path import check_file_exists, format_path_media, is_installed_ffmpeg, path_file_sanitize from tidal_dl_ng.helper.tidal import ( instantiate_media, items_results_all, @@ -82,6 +82,13 @@ class Download: self.progress = progress self.path_base = path_base + if not is_installed_ffmpeg() and self.settings.data.video_convert_mp4: + self.settings.data.video_convert_mp4 = False + self.fn_logger.error( + "Cannot find FFmpeg in PATH. Videos can be downloaded but will not be processed. " + "Make sure FFmpeg is installed correctly and present within your environmental PATH variable." + ) + def _download( self, media: Track | Video, diff --git a/tidal_dl_ng/helper/path.py b/tidal_dl_ng/helper/path.py index 43dd9de..2b739d6 100644 --- a/tidal_dl_ng/helper/path.py +++ b/tidal_dl_ng/helper/path.py @@ -2,6 +2,7 @@ import glob import math import os import re +import shutil from pathlib import Path, PosixPath from pathvalidate import sanitize_filename, sanitize_filepath @@ -261,3 +262,10 @@ def check_file_exists(path_file: str, extension_ignore: bool = False) -> bool: result = bool(sum([glob.glob(_file) for _file in path_files], [])) return result + + +def is_installed_ffmpeg() -> bool: + # Checks if ffmpeg is found in PATH. + result: bool = bool(shutil.which("ffmpeg")) + + return result