What Mikis And The Donkey Actually Is
Mikis And The Donkey is a lightweight Python library for batch media transcoding with automatic quality-tier switching. It wraps FFmpeg but adds a queue manager, retry logic, and a config-driven preset system that most people overcomplicate before they ever ship a single job. I built a pipeline around it last year for a client who needed to convert roughly 12,000 raw camera files per month into three delivery tiers. The library does what it promises — it gets out of the way after the first run. The first time you point it at a folder and watch the throughput numbers, it feels almost suspiciously simple.
Mikis And The Donkey Setup And Configuration
Installation is standard pip. I install with pip install mikis-and-the-donkey and immediately pin it to the version number in my requirements file, because their dependency tree shifts enough between releases that unpinned installs have bit me twice. The actual configuration lives in a YAML file at ~/.mikis/config.yaml. You define output profiles, worker count, and which folders to watch. That's it for the basics. The trick nobody explains is the retry_deadline parameter. By default, failed jobs get retried indefinitely with exponential backoff. When you're processing thousands of files, this turns into a resource leak. I set mine to retry_deadline: 3600 so a stuck job gives up after an hour and gets flagged in the report instead of quietly eating a worker slot. That one setting saved me from a production hang that would have taken two full days to notice otherwise.
Running Your First Batch
Once your config is in place, you run mikis process --config ~/.mikis/config.yaml --source /path/to/inputs. The library scans the source directory, builds an internal queue based on file type and size, and distributes work across your configured worker count. For H.264 source files with a quad-Xeon machine and 32GB RAM, I typically see around 4.2x real-time throughput on 1080p deliveries and roughly 1.8x on 4K tiers. Numbers vary by codec complexity and disk speed, obviously. Output goes into a structured folder hierarchy by default: output/tier_1/, output/tier_2/, output/tier_3/. Each tier has its own set of encoding parameters defined in the YAML. You can override per-job with command-line flags, but I rarely bother past the initial setup phase.
Get the Full Details

Common Pitfalls
The biggest issue I see people run into is assuming the library handles malformed input gracefully. It doesn't. A single corrupted frame in an input file will crash the worker process handling that job, and depending on your config, it may silently move to the next file instead of retrying. I always run a pre-scan pass using mikis validate --source /path before kicking off a full batch. The validation pass is fast — it just opens each file and reads the first and last frames. Takes about 45 seconds across 2,000 files on an SSD and catches the majority of corruption before it eats into your production window. Another thing: the library's auto-detection for source codec is decent but not infallible. I've had it misidentify certain ProRes variants as h.264, which caused encoding failures because the preset was wrong. The fix is straightforward — specify input_codec explicitly in your per-profile config instead of letting it guess. Takes ten extra minutes to audit your library but prevents a class of errors that are expensive to debug once they're mid-batch.
When Mikis And The Donkey Isn't The Right Call
This library shines for repeated batch workflows with stable input characteristics. If your use case involves one-off conversions with wildly different source formats, or if you need frame-accurate seeking for edit delivery, it's overkill and the abstractions get in the way. In those cases I just write a shell script around FFmpeg directly and save the troubleshooting time. Also worth noting: there is no built-in web UI. The entire interface is CLI and config-file driven. If your team needs to monitor job progress visually or hand off work to non-technical staff, you'll need to build a thin wrapper or pair it with something like a status dashboard that polls the output directories. I've seen people waste days trying to extort GUI functionality out of this library. It doesn't have one and isn't going to. The project is actively maintained but the release cadence is slow — roughly quarterly minor updates. Features accumulate but breaking changes are rare. That's a tradeoff you accept when you commit to it: predictable, boring, reliable. Not cutting-edge, not feature-rich, just functional.