and backtick — filtergraphs rarely contain either.\n- **`NUL` not `/dev/null`** for two-pass logs: `-passlogfile` defaults are fine, but\n `ffmpeg ... -f null NUL` (PowerShell also accepts `-f null -`, which is portable —\n prefer it).\n- **Font paths in drawtext**: `fontfile='C\\:/Windows/Fonts/arial.ttf'` — forward\n slashes, escaped drive colon, inside the filter string.\n- **Prefer `-f null -` and relative paths** to sidestep both quoting tables at once.\n\n## Decision trees\n\n**Codec** — `H.264 (libx264)`: default; universal playback, fast, good per-bit at\n`-crf 18..23`. → `H.265 (libx265)`: same quality ~40% smaller; slower; needs\n`-tag:v hvc1` for Apple; fine for storage/modern devices. → `AV1 (libsvtav1)`: best\ncompression, royalty-free, web-first (YouTube/Netflix path); encode cost highest;\nplayback on older hardware is software-only. → `VP9`: only when a pipeline demands\nwebm and AV1 is unavailable. → `FFV1`: archival masters only.\n\n**Cut method** — Need exact frames OR applying any filter → re-encode (input-side\n`-ss`, `-crf 18`). Cut points happen to sit on keyframes (verify with\n`--keyframes-near`) OR a ±2s slop is acceptable → stream copy with\n`-avoid_negative_ts make_zero`. Many cuts from one source → EDL workflow below.\n\n**CPU vs hardware encode** — Hardware (NVENC/QSV/AMF/VideoToolbox) is 5-20× faster\nbut **worse quality per bit** than libx264/x265 at slow presets. Use hardware for:\nspeed-critical batch work, live/streaming, drafts, \"good enough\" deliveries (bump\nbitrate ~30% to compensate). Use CPU for: final masters, size-constrained targets,\nquality comparisons. Always `capability-scan.sh` first — listed encoders fail at\nruntime on driver mismatches. Details: [references/hardware-accel.md](references/hardware-accel.md).\n\n## EDL workflow (edit-as-code)\n\nFor any multi-cut edit, do not fire ad-hoc trim commands. Write an **edit decision\nlist** — a JSON file naming every clip, time range, and *why* — then cut from it.\nThe edit becomes reviewable (rationale is written down), rerunnable (regenerate the\noutput any time), and diffable (versions of the edit are git history).\n\n```bash\n# 1. Find candidate cut points (silence = clean speech boundaries):\npython skills/ffmpeg-ops/scripts/detect-segments.py --silence --json take3.mp4\n\n# 2. Author the EDL (schema: assets/edl-schema.json) with per-scene rationale.\n\n# 3. Dry-run prints every ffmpeg command it would run (default — nothing executes):\npython skills/ffmpeg-ops/scripts/cut-from-edl.py edit.json\n\n# 4. Execute: cuts + concat -> final. Re-encodes by default for frame accuracy;\n# --copy for keyframe-aligned EDLs.\npython skills/ffmpeg-ops/scripts/cut-from-edl.py edit.json --execute -o final.mp4\n```\n\nRules that make this work (from the Fable launch-video pipeline): cuts must land in\n**silence**; the model reasons over **transcripts, not frames**; after cutting,\n**re-transcribe the output to verify** (no filler words survived, no words clipped).\nFull architecture, EDL schema, verification loop:\n[references/edit-as-code.md](references/edit-as-code.md).\n\n## Color grading\n\n```bash\n# Apply a .cube LUT (tetrahedral = highest quality interpolation):\nffmpeg -i in.mp4 -vf \"lut3d=file=grade.cube:interp=tetrahedral\" \\\n -c:v libx264 -crf 18 -c:a copy graded.mp4\n\n# Generate a family of grade candidates + an HTML still-chooser:\npython skills/ffmpeg-ops/scripts/gen-luts.py --variants all --out-dir work/luts \\\n --previews in.mp4\n```\n\n**The human picks the grade.** Generate variants, render preview stills, present a\nchooser — never auto-select a look. Grading is a taste call; the agent's job is the\nlattice math and the apply command. LUT format, log-footage normalization\n(S-Log3/V-Log → Rec.709), curves/eq safe ranges, checking work with ffmpeg's\nbuilt-in scopes (waveform/vectorscope):\n[references/color-grading.md](references/color-grading.md). The 25-look recipe\ncatalog — film stocks (Kodachrome, CineStill halation, Technicolor, Eterna),\nsignature grades (Mad Max, Fincher, Matrix, BR2049, Amélie…), era/genre moods,\nSin City selective color — every chain build-validated, plus the Hald-CLUT\nmatch-any-look workflow and scope-matching ladder:\n[references/look-recipes.md](references/look-recipes.md). Pipeline correctness\n(pix_fmt, HDR→SDR tonemapping, range/matrix tagging):\n[references/color-hdr.md](references/color-hdr.md).\n\n## Quality gates\n\n```bash\n# VMAF/SSIM/PSNR verdict on an encode (exit 10 = below threshold -> branch on it):\npython skills/ffmpeg-ops/scripts/quality-compare.py reference.mp4 encoded.mp4 \\\n --metrics ssim,psnr\npython skills/ffmpeg-ops/scripts/quality-compare.py reference.mp4 encoded.mp4 \\\n --metrics vmaf --min-vmaf 90 --json | jq '.data.vmaf'\n```\n\nVMAF ≥ 93 at 1080p ≈ visually transparent; 80-93 = noticeable on inspection.\nSide-by-side visual A/B (`hstack`), metric interpretation, encode-ladder tuning:\n[references/quality-metrics.md](references/quality-metrics.md).\n\n## Scripts\n\nAll eleven follow the [Skill Resource Protocol](../../docs/SKILL-RESOURCE-PROTOCOL.md):\n`--help` with examples, stdout = data only, `--json` envelopes\n(`claude-mods.ffmpeg-ops.*/v1`), semantic exit codes (`0` ok, `2` usage, `3` input\nmissing, `4` invalid input, `5` missing dependency, `7` ffmpeg unavailable,\n`10` domain finding).\n\n| Script | Job | Worked invocation |\n|---|---|---|\n| `probe-media.py` | Normalized inspection, keyframe proximity, `--doctor` triage (hazard → fix command, exit 10) | `probe-media.py --doctor in.mp4` |\n| `capability-scan.sh` | What can THIS ffmpeg build do (proof-encodes hw encoders; `--quick` skips) | `capability-scan.sh --json \\| jq '.data.encoders'` — exit 10 = a listed encoder failed verification |\n| `quality-compare.py` | VMAF/SSIM/PSNR gate | `quality-compare.py ref.mp4 enc.mp4 --min-vmaf 90` — exit 10 = below threshold |\n| `loudnorm-scan.py` | Two-pass loudnorm: measures pass 1, emits exact pass-2 filter | `loudnorm-scan.py -I -16 in.mp4 --json \\| jq -r '.data.pass2_filter'` |\n| `detect-segments.py` | Silence/scene boundaries as JSON segments (STT chunking, dead-air cuts, shot splits) | `detect-segments.py --scenes --json in.mp4 \\| jq '.data.segments'` |\n| `cut-from-edl.py` | EDL JSON → validated cuts + concat (dry-run by default) | `cut-from-edl.py edit.json --execute -o final.mp4` |\n| `make-chapters.py` | Scene/silence points (or explicit JSON) → embedded chapters / YouTube text / WebVTT | `make-chapters.py --from-scenes --media talk.mp4 --write chaptered.mp4` |\n| `smart-compress.py` | Fit a size cap: computed two-pass bitrate, auto audio/downscale, size-verified (exit 10 = still over) | `smart-compress.py --target 25MB video.mp4` |\n| `make-sprites.py` | Scrub-preview sprite sheets + WebVTT thumbnail track (#xywh) | `make-sprites.py --interval 5 video.mp4` |\n| `gen-luts.py` | Emit .cube grade variants (+ `--previews` still chooser) | `gen-luts.py --variants warm_filmic,punchy --out-dir luts/` |\n| `verify-commands.sh` | Staleness verifier: `--offline` structural (CI), `--live` checks docs against the installed build | `verify-commands.sh --live` — exit 10 = doc drift, 7 = no ffmpeg |\n\n## References\n\nLoad on demand — one concept per file:\n\n| Reference | Load when |\n|---|---|\n| [encoding.md](references/encoding.md) | Choosing codec/CRF/preset, two-pass, social platform targets, archival |\n| [hardware-accel.md](references/hardware-accel.md) | NVENC/QSV/AMF/VideoToolbox/VAAPI flags, quality caveats, detection |\n| [filtergraph.md](references/filtergraph.md) | Any `-filter_complex`, labels/chains/split, speed ramps, xstack |\n| [trim-concat.md](references/trim-concat.md) | Cut accuracy, keyframes, concat selection, segment removal |\n| [edit-as-code.md](references/edit-as-code.md) | Multi-cut edits, EDL schema, transcript-driven editing, verify loop |\n| [audio.md](references/audio.md) | Loudness, mixing, channel layout, audio repair |\n| [stt-whisper.md](references/stt-whisper.md) | Whisper/WhisperX prep, chunking, transcript JSON, summarisation pipeline |\n| [subtitles.md](references/subtitles.md) | Burn vs soft, styling, extraction, format conversion |\n| [color-grading.md](references/color-grading.md) | LUTs, .cube format, log normalization, scopes, grade workflow |\n| [look-recipes.md](references/look-recipes.md) | 25-look catalog (film stocks, signature movie grades, era/genre moods), Hald-CLUT extraction, scope-matching |\n| [color-hdr.md](references/color-hdr.md) | pix_fmt, HDR→SDR tonemap, BT.601/709 tagging, 10-bit |\n| [quality-metrics.md](references/quality-metrics.md) | VMAF/SSIM interpretation, visual A/B, ladder tuning |\n| [streaming-hls.md](references/streaming-hls.md) | HLS/DASH packaging, ABR ladders, live restream |\n| [images-gif.md](references/images-gif.md) | GIF quality, sprite sheets, dataset frame extraction |\n| [restoration.md](references/restoration.md) | Deinterlace, denoise, deband, stabilize, audio cleanup |\n| [analysis-validation.md](references/analysis-validation.md) | Corruption checks, hashing, metadata stripping, untrusted uploads |\n| [capture-devices.md](references/capture-devices.md) | Screen/webcam capture per OS (gdigrab/dshow, avfoundation, x11grab) |\n| [error-decoder.md](references/error-decoder.md) | An ffmpeg command failed with a cryptic message — symptom → cause → fix |\n| [visualization.md](references/visualization.md) | Waveform/spectrogram videos, audiograms, comparison grids |\n| [cookbook.md](references/cookbook.md) | Any concrete command: the full recipe set by job (convert, cut, transform, overlay, audio, STT prep, images, diagnostics, yt-dlp, test sources) |\n\nAssets: [encoding-presets.json](assets/encoding-presets.json) (recipe data incl.\ndate-stamped social targets), [hls-ladder.json](assets/hls-ladder.json) (ABR ladder),\n[edl-schema.json](assets/edl-schema.json) (the cut-from-edl.py contract).\n\n## Self-test\n\n```bash\nbash skills/ffmpeg-ops/tests/run.sh # offline suite; synthesizes fixtures via lavfi\n```\n\nStructural assertions always run; media round-trips run only when ffmpeg is on PATH\n(loud skip otherwise — never a silent false-clean).\n","licenseDocuments":[]}}
L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Développement · SKILL.md

