Skip to content

Commit

Permalink
feat(ui): warn user if FFmpeg not installed (#441)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
seakrueger authored Sep 14, 2024
1 parent 6490cc9 commit b2dbc57
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .github/workflows/apprun.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ jobs:
libxcb-xinerama0 \
libopengl0 \
libxcb-cursor0 \
libpulse0
libpulse0 \
ffmpeg
- name: Install dependencies
run: |
Expand Down
65 changes: 65 additions & 0 deletions tagstudio/src/qt/modals/ffmpeg_checker.py
Original file line number Diff line number Diff line change
@@ -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))
10 changes: 10 additions & 0 deletions tagstudio/src/qt/ts_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
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
Expand Down Expand Up @@ -639,6 +640,9 @@ def create_folders_tags_modal():
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()

Expand Down Expand Up @@ -1852,6 +1856,12 @@ def open_library(self, path: Path):
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."""

Expand Down

0 comments on commit b2dbc57

Please sign in to comment.