- Rust 100%
| src | ||
| .gitignore | ||
| .justfile | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
kutter
a cli program that can split and organize mkv files
why not just use mkvtoolnix?
I am actually! this is just a automated workflow on top of mkvtoolnix and ffmpeg that I can plug into tdar to make my life easier when ripping shows. that and I thought it'd just be a fun project to flex my programmer brain.
goal for this project
- automate the process of detecting episodes and where to split
- integrate into tdarr flow to split files before/during/after encoding
- organize the files into a format that can just plug directly into jellyfin/plex
strategies to use to find episodes
Start with duration matching as baseline. Adjust using chapter count expectations. Use chapter title metadata or duration anomalies (e.g. intros/outros) to fine-tune.
cumulative duration matching
Build a cumulative chapter time list.
Iterate over the chapters and keep summing durations until the total matches the average episode duration.
If a chapter ends slightly before or after the target, use a tolerance window
This is often the most accurate for episodes with uniform pacing.
Pros: Most direct match to episode duration Cons: Breaks if pacing is uneven or some episodes have long intros/outros
duration anomaly detection
When to use: Chapter titles are absent or unreliable, but durations are available.
What to do: Calculate the mean and standard deviation of chapter durations.
Flag chapters that are:
Much shorter (e.g. <10s, common for intros/outros)
Much longer (could signal the start of a new episode)
Identify consistent long-duration clusters (near your average episode length).
Use these chapter indices as candidate split points.
Why it helps: Some releases use chapters inconsistently, but episode breaks often fall near unusually long chapters (i.e., full content between intros/outros).
sliding window alignment
If average episode durations are reliable, use a sliding window over the chapter durations:
- Start at 0, and at each step, look ahead over n chapters.
- Find the window where sum(chapter_durations) ≈ average_episode_duration ± tolerance.
Pick the chapter boundary closest to that sum.
This is similar to what you already do, but allows you to adjust dynamically when previous episodes were under/over time.