ffmpeg-ops

ffmpeg-ops

Comprehensive ffmpeg/ffprobe media processing: transcode, cut/trim/concat, color grading, loudness normalization, subtitles, GIFs, HLS packaging, hardware encoding, and quality gates (VMAF). Triggers on: ffmpeg, ffprobe, transcode, compress/convert video, extract audio, color grade, hls.

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: ffmpeg-ops description: "Comprehensive ffmpeg/ffprobe media processing: transcode, cut/trim/concat, color grading, loudness normalization, subtitles, GIFs, HLS packaging, hardware encoding, and quality gates (VMAF). Triggers on: ffmpeg, ffprobe, transcode, compress/convert video, extract audio, color grade, hls." license: MIT compatibility: "ffmpeg 5.0+ (6.0+ recommended). Scripts: bash + python3.10+. Optional per task: libvmaf, libass, libzimg, libvidstab." allowed-tools: "Read Write Edit Bash Glob Grep" metadata: author: claude-mods related-skills: color-ops, debug-ops

ffmpeg Operations

Operational expertise for ffmpeg/ffprobe: the ~30 commands that cover most real work, the footguns that silently ruin output, EDL-driven editing (edit-as-code), and eight scripts that replace the logic an agent would otherwise re-derive every task.

Doctrine: probe first

