#!/usr/bin/env python3 """Batch front-end for videoclean.""" from __future__ import annotations import argparse import shutil import subprocess import sys from pathlib import Path VIDEO_EXTENSIONS = {".mp4", ".mkv", ".mov", ".m4v", ".avi", ".webm"} def main() -> int: parser = argparse.ArgumentParser(description="Batch-clean videos with videoclean") parser.add_argument("source", help="Video file or directory") parser.add_argument("-o", "--output", help="Output directory") parser.add_argument("--clean", action="store_true", help="Compatibility flag; cleaning is the default") parser.add_argument("--no-clean", "--copy", action="store_true", help="Copy files without cleaning") parser.add_argument("-y", "--yes", action="store_true", help="Run without confirmation") parser.add_argument("--detect-mode", choices=["auto", "fast", "balanced", "sensitive"], default="auto") parser.add_argument("--inpaint-method", choices=["telea", "ns"], default="telea") parser.add_argument("--inpaint-radius", type=float, default=3.0) parser.add_argument("--inpaint-dilate", type=int, default=0) args = parser.parse_args() source = Path(args.source).expanduser().resolve() if source.is_file(): videos = [source] elif source.is_dir(): videos = sorted(path for path in source.iterdir() if path.suffix.lower() in VIDEO_EXTENSIONS) else: parser.error(f"source does not exist: {source}") if not videos: parser.error(f"no videos found in {source}") output = Path(args.output).expanduser().resolve() if args.output else source.parent / f"{source.stem}_processed" output.mkdir(parents=True, exist_ok=True) python = Path(__file__).resolve().parent / ".venv" / "bin" / "python" if not python.exists(): python = Path(sys.executable) for video in videos: destination = output / f"{video.stem}.mp4" if args.no_clean: shutil.copy2(video, destination) continue command = [ str(python), "-m", "videoclean.cli", "clean", str(video), "-o", str(output), "--detect-mode", args.detect_mode, "--inpaint-method", args.inpaint_method, "--inpaint-radius", str(args.inpaint_radius), "--inpaint-dilate", str(args.inpaint_dilate), ] result = subprocess.run(command) if result.returncode: return result.returncode generated = output / f"{video.stem}_clean.mp4" if generated.exists() and generated != destination: generated.replace(destination) return 0 if __name__ == "__main__": raise SystemExit(main())