mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-01-30 23:00:51 +00:00
feat(ui): warn user if FFmpeg not installed (#441)
* feat: Warn user if FFmpeg is not installed Creates a Warning dialog on startup if the program cannot find FFmpeg or FFprobe in the PATH. Other interactions with the program are blocked until the issue is either ignore or resolved. * docs: Add FFmpeg installation guide * ruff formatting * chore: Cleanup missing logic and warning message * chore: Remove custom icon Per QT docs, handling custom iconPixmap requires multiple icons per platform. Easier to just use universal, default warning icon (yellow triangle) * fix: Ignore dialog with X button * fix: Move startup checks after CI * chore: Unreverse install check logic * doc: Improve docs formatting * docs: Point help url to new docs sites * Remove ffmpeg docs page * Use which from python stdlib
This commit is contained in:
3
.github/workflows/apprun.yaml
vendored
3
.github/workflows/apprun.yaml
vendored
@@ -33,7 +33,8 @@ jobs:
|
||||
libxcb-xinerama0 \
|
||||
libopengl0 \
|
||||
libxcb-cursor0 \
|
||||
libpulse0
|
||||
libpulse0 \
|
||||
ffmpeg
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
|
||||
65
tagstudio/src/qt/modals/ffmpeg_checker.py
Normal file
65
tagstudio/src/qt/modals/ffmpeg_checker.py
Normal file
@@ -0,0 +1,65 @@
|
||||
import logging
|
||||
import math
|
||||
from pathlib import Path
|
||||
from shutil import which
|
||||
import subprocess
|
||||
|
||||
from PIL import Image, ImageQt
|
||||
from PySide6.QtCore import Signal, Qt, QUrl
|
||||
from PySide6.QtGui import QPixmap, QDesktopServices
|
||||
from PySide6.QtWidgets import QMessageBox
|
||||
|
||||
|
||||
class FfmpegChecker(QMessageBox):
|
||||
"""A warning dialog for if FFmpeg is missing."""
|
||||
|
||||
HELP_URL = "https://docs.tagstud.io/help/ffmpeg/"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.setWindowTitle("Warning: Missing dependency")
|
||||
self.setText("Warning: Could not find FFmpeg installation")
|
||||
self.setIcon(QMessageBox.Warning)
|
||||
# Blocks other application interactions until resolved
|
||||
self.setWindowModality(Qt.ApplicationModal)
|
||||
|
||||
self.setStandardButtons(
|
||||
QMessageBox.Help | QMessageBox.Ignore | QMessageBox.Cancel
|
||||
)
|
||||
self.setDefaultButton(QMessageBox.Ignore)
|
||||
# Enables the cancel button but hides it to allow for click X to close dialog
|
||||
self.button(QMessageBox.Cancel).hide()
|
||||
|
||||
self.ffmpeg = False
|
||||
self.ffprobe = False
|
||||
|
||||
def installed(self):
|
||||
"""Checks if both FFmpeg and FFprobe are installed and in the PATH."""
|
||||
if which("ffmpeg"):
|
||||
self.ffmpeg = True
|
||||
if which("ffprobe"):
|
||||
self.ffprobe = True
|
||||
|
||||
logging.info(
|
||||
f"[FFmpegChecker] FFmpeg found: {self.ffmpeg}, FFprobe found: {self.ffprobe}"
|
||||
)
|
||||
return self.ffmpeg and self.ffprobe
|
||||
|
||||
def show_warning(self):
|
||||
"""Displays the warning to the user and awaits respone."""
|
||||
missing = "FFmpeg"
|
||||
# If ffmpeg is installed but not ffprobe
|
||||
if not self.ffprobe and self.ffmpeg:
|
||||
missing = "FFprobe"
|
||||
|
||||
self.setText(f"Warning: Could not find {missing} installation")
|
||||
self.setInformativeText(
|
||||
f"{missing} is required for multimedia thumbnails and playback"
|
||||
)
|
||||
# Shows the dialog
|
||||
selection = self.exec()
|
||||
|
||||
# Selection will either be QMessageBox.Help or (QMessageBox.Ignore | QMessageBox.Cancel) which can be ignored
|
||||
if selection == QMessageBox.Help:
|
||||
QDesktopServices.openUrl(QUrl(self.HELP_URL))
|
||||
@@ -92,6 +92,7 @@ from src.qt.modals.fix_unlinked import FixUnlinkedEntriesModal
|
||||
from src.qt.modals.fix_dupes import FixDupeFilesModal
|
||||
from src.qt.modals.folders_to_tags import FoldersToTagsModal
|
||||
from src.qt.modals.drop_import import DropImport
|
||||
from src.qt.modals.ffmpeg_checker import FfmpegChecker
|
||||
|
||||
# this import has side-effect of import PySide resources
|
||||
import src.qt.resources_rc # pylint: disable=unused-import
|
||||
@@ -639,6 +640,9 @@ class QtDriver(QObject):
|
||||
if self.args.ci:
|
||||
# gracefully terminate the app in CI environment
|
||||
self.thumb_job_queue.put((self.SIGTERM.emit, []))
|
||||
else:
|
||||
# Startup Checks
|
||||
self.check_ffmpeg()
|
||||
|
||||
app.exec()
|
||||
|
||||
@@ -1852,6 +1856,12 @@ class QtDriver(QObject):
|
||||
self.filter_items()
|
||||
self.main_window.toggle_landing_page(False)
|
||||
|
||||
def check_ffmpeg(self) -> None:
|
||||
"""Checks if FFmpeg is installed and displays a warning if not."""
|
||||
self.ffmpeg_checker = FfmpegChecker()
|
||||
if not self.ffmpeg_checker.installed():
|
||||
self.ffmpeg_checker.show_warning()
|
||||
|
||||
def create_collage(self) -> None:
|
||||
"""Generates and saves an image collage based on Library Entries."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user