Never transcode, cut, or filter blind. Every media task starts by probing the input — codec, duration, frame rate (constant or variable?), pixel format, rotation, stream layout. Half of all "ffmpeg did something weird" reports are a property of the input the command never checked.

python skills/ffmpeg-ops/scripts/probe-media.py input.mp4            # human summary
python skills/ffmpeg-ops/scripts/probe-media.py --doctor input.mp4   # TRIAGE: hazards + exact fixes
python skills/ffmpeg-ops/scripts/probe-media.py --json input.mp4 | jq '.data.streams'
python skills/ffmpeg-ops/scripts/probe-media.py --keyframes-near 92.5 input.mp4

--doctor makes the doctrine self-enforcing: VFR, HDR transfer, rotation metadata, interlacing, non-yuv420p delivery, and moov-at-EOF each come back as a finding with the exact fix command, and exit 10 means "fix before processing". The --keyframes-near form answers "can I stream-copy a cut at 92.5s?" — it reports the nearest keyframes so you know whether a copy cut will snap (see Footguns). When a command fails with a cryptic message, decode it: references/error-decoder.md.

Before recommending an encoder, verify the build has it. Installed ffmpeg builds vary wildly (especially hardware encoders — listed ≠ working):

bash skills/ffmpeg-ops/scripts/capability-scan.sh           # full: proof-encodes each hw encoder
bash skills/ffmpeg-ops/scripts/capability-scan.sh --quick   # list-only, no GPU touch

