How a one-line ffmpeg command became a script, a skill, and a story
I'm an experienced developer who'd used ffmpeg before but never dug into its internals. I was also skeptical of AI coding — worried it would produce plausible-looking code that doesn't hold up. One session later, I had three things I didn't expect: a production script, an AI agent skill package, and a clearer picture of what real AI collaboration actually looks like.
- Asked Claude to explain an ffmpeg command — discovered it was producing the wrong output duration
- Learned that a naive
-c copycut silently corrupts frames at boundaries — the keyframe problem - Built a 3-segment head/mid/tail strategy — re-encode only the edges, stream-copy the bulk
- Debugged 6 bugs including a silent timebase mismatch that inflated the output to 4780s instead of 3192s
- Added per-segment timing — revealed the tail was taking 57s for 5s of content due to full-file decoding
- Fixed it by moving
-ssbefore-i: 67s → 3s (~20× speedup) - Packaged as an AI agent skill with
SKILL.md,EXAMPLES.md, andinvoke_cut.sh
-ss before -i makes -to an absolute timestamp, not a relative one. The output file was 13 minutes long instead of 1 second. That one question kicked off the whole session.10#$hh prevents octal errors, why float comparisons need awk not bash arithmetic, why functions return via echo and command substitution.-c copy cut corrupts frames at boundaries, so we designed a head/mid/tail approach. Then came six bugs. The most significant: the output was 4780s instead of 3192s with no error. Keeping the temp files on disk (a debugging habit, not something Claude asked for) made ffprobe inspection possible — revealing the middle segment had a different timebase (1/90000 vs 1/60000). This led to codec and timescale auto-detection from the source — a suggestion that came from the human side.-ss was decoding the entire 66-minute file before every cut. Moving -ss before -i for head and tail dropped total time from 67s to 3s.EXPECTED_DURATION vs ACTUAL_DURATION with a diff printed on every run. Then came full documentation: README, DEVLOG, an interactive HTML viewer.SKILL.md, EXAMPLES.md, and invoke_cut.sh. Then the session kept going into something less expected — reviewing the collaboration itself, finding the moments that mattered, and building this page.It wasn't just "AI wrote the code"
Claude brought ffmpeg internals, bash patterns, and debugging methodology. The human side brought engineering instinct — questioning assumptions, spotting redundancy, and expanding scope. Three decisions changed the outcome more than any others.
EXPECTED_DURATION vs ACTUAL_DURATION into every run means future regressions get caught automatically — not discovered after the fact.Five questions that changed the outcome
These weren't instructions — they were observations from reading the code critically.
ffprobe is being called twice. Is it possible to only call it once and reuse it?"$START and $END as its boundaries, which might have a keyframe issue."kf_after_start and kf_before_end as the true safe boundaries.libx264/aac with no justification. This question — coming from principle — led to auto-detecting codec and timescale from the source, making the script portable across any MP4.EXPECTED_DURATION vs ACTUAL_DURATION with a diff printed on every run.cut.sh as a skill for AI agents? What should we do, and what files should we generate?"SKILL.md, EXAMPLES.md, and invoke_cut.sh so Claude can invoke it autonomously.This wasn't a flawless AI demo
Claude made real mistakes. Each one was caught through review and testing — which is exactly how it should work.
-ss before -imapfileffprobe awk parsingPattern: Claude introduced the bugs, human review caught them. Neither alone would have shipped clean code this fast.