KeyTune is a media player built with Python, wxPython, and MPV.
KeyTune 2 also includes a permission-based plugin platform, process-isolated plugin lifecycle, accessible plugin manager, verified package installer, and a GitHub-friendly marketplace workflow. See the plugin developer and marketplace guide (Português, Español).
It focuses on playlist management, folder browsing, session restore, and persistent user preferences.
- Embedded MPV playback inside a wxPython window
- Tabbed playlists and a folder explorer next to the tabs (
Ctrl+E) .m3uand.m3u8playlist loading and saving- Session restore for tabs, playback position, volume, and the current item
- Persistent preferences stored in
settings.json - Recent files, folders, and playlists
- Item search inside the active playlist or folder (
Ctrl+F,F3,Shift+F3) - Smart library: FTS5-backed global search across indexed playlists and folders (
Ctrl+G) - Favorites (
Ctrl+D) and star ratings (Ctrl+0–Ctrl+5) for local media, shown inline in the item list - Local playback history with all-plays, grouped, and most-played views (
Ctrl+Shift+H) - Per-file resume for podcasts, audiobooks, and other long-form media, plus a "continue listening" list (
Ctrl+Shift+R) - Smart playlists: saved rules (favorites, rating, folder, staleness, play count) rebuilt on every open
- AutoDJ sessions with a visible rolling queue, per-track state, preparation controls, multi-track planning, downbeat/section/key/vocal analysis, loudness-aware selection, phrase alignment, tempo matching, and profile-specific bass/EQ mixing
- Sleep timer with preset durations, a custom duration, or an end-of-track stop (
Ctrl+Shift+D) - Built-in equalizer presets plus custom presets
- KeyTube (
Ctrl+Shift+Y): YouTube Music and YouTube in one list, with search, link-based open flows, channels, subscriptions, comments, details, library refresh, and account-synced likes/dislikes - Online radio from the Radio Browser directory (
Ctrl+Shift+N), with favorites, recents, and browsing by country, genre, and language - Optional YouTube Music related-content autoplay (radio) when a playlist ends
- YouTube live broadcasts from a link, with audio and optional video (
Ctrl+Alt+Vtoggles video output), automatic reconnection, and accessible status announcements - Audio and video conversion between formats (
Ctrl+Shift+K, File > Convert): audio to video, video to audio, audio to audio, and video to video, powered by FFmpeg - Batch download and conversion: the selected list items or a whole YouTube playlist (into a folder named after it), and several local files at once, from the list's context menu
- Download of the current YouTube or YouTube Music media as audio (original, MP3, FLAC) or video with
Ctrl+Shift+B, using yt-dlp, with configurable quality, sample rate, and folder in a new Download preferences tab - Fresh per-track YouTube Music radio (
Ctrl+R) with recent-playback repeat suppression - Keyboard customization (Settings > Customize keyboard): change, remove, or restore any shortcut, with conflict checks
- Global shortcuts (Windows) for playback, volume, status, and showing or hiding the window, plus a system tray icon with minimize/close-to-tray options
- Python 3.14
python-mpvinstalled in the active Python environment- A compatible libmpv runtime available in one of these locations:
- a local
mpv/folder - the path pointed to by
MPV_HOME - the path pointed to by
MPV_DLL_DIR - a supported Chocolatey installation path
- a local
Python 3.14 is required for source development and is also used by the Windows release build.
-
Clone the repository.
git clone https://github.com/Ed-Fe/KeyTune.git cd KeyTune -
Install uv.
-
Install dependencies. This creates
.venvwith Python 3.14 and installs the exact versions pinned inuv.lock.uv sync
The command also installs the optional YouTube Music and AutoDJ integrations for source-tree development. Release builds publish these components separately and the installed app downloads them only after the user enables and confirms the corresponding feature.
-
Download the MPV runtime for local development.
uv run python scripts/download_mpv_runtime.pyThis helper downloads the latest
mpv-winbuildrelease, extracts the folder containinglibmpv-2.dll, and writes it to./mpv/by default. It depends on7zor 7-Zip to unpack the.7zarchive.If you already have a compatible runtime in another location, you can skip this step and point
MPV_HOME,MPV_DLL_DIR, or a Chocolatey installation to it. -
Run the application.
uv run keytune
Useful project links:
The Windows release workflow is defined in .github/workflows/release-windows.yml. It builds the app, bundles the MPV runtime, compiles the Inno Setup installer (installer/keytune.iss), and publishes KeyTune-Setup.exe plus the matching SHA256 file.
The installer supports both per-user (no admin) and per-machine installs, registers KeyTune for Windows "Default apps", and drives updates: the app downloads KeyTune-Setup.exe and runs it silently to upgrade in place, then relaunches.
For a repeatable end-to-end updater test flow, see docs/update-testing.md.
src/main.py— application entry pointsrc/player/app.py— wx application bootstrapsrc/player/frames/base.py— main window coordinator and mixin compositionsrc/player/frames/ui.py— menus, layout, and UI bindingssrc/player/frames/commands.py— event handlers, dialogs, and shortcutssrc/player/frames/playback.py— playback control and MPV integrationsrc/player/frames/library.py— library mixin compositionsrc/player/frames/library_tabs.py— tab state, selection, and ordering behaviorsrc/player/frames/library_loader.py— background loading for folders and playlistssrc/player/frames/library_navigation.py— folder navigation and browser refresh flowssrc/player/frames/session.py— session capture and restoresrc/player/frames/recents.py— recent items and path helperssrc/player/playlists/models.py— playlist state and playback order helperssrc/player/playlists/titles.py— playlist and folder tab naming helperssrc/player/library/media_scan.py— supported media checks and folder scanning helperssrc/player/library/playlist_io.py—.m3u/.m3u8load and save helperssrc/player/library/browser.py— side panel for playlist and folder navigationsrc/player/library/search_dialog.py— item search dialog (Ctrl+F)src/player/frames/item_search.py— item search coordination and result navigationsrc/player/smart_library/— smart library storage (SQLite index, favorites, ratings, history, resume, metadata cache)src/player/smart_library/search_dialog.py— global library search dialog (Ctrl+G)src/player/smart_library/history_dialog.py— playback history dialog (Ctrl+Shift+H)src/player/smart_library/smart_playlists.py— smart playlist rules and their query buildersrc/player/smart_library/smart_playlist_dialog.py— smart playlist manager and rule editorsrc/player/frames/smart_library/— window behavior for the smart librarysrc/player/frames/sleep_timer.py— sleep timer scheduling and countdown handlingsrc/player/sleep_timer/dialog.py— sleep timer configuration dialogsrc/player/keyboard/— shortcut catalog, customization rules, and the keyboard customization dialogsrc/player/frames/keyboard.py,global_hotkeys.py,tray.py— custom shortcuts, global hotkeys, and the system tray iconsrc/player/preferences/dialog.py— preferences UIsrc/player/preferences/models.py— persistent user settings modelsrc/player/preferences/storage.py— persistent user settings storagesrc/player/session.py— session persistencesrc/player/accessibility.py— shared UI helpers
Contributions are welcome. Start with CONTRIBUTING.md for the recommended workflow, local setup, and validation steps.
In short:
- Fork the repository and create a feature branch.
- Make focused changes that match the existing architecture.
- Run the relevant validation before opening a pull request.
- Describe the behavior change clearly in the PR description.