Cookbook

Copy-paste recipes, each with the trap it avoids in its comments: references/cookbook.md. Commands are bash-form (see Windows notes); always pass -y or -n so no agent-run command goes interactive.

NeedCookbook section
Web H.264, HEVC, AV1, remux, VFR normalize, FFV1 archive, fit-to-sizeConvert and compress
Copy vs frame-accurate trim, concat demuxer vs filterCut and join
Scale, crop, 9:16 blurred pad, rotate, fps, speed, slow-mo, timelapseResize, transform, retime
Watermark, drawtext timecode, burned vs soft subtitlesOverlay, text, subtitles
Extract, replace, mix, loudness, trim silenceAudio
16 kHz mono STT extraction, piping, silence chunkingSpeech-to-text prep
Thumbnails, contact sheets, GIFs, chapters, dataset frames, spritesImages, GIFs, frames
Corruption check, frame hashes, metadata strip, ffprobe one-linersDiagnostics and validation
Post-download yt-dlp patternsyt-dlp interop
Synthetic test fixturesGenerative/test sources

Footguns

The table that pays this skill's rent. Each row is a class of silent failure.

FootgunThe trapThe rule
-ss + -c copyCut starts seconds early or with frozen/black lead-in (snapped to prior keyframe)Copy cuts snap. Check probe-media.py --keyframes-near; re-encode when exact
Output-side -to after input-side -ssTimestamps reset at the seek point, so -to silently becomes a durationKeep -ss/-to on the same side of -i (both input-side is fast and absolute)
Missing -pix_fmt yuv420pEncode "works" but Safari/QuickTime/TVs show black or refuse to play (defaulted to yuv444p/yuv422p from a high-quality source)Always set it for delivery H.264/H.265
Missing -movflags +faststartBrowser can't start playback until the whole file downloads (moov at EOF)Always set it for web-served MP4
Default stream selectionffmpeg picks ONE stream per type (highest-res video, most-channels audio) — extra audio tracks and all subs are silently dropped-map 0 to keep everything, explicit -map otherwise
-vf + -c:v copy togetherHard error — filters require decodingFiltering implies re-encode; pick one
VFR source (phone/Zoom/Loom/screen-rec)Cut math drifts, concat desyncs, players stutterNormalize first: -fps_mode cfr -r 30 + re-encode (cookbook)
-vsync (deprecated)Old flag, removed directionUse -fps_mode (cfr/vfr/passthrough)
scale=W:-1Odd height → encoder error with yuv420pAlways -2
concat demuxer on mismatched inputs"Works" then glitches/desyncs at boundaries (codec/timebase mismatch)Demuxer = identical params only; else concat filter with re-encode
amix defaultEach input's volume halved (normalize defaults on)amix=...:normalize=0 + explicit volume=
One-pass loudnormDynamic mode pumps quiet passages; output silently 192 kHzTwo-pass linear via loudnorm-scan.py; add -ar 48000
-shortest absent on audio-replaceOutput runs as long as the LONGEST input (silence or frozen frame tail)Add -shortest when muxing separate A/V
BT.601/709 colour shiftSlightly wrong colours after scaling SD↔HD (matrix guessed from resolution)Tag explicitly when it matters: see references/color-hdr.md
drawtext/subtitles path escapingFilter args re-parse : and \ — Windows paths like C:\x explode inside filter stringscd to the asset's dir and use bare relative names; or escape as C\:/path
Interactive overwrite promptAgent-run command hangs forever on "File exists. Overwrite? [y/N]"Always pass -y or -n explicitly
% in cmd.exe%06d patterns and %{pts} get mangled by cmd variable expansionUse PowerShell or bash; in .bat double to %%

