#!/usr/bin/env bash set -euo pipefail INPUT="" OUTDIR="" COUNT="14" while [[ $# -gt 0 ]]; do case "$1" in --input) INPUT="$2" shift 2 ;; --outdir) OUTDIR="$2" shift 2 ;; --count) COUNT="$2" shift 2 ;; *) echo "Unknown arg: $1" >&2 exit 1 ;; esac done if [[ -z "$INPUT" || -z "$OUTDIR" ]]; then echo "Usage: $0 --input --outdir [--count 14]" >&2 exit 1 fi if [[ ! -f "$INPUT" ]]; then echo "Input file not found: $INPUT" >&2 exit 1 fi mkdir -p "$OUTDIR" rm -f "$OUTDIR"/frame_*.jpg DURATION="$(ffprobe -v error -show_entries format=duration -of default=nokey=1:noprint_wrappers=1 "$INPUT")" python3 - "$INPUT" "$OUTDIR" "$COUNT" "$DURATION" <<'PY' import os import subprocess import sys inp, outdir, count_s, dur_s = sys.argv[1:] count = max(1, int(count_s)) duration = float(dur_s) if duration <= 0: print("Invalid duration", file=sys.stderr) sys.exit(1) # Centered uniform sampling across full duration. step = duration / count times = [min(duration - 0.01, (i + 0.5) * step) for i in range(count)] for idx, t in enumerate(times, start=1): out = os.path.join(outdir, f"frame_{idx:02d}.jpg") cmd = [ "ffmpeg", "-y", "-ss", f"{t:.6f}", "-i", inp, "-frames:v", "1", "-q:v", "2", out, ] subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) print(f"Extracted {count} frames to {outdir}") PY ls -1 "$OUTDIR"/frame_*.jpg