feat(preflight): chekc for makemkv libs

This commit is contained in:
Jan Meyer
2026-02-10 20:41:34 +01:00
parent e6b0191b26
commit fd3f6cc317

View File

@@ -5,9 +5,11 @@ starting a rip, with platform-specific install instructions.
"""
import importlib
import os
import shutil
import subprocess
import sys
from pathlib import Path
def _check_python_version() -> tuple[bool, str]:
@@ -55,6 +57,86 @@ def _check_binary(name: str, version_flag: str = "--version") -> tuple[bool, str
return True, f"{name} ({path})"
def _check_library(name: str, search_paths: list[str | Path]) -> tuple[bool, str]:
"""Check if a shared library exists in any of the given paths."""
for search_dir in search_paths:
p = Path(search_dir)
if not p.is_dir():
continue
for f in p.iterdir():
# Match libmmbd.so, libmmbd.so.0, libmmbd.dylib, mmbd.dll, etc.
if name.lower() in f.name.lower() and f.is_file():
return True, f"{name} ({f})"
return False, f"{name} — not found"
def _check_decryption_libs() -> list[tuple[str, bool, str, bool]]:
"""Check for disc decryption libraries (libmmbd, libdvdcss, MakeMKV)."""
results = []
# Platform-specific library search paths
if sys.platform == "win32":
lib_paths = [
Path(os.environ.get("ProgramFiles", "C:/Program Files")) / "MakeMKV",
Path(os.environ.get("ProgramFiles(x86)", "C:/Program Files (x86)")) / "MakeMKV",
Path(os.environ.get("SYSTEMROOT", "C:/Windows")) / "System32",
# HandBrakeCLI directory
]
hb_path = shutil.which("HandBrakeCLI")
if hb_path:
lib_paths.append(Path(hb_path).parent)
css_name = "libdvdcss"
mmbd_name = "libmmbd"
elif sys.platform == "darwin":
lib_paths = [
Path("/usr/local/lib"),
Path("/opt/homebrew/lib"),
Path("/usr/lib"),
Path.home() / "lib",
Path("/Applications/MakeMKV.app/Contents/lib"),
]
css_name = "libdvdcss"
mmbd_name = "libmmbd"
else:
lib_paths = [
Path("/usr/lib"),
Path("/usr/lib64"),
Path("/usr/local/lib"),
Path("/usr/lib/x86_64-linux-gnu"),
Path("/usr/lib/aarch64-linux-gnu"),
Path.home() / "lib",
Path.home() / ".local" / "lib",
]
# Also check snap / flatpak MakeMKV paths
snap_lib = Path("/snap/makemkv/current/usr/lib")
if snap_lib.is_dir():
lib_paths.append(snap_lib)
css_name = "libdvdcss"
mmbd_name = "libmmbd"
# Check MakeMKV binary
ok, detail = _check_binary("makemkvcon", "--version")
if not ok:
# Also check common non-PATH locations
for candidate in ["/usr/bin/makemkvcon", "/usr/local/bin/makemkvcon",
"/snap/bin/makemkvcon"]:
if Path(candidate).is_file():
ok = True
detail = f"makemkvcon ({candidate})"
break
results.append(("MakeMKV", ok, detail, False))
# Check libmmbd (Blu-ray decryption via MakeMKV)
ok, detail = _check_library(mmbd_name, lib_paths)
results.append(("libmmbd", ok, detail, False))
# Check libdvdcss (DVD decryption)
ok, detail = _check_library(css_name, lib_paths)
results.append(("libdvdcss", ok, detail, False))
return results
def _windows_install_hint(tool: str) -> str:
"""Return a Windows-specific install hint."""
hints = {
@@ -68,6 +150,18 @@ def _windows_install_hint(tool: str) -> str:
" pip install pymediainfo\n"
" Also requires MediaInfo DLL: https://mediaarea.net/en/MediaInfo/Download/Windows"
),
"MakeMKV": (
" Download from https://www.makemkv.com/download/\n"
" Or: winget install MakeMKV.MakeMKV"
),
"libmmbd": (
" Install MakeMKV, then copy libmmbd.dll next to HandBrakeCLI.exe\n"
" Guide: https://www.makemkv.com/forum/viewtopic.php?t=224"
),
"libdvdcss": (
" Download from https://www.videolan.org/developers/libdvdcss.html\n"
" Or install VLC (bundles libdvdcss)"
),
}
return hints.get(tool, f" pip install {tool}")
@@ -88,6 +182,21 @@ def _linux_install_hint(tool: str) -> str:
" Also install: sudo apt install libmediainfo0v5 (or equivalent)"
),
"eject": " Usually pre-installed. Ubuntu/Debian: sudo apt install eject",
"MakeMKV": (
" Download from https://www.makemkv.com/download/\n"
" Arch: yay -S makemkv\n"
" Snap: sudo snap install makemkv"
),
"libmmbd": (
" Install MakeMKV, then symlink:\n"
" sudo ln -sf /usr/lib/libmmbd.so.0 /usr/lib/libdvdcss.so.2\n"
" Guide: https://www.makemkv.com/forum/viewtopic.php?t=224"
),
"libdvdcss": (
" Ubuntu/Debian: sudo apt install libdvdcss2\n"
" Fedora: sudo dnf install libdvdcss\n"
" Arch: sudo pacman -S libdvdcss"
),
}
return hints.get(tool, f" pip install {tool}")
@@ -104,6 +213,19 @@ def _macos_install_hint(tool: str) -> str:
" pip install pymediainfo\n"
" Also install: brew install media-info"
),
"MakeMKV": (
" Download from https://www.makemkv.com/download/\n"
" Or: brew install --cask makemkv"
),
"libmmbd": (
" Install MakeMKV, then symlink from the .app bundle:\n"
" sudo ln -sf /Applications/MakeMKV.app/Contents/lib/libmmbd.dylib /usr/local/lib/\n"
" Guide: https://www.makemkv.com/forum/viewtopic.php?t=224"
),
"libdvdcss": (
" brew install libdvdcss\n"
" Or: download from https://www.videolan.org/developers/libdvdcss.html"
),
}
return hints.get(tool, f" pip install {tool}")
@@ -154,7 +276,6 @@ def check_all(verbose: bool = True) -> bool:
# Optional binaries (platform-specific)
if sys.platform == "win32":
# PowerShell is always available on Windows
ok, detail = _check_binary("powershell", "-Command \"echo ok\"")
checks.append(("PowerShell", ok, detail, False))
elif sys.platform == "darwin":
@@ -164,6 +285,9 @@ def check_all(verbose: bool = True) -> bool:
ok, detail = _check_binary("eject", "--version")
checks.append(("eject", ok, detail, False))
# Disc decryption libraries
checks.extend(_check_decryption_libs())
# Print results
all_required_ok = all(ok for _, ok, _, req in checks if req)