Windows notes

Platform-agnostic commands, but when running on Windows:

  • PowerShell quoting is friendlier than bash here: single quotes are fully literal, so -vf 'scale=1280:-2,fps=30' needs no escaping. Double quotes only interpolate $ and backtick — filtergraphs rarely contain either.
  • NUL not /dev/null for two-pass logs: -passlogfile defaults are fine, but ffmpeg ... -f null NUL (PowerShell also accepts -f null -, which is portable — prefer it).
  • Font paths in drawtext: fontfile='C\:/Windows/Fonts/arial.ttf' — forward slashes, escaped drive colon, inside the filter string.
  • Prefer -f null - and relative paths to sidestep both quoting tables at once.

Decision trees

Codec — H.264 (libx264): default; universal playback, fast, good per-bit at -crf 18..23. → H.265 (libx265): same quality ~40% smaller; slower; needs -tag:v hvc1 for Apple; fine for storage/modern devices. → AV1 (libsvtav1): best compression, royalty-free, web-first (YouTube/Netflix path); encode cost highest; playback on older hardware is software-only. → VP9: only when a pipeline demands webm and AV1 is unavailable. → FFV1: archival masters only.

Cut method — Need exact frames OR applying any filter → re-encode (input-side -ss, -crf 18). Cut points happen to sit on keyframes (verify with --keyframes-near) OR a ±2s slop is acceptable → stream copy with -avoid_negative_ts make_zero. Many cuts from one source → EDL workflow below.

CPU vs hardware encode — Hardware (NVENC/QSV/AMF/VideoToolbox) is 5-20× faster but worse quality per bit than libx264/x265 at slow presets. Use hardware for: speed-critical batch work, live/streaming, drafts, "good enough" deliveries (bump bitrate ~30% to compensate). Use CPU for: final masters, size-constrained targets, quality comparisons. Always capability-scan.sh first — listed encoders fail at runtime on driver mismatches. Details: references/hardware-accel.md.

