calesthio/OpenMontage · error · ValueError

FFmpeg lavfi movie paths containing single quotes are unsupp

Error message

FFmpeg lavfi movie paths containing single quotes are unsupported

What it means

Raised by _escape_lavfi_movie_path when the input path contains a single quote, which cannot be safely escaped inside an FFmpeg lavfi movie='...' filtergraph without risking filter injection. The code treats this as an unsupported input rather than attempting partial escaping. It is a deliberate security guard, so the fix is on the caller's side: rename or copy the file.

Source

Thrown at tools/analysis/scene_detect.py:172

        scenes = []
        for i, (scene_start, scene_end) in enumerate(scene_list):
            scenes.append({
                "index": i,
                "start_seconds": round(scene_start.get_seconds(), 3),
                "end_seconds": round(scene_end.get_seconds(), 3),
                "duration_seconds": round(
                    scene_end.get_seconds() - scene_start.get_seconds(), 3
                ),
            })

        return scenes

    @staticmethod
    def _escape_lavfi_movie_path(path: str) -> str:
        """Escape a path for FFmpeg lavfi movie=... without allowing filter injection."""
        normalized = path.replace("\\", "/")
        if "'" in normalized:
            raise ValueError("FFmpeg lavfi movie paths containing single quotes are unsupported")
        escaped = []
        for char in normalized:
            if char in "\\:,[];":
                escaped.append("\\" + char)
            else:
                escaped.append(char)
        return "".join(escaped)

    def _detect_ffmpeg(self, inputs: dict[str, Any]) -> list[dict]:
        """Fallback: use FFmpeg scene change filter."""
        input_path = str(inputs["input_path"])
        threshold = inputs.get("threshold", 0.3)
        min_scene_len = inputs.get("min_scene_length_seconds", 1.0)
        escaped_input = self._escape_lavfi_movie_path(input_path)

        cmd = [
            "ffprobe",
            "-v", "quiet",

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Rename the file (or copy it) to a path without single quotes before calling scene detection
  2. Sanitize filenames at ingest time: strip/replace ' and other shell/filter metacharacters when a file enters the pipeline
  3. If you control the code path, pass the file via a symlink or hardlink with a safe generated name (e.g. mkdtemp + sanitized basename)

Example fix

// before
result = detect._detect_ffmpeg({"input_path": "/tmp/Bob's clip.mp4"})

// after
import shutil, tempfile, os
safe_dir = tempfile.mkdtemp()
safe_path = os.path.join(safe_dir, "input.mp4")
shutil.copy("/tmp/Bob's clip.mp4", safe_path)
result = detect._detect_ffmpeg({"input_path": safe_path})
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

def safe_movie_path(path: str) -> str:
    if "'" in path:
        raise ValueError(f"path contains a single quote; rename the file: {path}")
    return path

Type guard

def is_lavfi_safe(path: str) -> bool:
    return "'" not in path.replace("\\", "/")

Try / catch

try:
    escaped = _escape_lavfi_movie_path(path)
except ValueError:
    safe = Path(tempfile.mkdtemp()) / re.sub(r"[^A-Za-z0-9._-]", "_", Path(path).name)
    shutil.copy(path, safe)
    escaped = _escape_lavfi_movie_path(str(safe))

Prevention

When it happens

Trigger: Calling the FFmpeg scene-detect fallback with an input_path like /tmp/user's clip.mp4 or any path produced from user-titled content (episode names, song titles) interpolated into a temp filename; on Windows, paths normalized to forward slashes still carry the quote.

Common situations: Batch pipelines processing files named from spreadsheet rows or media-library titles containing apostrophes; macOS/Unix directories like /home/o'brien/videos; user uploads retaining original filenames.

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/ec0f3a8242f58457. Report an issue: GitHub.