ButterEye

ButterEye logo

ButterEye

ButterEye is a free, open-source (AGPL-3.0-or-later) smooth-motion control center for mpv on Linux: it interpolates video to a rate that suits your display with RIFE (Vulkan, via VapourSynth) or MVTools, live in mpv or as an offline render. It works with your distribution’s own mpv and never edits your mpv.conf. Status: pre-alpha; the design lives in docs/SCOPE.md and docs/design/GUI.md.

Copyright (C) 2026 The ButterEye contributors. This program comes with ABSOLUTELY NO WARRANTY; see the GNU Affero General Public License v3.0 or later, full text in COPYING. Files ButterEye generates from its templates (.vpy scripts, buttereye.conf, input.conf snippets, render job manifests) carry an additional permission under AGPL section 7, in LICENSES/AdditionRef-ButterEye-generated-output.txt (SCOPE §8.4; the wording is due a final check before the first public release). Both files are shown in About, ship in the sdist and wheel (license-files), and must ship as %license in the RPM.

Status

Pre-alpha, verified on the dev box (Fedora 44, RTX 4090, mpv 0.41.0, VapourSynth R72) on 2026-10-07. “Works” means it ran against the real tools, not a fake.

Works for real

Not in this build yet (the GUI shows an “isn’t in this build yet” panel, BE-9001)

Known gaps

Screenshots

Taken over the real core on the dev box. The top row and the speed test show the default window and its Details dialog; the setup wizard and the rest come from the classic multi-page window (BUTTEREYE_DEV=1 … --classic, see below). More are in docs/design/screenshots/.

The default window, playing a video smoothly
The default window, playing a video smoothly
The same window with a dark palette
The same window with a dark palette
First start: the GPU is measured in the background
First start: the GPU is measured in the background
Setup wizard (classic window): checks first, nothing saved until the end
Setup wizard (classic window): checks first, nothing saved until the end
Details: the in-mpv speed test
Details: the in-mpv speed test
Benchmark results (classic window): RIFE v4.26 vs MVTools, in mpv and in vspipe
Benchmark results (classic window): RIFE v4.26 vs MVTools, in mpv and in vspipe
Live session details (classic window): rates, engine, frame drops
Live session details (classic window): rates, engine, frame drops
Profiles & Rules (classic window): built-in Quality, Balanced, Fast and CPU profiles
Profiles & Rules (classic window): built-in Quality, Balanced, Fast and CPU profiles
System checks (classic window): causes, fixes and raw evidence for each finding
System checks (classic window): causes, fixes and raw evidence for each finding

Development setup (Fedora 44)

The GUI uses the distro PySide6 (python3-pyside6, Essentials modules only), so the virtualenv sees system site-packages:

python3 -m venv --system-site-packages .venv
.venv/bin/pip install pytest pytest-qt pytest-asyncio ruff mypy

Runtime tools the core talks to: mpv (≥ 0.41 with the VapourSynth filter), vspipe (VapourSynth), ffmpeg, and the ButterEye COPR plugin packages (buttereye-vs-rife-ncnn, buttereye-vs-mvtools, buttereye-rife-ncnn-models).

Run the GUI

.venv/bin/python -m buttereye.gui

(The buttereye-gui entry point does the same once the package is installed.)

ButterEye opens one small window with two drop zones. Drop a video on the left one (or press Open video…, Ctrl+O) and it plays in mpv with smooth motion; drop one on the right (or press Convert a video…, Ctrl+Shift+O) to save a smooth copy as a new file. There are four choices:

To keep CPU and GPU load down, live CPU smoothing (MVTools) searches at full-pixel precision (pel=1) from 720p up, switches to its faster block mode when it can’t keep up (4K on most CPUs; spike M0(p)), and converted files use the lighter software encoder presets libx265 fast and libsvtav1 8 (about 1.5-2× less CPU than medium/6, for files a few % larger at the same quality setting); conversions keep MVTools at pel=2. See SCOPE §7.5.

Each playing video gets a row with its rates (for example “24 → 48 fps”), whether the GPU or the CPU is smoothing it, a Pause smoothing button and Let go (mpv keeps playing; ButterEye stops managing it).

The first start sets ButterEye up silently (checks, a short test run, settings) and then measures your GPU in the background for about a minute; you can play videos while it runs. ButterEye never edits your mpv.conf. Details ▸ has the system checks (with error codes and fix commands), the speed test, storage and licences.

Your choices are stored in ~/.config/buttereye/config.toml as one profile, simple, with a single rule that uses it. The earlier multi-page window (profiles, rules, render) is still available for development: BUTTEREYE_DEV=1 .venv/bin/python -m buttereye.gui --classic.

The buttereye command

Everything the window does is also a command (SCOPE §4.1), over the same core: buttereye doctor [--trt], setup [--trt-experimental], play FILE [--profile ID] (stays until mpv closes; Ctrl+C leaves mpv playing), render FILE [-o OUT] [--size WxH] [--target 2x|60] [--encoder E], bench [--width W --height H --fps F] [--history] [--apply LABEL], profiles list|explain --fps F --height H, plugins, models, clean --dry-run|--engines…, licence, --version. Every command takes --json (one versioned document), -v/-q, and honours NO_COLOR. Exit codes: 0 ok, 1 failure, 2 usage or config, 3 blocking doctor issue, 4 dependency missing, 130 cancelled. attach and detach say they aren’t in this build yet.

Building the RPMs

packaging/ holds the specs for the application and its three plugin packages (SCOPE §9; details in packaging/README.md). One command builds the SRPMs and rebuilds each in mock for Fedora 44 and 45 with networking off, as the COPR will:

packaging/build.sh                    # or: packaging/build.sh --srpm-only

Tests and checks

QT_QPA_PLATFORM=offscreen QT_ACCESSIBILITY=1 .venv/bin/pytest
.venv/bin/ruff check .
.venv/bin/mypy buttereye/core buttereye/gui   # strict, see pyproject.toml

The suite runs under memory failsafes (tools/memguard.py). It refuses to start when less than 4 GiB is available, and runs inside a systemd user scope capped at 8 GiB, so only the tests are killed if they go over. A watchdog also stops the run and every mpv/vspipe it started when the system falls below 3 GiB available. To change these, set BUTTEREYE_MEM_MAX_MIB, BUTTEREYE_MEM_START_MIB or BUTTEREYE_MEM_FLOOR_MIB; BUTTEREYE_NO_MEMCAP=1 drops the cap but keeps the other two. tools/perf/breakdown.py uses the same failsafes.

Markers: integration (needs mpv and vspipe), gpu (needs a real GPU), devbox (needs the installed buttereye-* RPMs) are skipped automatically when their requirements are missing; manual runs only with --run-manual. Tests never touch your real ~/.config: the xdg_env fixture points HOME and every XDG directory at temporary directories.

Layout