EDL workflow (edit-as-code)

For any multi-cut edit, do not fire ad-hoc trim commands. Write an edit decision list — a JSON file naming every clip, time range, and why — then cut from it. The edit becomes reviewable (rationale is written down), rerunnable (regenerate the output any time), and diffable (versions of the edit are git history).

# 1. Find candidate cut points (silence = clean speech boundaries):
python skills/ffmpeg-ops/scripts/detect-segments.py --silence --json take3.mp4

# 2. Author the EDL (schema: assets/edl-schema.json) with per-scene rationale.

# 3. Dry-run prints every ffmpeg command it would run (default — nothing executes):
python skills/ffmpeg-ops/scripts/cut-from-edl.py edit.json

# 4. Execute: cuts + concat -> final. Re-encodes by default for frame accuracy;
#    --copy for keyframe-aligned EDLs.
python skills/ffmpeg-ops/scripts/cut-from-edl.py edit.json --execute -o final.mp4

Rules that make this work (from the Fable launch-video pipeline): cuts must land in silence; the model reasons over transcripts, not frames; after cutting, re-transcribe the output to verify (no filler words survived, no words clipped). Full architecture, EDL schema, verification loop: references/edit-as-code.md.

Color grading

# Apply a .cube LUT (tetrahedral = highest quality interpolation):
ffmpeg -i in.mp4 -vf "lut3d=file=grade.cube:interp=tetrahedral" \
  -c:v libx264 -crf 18 -c:a copy graded.mp4

# Generate a family of grade candidates + an HTML still-chooser:
python skills/ffmpeg-ops/scripts/gen-luts.py --variants all --out-dir work/luts \
  --previews in.mp4

The human picks the grade. Generate variants, render preview stills, present a chooser — never auto-select a look. Grading is a taste call; the agent's job is the lattice math and the apply command. LUT format, log-footage normalization (S-Log3/V-Log → Rec.709), curves/eq safe ranges, checking work with ffmpeg's built-in scopes (waveform/vectorscope): references/color-grading.md. The 25-look recipe catalog — film stocks (Kodachrome, CineStill halation, Technicolor, Eterna), signature grades (Mad Max, Fincher, Matrix, BR2049, Amélie…), era/genre moods, Sin City selective color — every chain build-validated, plus the Hald-CLUT match-any-look workflow and scope-matching ladder: references/look-recipes.md. Pipeline correctness (pix_fmt, HDR→SDR tonemapping, range/matrix tagging): references/color-hdr.md.

Quality gates

# VMAF/SSIM/PSNR verdict on an encode (exit 10 = below threshold -> branch on it):
python skills/ffmpeg-ops/scripts/quality-compare.py reference.mp4 encoded.mp4 \
  --metrics ssim,psnr
python skills/ffmpeg-ops/scripts/quality-compare.py reference.mp4 encoded.mp4 \
  --metrics vmaf --min-vmaf 90 --json | jq '.data.vmaf'

VMAF ≥ 93 at 1080p ≈ visually transparent; 80-93 = noticeable on inspection. Side-by-side visual A/B (hstack), metric interpretation, encode-ladder tuning: references/quality-metrics.md.

Scripts

All eleven follow the Skill Resource Protocol: --help with examples, stdout = data only, --json envelopes (claude-mods.ffmpeg-ops.*/v1), semantic exit codes (0 ok, 2 usage, 3 input missing, 4 invalid input, 5 missing dependency, 7 ffmpeg unavailable, 10 domain finding).

