The escape hatch that turned out to be french doors
I wanted an FFmpeg that couldn't touch my disk. Building the interface to get one accidentally produced something considerably more useful.


I wanted an FFmpeg that couldn't touch my disk. Building the interface to get one accidentally produced something considerably more useful.

Every FFmpeg progress bar I've seen scrapes the CLI's stderr. afmpeg has no CLI to scrape, so progress had to become part of the API instead.

The issue tracker is full of answers, which is exactly why my support bot isn't allowed to quote it. An issue can point at the docs, but it never gets to be the answer.

An hour to compile and 170GB of artefacts to clean up afterwards. Rust has a built-in answer to that, and I only used half of it.

I'd built this exact thing by hand, years ago, pixel perfect. So why was I sitting here shouting at a screen while a machine got it wrong three times?

Go says a constructor either works or it doesn't. That contract stops making sense the moment a client has a dozen optional parts, so I broke it on purpose.

Viper reads a dozen extensions. Mine reads one, and the other formats live somewhere else entirely. Here's what that bought, measured rather than asserted.

I set out to add a config writer and keep Viper. I ended up keeping the writer and deleting Viper, and I didn't notice until it was already gone.

I built a boundary so I wouldn't have to move my config package. Then I moved it anyway, and the boundary is the only reason that didn't hurt.

One interface posts a reel to four platforms cleanly. Their OAuth token handling refused to unify at all, which is why I built all four first.
