This commit is contained in:
2026-01-09 16:02:49 -08:00
parent a70482fdf1
commit 6c13604664
2 changed files with 65 additions and 21 deletions

View File

@@ -8,6 +8,10 @@ downloads Playwright browser binaries by running `python -m playwright install`.
By default this script installs **Chromium** only to conserve space; pass
`--browsers all` to install all supported engines (chromium, firefox, webkit).
FFmpeg: The project includes ffmpeg binaries for Windows (in MPV/ffmpeg). On Linux/macOS,
install ffmpeg using your system package manager (apt install ffmpeg, brew install ffmpeg, etc.).
ffmpeg-python is installed as a dependency, but requires ffmpeg itself to be on your PATH.
Note: This Python script is the canonical installer for the project — prefer
running `python ./scripts/bootstrap.py` locally. The platform scripts
(`scripts/bootstrap.ps1` and `scripts/bootstrap.sh`) are now thin wrappers
@@ -641,7 +645,7 @@ def main() -> int:
if not playwright_package_installed():
if not args.quiet:
print("'playwright' package not found; installing it via pip...")
run([sys.executable, "-m", "pip", "install", "playwright"])
run([sys.executable, "-m", "pip", "install", "--no-cache-dir", "playwright"])
if not args.quiet:
print(
@@ -668,6 +672,7 @@ def main() -> int:
"pip",
"install",
"--upgrade",
"--no-cache-dir",
"pip",
"setuptools",
"wheel",
@@ -686,13 +691,13 @@ def main() -> int:
print(
f"Installing Python dependencies into local venv from {req_file}..."
)
run([str(venv_python), "-m", "pip", "install", "-r", str(req_file)])
run([str(venv_python), "-m", "pip", "install", "--no-cache-dir", "-r", str(req_file)])
if not args.no_playwright:
if not playwright_package_installed():
if not args.quiet:
print("'playwright' package not installed in venv; installing it...")
run([str(venv_python), "-m", "pip", "install", "playwright"])
run([str(venv_python), "-m", "pip", "install", "--no-cache-dir", "playwright"])
if not args.quiet:
print(
@@ -711,7 +716,7 @@ def main() -> int:
# Install the project into the local venv (editable mode is the default, opinionated)
if not args.quiet:
print("Installing project into local venv (editable mode)")
run([str(venv_python), "-m", "pip", "install", "-e", str(repo_root / "scripts")])
run([str(venv_python), "-m", "pip", "install", "--no-cache-dir", "-e", str(repo_root / "scripts")])
# Verify top-level 'CLI' import and, if missing, attempt to make it available
if not args.quiet:

View File

@@ -174,30 +174,49 @@ class PlaywrightTool:
ignore_https = bool(_get("ignore_https_errors", defaults.ignore_https_errors))
# Try to find ffmpeg: config override, environment variable, bundled, then system
# This checks if ffmpeg is actually available (not just the path to it)
ffmpeg_path: Optional[str] = None
config_ffmpeg = _get("ffmpeg_path", None)
if config_ffmpeg:
ffmpeg_path = str(config_ffmpeg).strip()
else:
# User explicitly configured ffmpeg path
candidate = str(config_ffmpeg).strip()
if Path(candidate).exists():
ffmpeg_path = candidate
else:
debug(f"Configured ffmpeg path does not exist: {candidate}")
if not ffmpeg_path:
# Check environment variable (supports project ffmpeg)
env_ffmpeg = os.environ.get("PLAYWRIGHT_FFMPEG_PATH")
if env_ffmpeg:
if env_ffmpeg and Path(env_ffmpeg).exists():
ffmpeg_path = env_ffmpeg
else:
# Try to find bundled ffmpeg in the project (if available)
try:
repo_root = Path(__file__).resolve().parent.parent
bundled_ffmpeg = repo_root / "MPV" / "ffmpeg" / "bin"
if bundled_ffmpeg.exists():
ffmpeg_exe = bundled_ffmpeg / ("ffmpeg.exe" if os.name == "nt" else "ffmpeg")
if ffmpeg_exe.exists():
ffmpeg_path = str(ffmpeg_exe)
except Exception:
pass
elif env_ffmpeg:
debug(f"PLAYWRIGHT_FFMPEG_PATH set but path does not exist: {env_ffmpeg}")
# Try system ffmpeg if bundled not found
if not ffmpeg_path:
ffmpeg_path = shutil.which("ffmpeg")
if not ffmpeg_path:
# Try to find bundled ffmpeg in the project (Windows-only, in MPV/ffmpeg/bin)
try:
repo_root = Path(__file__).resolve().parent.parent
bundled_ffmpeg = repo_root / "MPV" / "ffmpeg" / "bin"
if bundled_ffmpeg.exists():
ffmpeg_exe = bundled_ffmpeg / ("ffmpeg.exe" if os.name == "nt" else "ffmpeg")
if ffmpeg_exe.exists():
ffmpeg_path = str(ffmpeg_exe)
debug(f"Found bundled ffmpeg at: {ffmpeg_path}")
except Exception as e:
debug(f"Error checking for bundled ffmpeg: {e}")
if not ffmpeg_path:
# Try system ffmpeg if bundled not found
system_ffmpeg = shutil.which("ffmpeg")
if system_ffmpeg:
ffmpeg_path = system_ffmpeg
debug(f"Found system ffmpeg at: {ffmpeg_path}")
else:
# ffmpeg not found - log a debug message but don't fail
# ffmpeg-python may still work with system installation, or user might not need it
debug("ffmpeg not found on PATH. For best compatibility, install ffmpeg: Windows (use bundled or choco install ffmpeg), macOS (brew install ffmpeg), Linux (apt install ffmpeg or equivalent)")
return PlaywrightDefaults(
browser=browser,
@@ -219,6 +238,26 @@ class PlaywrightTool:
"playwright is required; install with: pip install playwright; then: playwright install"
)
def ffmpeg_available(self) -> bool:
"""Check if ffmpeg is available on the system."""
return bool(self.defaults.ffmpeg_path)
def require_ffmpeg(self) -> None:
"""Require ffmpeg to be available; raise a helpful error if not.
This should be called before operations that need ffmpeg (e.g., video recording).
"""
if not self.ffmpeg_available():
raise RuntimeError(
"ffmpeg is required but not found on your system.\n"
"Install it using:\n"
" Windows: choco install ffmpeg (if using Chocolatey) or use the bundled version in MPV/ffmpeg\n"
" macOS: brew install ffmpeg\n"
" Linux: apt install ffmpeg (Ubuntu/Debian) or equivalent for your distribution\n"
"\n"
"Or set the PLAYWRIGHT_FFMPEG_PATH environment variable to point to your ffmpeg executable."
)
@contextlib.contextmanager
def open_page(
self,