Gmpv
I like mpv. I wanted to build a video player around it for my GNOME desktop, exactly to my liking.
So I built one.
What It Does
Gmpv is a GTK4/libadwaita video player that uses mpv as its playback engine. That’s it. No playlist manager, no library scanner, no media server integration. You open a video, it plays. It looks like it belongs on your GNOME desktop because it actually uses your GNOME desktop’s toolkit.
It supports both Wayland and X11. On Wayland it renders through OpenGL via libmpv. On X11 it embeds mpv directly using the window ID. No abstraction layers eating your CPU. Just mpv doing what mpv does best.
The Controls
The controls bar is a floating pill that hovers at the bottom center of the video, QuickTime-style. Translucent black background, rounded corners, two rows. It auto-hides after 2 seconds along with the headerbar and cursor.
┌─────────────────────────────────────────────────────┐
│ 0:00 [═══════════ Seek Bar ═══════════] 5:45 │
│ [Vol] [⏪] [▶/⏸] [⏩] [Sub][🔊][⛶] │
└─────────────────────────────────────────────────────┘
Top row is the seek bar with timestamps on each side. Bottom row has volume on the left, skip back/play-pause/skip forward in the center, and subtitle track, audio track, and fullscreen buttons on the right. The skip buttons jump 10 seconds.
Subtitle and audio track switching is built in. If your file has multiple tracks, you get menu buttons in the controls bar to switch between them.
Keyboard shortcuts:
| Key | What it does |
|---|---|
| Space | Play/pause |
| Left/Right arrows | Seek 5 seconds |
| Up/Down arrows | Volume |
| F | Fullscreen |
| Escape | Exit fullscreen |
| M | Mute |
| Q | Quit |
| Ctrl+O | Open file |
Mouse:
| Action | What it does |
|---|---|
| Single click | Play/pause (or open file if nothing loaded) |
| Double click | Fullscreen |
| Right click | Context menu |
| Drag and drop | Open file |
When you open a file, the title bar updates with the filename and a toast notification pops up briefly.
The Stack
The whole thing is Python with PyGObject. The UI is built with GTK4 and libadwaita. The player backend is python-mpv which talks directly to libmpv. The build system is meson.
| Component | Role |
|---|---|
| GTK4 | UI toolkit |
| libadwaita | GNOME styling and widgets |
| python-mpv | mpv bindings |
| libmpv | Actual playback |
| meson | Build and install |
Four source files. That’s the entire application. main.py handles the application lifecycle and actions. window.py sets up the window, video rendering, keyboard shortcuts, and drag and drop. player.py wraps mpv. controls.py draws the controls bar.
Wayland Rendering
This was the interesting part. On Wayland you can’t just pass a window ID to mpv and call it a day. You need to set up an OpenGL render context, hook into GtkGLArea, and manually call mpv’s render API every frame.
The flow looks like this: mpv tells us it has a new frame ready, we ask GTK to queue a render, GTK calls our render callback, we grab the current framebuffer object and tell mpv to draw into it. The get_proc_address callback goes through EGL so mpv can resolve OpenGL function pointers at runtime.
It sounds complicated but it’s about 40 lines of code. On X11 you just pass the window ID and mpv handles the rest.
Installing
sudo pacman -S gtk4 libadwaita mpv python-gobject
pip install python-mpv
meson setup builddir --prefix=/usr
sudo meson install -C builddir
Or just run it directly from the repo:
./gmpv
The Source
The whole thing is on GitHub. GPL 2.0. Do whatever you want with it.