ScriptJobWorked invocation
probe-media.pyNormalized inspection, keyframe proximity, --doctor triage (hazard → fix command, exit 10)probe-media.py --doctor in.mp4
capability-scan.shWhat can THIS ffmpeg build do (proof-encodes hw encoders; --quick skips)capability-scan.sh --json | jq '.data.encoders' — exit 10 = a listed encoder failed verification
quality-compare.pyVMAF/SSIM/PSNR gatequality-compare.py ref.mp4 enc.mp4 --min-vmaf 90 — exit 10 = below threshold
loudnorm-scan.pyTwo-pass loudnorm: measures pass 1, emits exact pass-2 filterloudnorm-scan.py -I -16 in.mp4 --json | jq -r '.data.pass2_filter'
detect-segments.pySilence/scene boundaries as JSON segments (STT chunking, dead-air cuts, shot splits)detect-segments.py --scenes --json in.mp4 | jq '.data.segments'
cut-from-edl.pyEDL JSON → validated cuts + concat (dry-run by default)cut-from-edl.py edit.json --execute -o final.mp4
make-chapters.pyScene/silence points (or explicit JSON) → embedded chapters / YouTube text / WebVTTmake-chapters.py --from-scenes --media talk.mp4 --write chaptered.mp4
smart-compress.pyFit a size cap: computed two-pass bitrate, auto audio/downscale, size-verified (exit 10 = still over)smart-compress.py --target 25MB video.mp4
make-sprites.pyScrub-preview sprite sheets + WebVTT thumbnail track (#xywh)make-sprites.py --interval 5 video.mp4
gen-luts.pyEmit .cube grade variants (+ --previews still chooser)gen-luts.py --variants warm_filmic,punchy --out-dir luts/
verify-commands.shStaleness verifier: --offline structural (CI), --live checks docs against the installed buildverify-commands.sh --live — exit 10 = doc drift, 7 = no ffmpeg

References

Load on demand — one concept per file:

ReferenceLoad when
encoding.mdChoosing codec/CRF/preset, two-pass, social platform targets, archival
hardware-accel.mdNVENC/QSV/AMF/VideoToolbox/VAAPI flags, quality caveats, detection
filtergraph.mdAny -filter_complex, labels/chains/split, speed ramps, xstack
trim-concat.mdCut accuracy, keyframes, concat selection, segment removal
edit-as-code.mdMulti-cut edits, EDL schema, transcript-driven editing, verify loop
audio.mdLoudness, mixing, channel layout, audio repair
stt-whisper.mdWhisper/WhisperX prep, chunking, transcript JSON, summarisation pipeline
subtitles.mdBurn vs soft, styling, extraction, format conversion
color-grading.mdLUTs, .cube format, log normalization, scopes, grade workflow
look-recipes.md25-look catalog (film stocks, signature movie grades, era/genre moods), Hald-CLUT extraction, scope-matching
color-hdr.mdpix_fmt, HDR→SDR tonemap, BT.601/709 tagging, 10-bit
quality-metrics.mdVMAF/SSIM interpretation, visual A/B, ladder tuning
streaming-hls.mdHLS/DASH packaging, ABR ladders, live restream
images-gif.mdGIF quality, sprite sheets, dataset frame extraction
restoration.mdDeinterlace, denoise, deband, stabilize, audio cleanup
analysis-validation.mdCorruption checks, hashing, metadata stripping, untrusted uploads
capture-devices.mdScreen/webcam capture per OS (gdigrab/dshow, avfoundation, x11grab)
error-decoder.mdAn ffmpeg command failed with a cryptic message — symptom → cause → fix
visualization.mdWaveform/spectrogram videos, audiograms, comparison grids
cookbook.mdAny concrete command: the full recipe set by job (convert, cut, transform, overlay, audio, STT prep, images, diagnostics, yt-dlp, test sources)

Assets: encoding-presets.json (recipe data incl. date-stamped social targets), hls-ladder.json (ABR ladder), edl-schema.json (the cut-from-edl.py contract).

Self-test

bash skills/ffmpeg-ops/tests/run.sh   # offline suite; synthesizes fixtures via lavfi

Structural assertions always run; media round-trips run only when ffmpeg is on PATH (loud skip otherwise — never a silent false-clean).

Skills enregistrées