## About the Name
The _kopuz_ is an ancient Turkic string instrument and is often considered the
ancestor of many Central Asian lutes. It was traditionally used by bards and
shamans.
The Kyrgyz _komuz_ is not the same instrument, but likely a descendant of the
_kopuz_. The Kazakh _kobyz_ is also related, though it is bowed rather than
plucked. In contrast, the Tuvan/Yakut _xomus_ (jaw harp) is unrelated, despite
the similar name.
In Turkic legend, the _kopuz_ is linked to Dede Korkut, a legendary bard, though
this is mythological rather than historical.
## Overview
Kopuz allows you to scan your local directories for audio files, stream from
your Jellyfin or Subsonic (Navidrome, etc.) server, or connect **YouTube Music**
or **SoundCloud** as a streaming backend, automatically organizing everything
into a browsable library. You can navigate by artists, albums, genres, or
explore your custom playlists. The application is built for performance and
desktop integration, utilizing the power of Rust.
Library, playlists, favorites, and settings are stored in a local **SQLite**
database (`kopuz.db`); the UI reads it live so changes show up immediately. Each
media source carries its own credentials and its own favorites.
## Features
[jellyfin-plugin-listenbrainz]: https://github.com/lyarenei/jellyfin-plugin-listenbrainz
- **Theming**: Includes dynamic theming support to customize the visual
appearance. You can also build your own custom theme from scratch with full
color variable control.
- **Native Integration**: Integrates with system media controls on Linux
(MPRIS), macOS (Now Playing / Remote Command Center), and Windows (System
Media Transport Controls).
- **Mini-Player**: A compact player overlay you can toggle from the bottom bar
for a smaller now-playing view.
- **Minimize to Tray**: Optionally close to a system tray icon instead of
quitting, so playback keeps running in the background. Toggle in **Settings**.
Requires the appindicator library on Linux (see Installation notes).
- **Discord RPC**: Embedded RPC included!!!
- **Multiple Backends**: Stream from your Jellyfin or Subsonic-compatible server
(Navidrome works great), connect YouTube Music or SoundCloud, or just point it
at a local folder. Mix and match as you like. Every source is exposed through
one unified `MediaSource` layer, and the UI adapts to each source's
capabilities (search, downloads, radio, discover, favorites sync, etc.) rather
than hardcoding per-service behavior.
- **YouTube Music**: Full streaming backend with a Spotify-style **Discover**
page (recommended songs, playlists, albums, artists, and moods), rich **artist
profiles** (banner, top songs, albums, singles, related artists),
album/playlist browsing, and **mix radio** ("start radio" from any track).
Sign in with your account for your library, Liked Music, and playlists - or
run it **anonymously** (no sign-in) for browse, search, and playback of public
tracks. See [YouTube Music Setup](#youtube-music-setup).
- **SoundCloud**: Streaming backend with search, track playback (progressive MP3
and Go+ AAC/HLS), your **Liked tracks** as favorites, read-only playlists, and
like/unlike. Added via a one-time browser sign-in in an isolated profile. See
[SoundCloud Setup](#soundcloud-setup).
- **Lyrics Support**: Enjoy real-time synced and plain lyrics, complete with
auto-scrolling to follow along with your music.
- **Favorites**: Star tracks locally or sync favorites with your
Jellyfin/Subsonic server.
- **Playlists**: Create and manage your own playlists, add individual tracks or
whole albums at once, and sync playlists to your server.
- **Genre Browsing**: Browse your library by genre for both local and server
music.
- **File-Type Badges**: Local tracks show a small format badge (MP3, FLAC, WAV,
etc.) in track rows so you can see the source format at a glance.
- **Search**: Search across artists, albums, and tracks with real-time results.
- **Listening Logs**: Tracks play counts locally so you can see what you
actually listen to most.
- **Scrobbling**: Scrobble to ListenBrainz. For Jellyfin users,
[jellyfin-plugin-listenbrainz] is recommended if you use multiple clients.
- **Language Support**: UI available in Arabic, Brazilian Portuguese, Dutch,
English, European Portuguese, Filipino, French, German, Greek, Hebrew,
Hungarian, Indonesian, Italian, Japanese, Korean, Malayalam, Polish, Romanian,
Russian, Simplified Chinese, Spanish, Swedish, Tamil, Toki Pona, Turkish,
Ukrainian, Vietnamese, and Sitelen Pona with a streamlined experience for
adding new languages.
- **High Performance**: Heavy background processing and an optimized library
scanner ensure the app opens instantly, runs smoothly, and skips previously
indexed files quickly.
- **Auto-Cleanup**: Automatically removes missing or deleted tracks from your
library when rescanning.
- **Smooth Navigation**: Enjoy a polished interface where scroll positions reset
properly as you browse different views and pages.
- **Reduce Animations**: Accessibility setting to tone down motion effects if
you prefer a calmer UI.
- **Equalizer**: Built-in 5-band equalizer with presets and custom settings to
fine-tune your sound.
- **Crossfade**: Blend track transitions for smoother automatic playback between
songs on native desktop builds. Browser playback currently uses normal track
switching.
- **Channel Mode**: Switch between `Stereo`, `Mono`, `Left only`, `Right only`,
and `Swap L/R` output modes.
- **yt-dlp Integration**: Download audio directly from YouTube and other
supported sites via yt-dlp. Choose your output format (Best Audio, MP3, FLAC,
WAV, or MP4 video). FLAC is not recommended since yt-dlp remuxes lossy audio
rather than decoding from a lossless source. Supports SponsorBlock, chapter
splitting, cookies, rate limiting, and more. Requires `yt-dlp` installed on
your system.
- **Metadata Settings**: A dedicated Metadata section in Settings lets you
control how artist images are sourced. Choose between **Album Cover** (uses
the first album artwork as the artist photo, default) or **Artist Photo**
(fetches actual artist images directly from your Jellyfin or Subsonic server).
When switching to Artist Photo mode, images are fetched from the server in the
background as soon as you open the Artists page. If an artist has no dedicated
photo on your server, their first album cover is used as a fallback so nothing
ever shows blank.
## Installation
### Cargo (crates.io)
Install directly with Cargo:
```bash
cargo install --locked kopuz
```
### NixOS / Nix
**Run directly without installing:**
```bash
nix run github:temidaradev/kopuz
```
**Install to your profile:**
```bash
nix profile add github:temidaradev/kopuz
```
**On NixOS, using the flake:**
> [!TIP]
> This is recommended over `nix profile` as it installs Kopuz as a proper system
> app with icon & `.desktop` entry.
Add Kopuz to your `flake.nix` inputs:
```nix
{
inputs.kopuz.url = "github:temidaradev/kopuz";
}
```
Then pass it through to your system config and add the Cachix substituter so it
downloads the pre-built binary instead of compiling:
```nix
{
nix.settings = {
substituters = ["https://kopuz.cachix.org" ];
trusted-public-keys = ["kopuz.cachix.org-1:J2X3AnAYhKTJW5S3aCLoA1ckonQXVNZMQvhZA0YAufw="];
};
}
```
Then install the package:
```nix
{pkgs, kopuz, ...}: let
kopuzPkg = kopuz.packages.${pkgs.stdenv.hostPlatform.system}.default
in {
environment.systemPackages = [kopuzPkg];
}
```
### AUR (Arch Linux)
Install from the AUR using your preferred helper:
```bash
yay -S kopuz-bin
# or
paru -S kopuz-bin
```
### Flatpak (Recommended)
Kopuz is soon available on Flathub. To install from source manifest:
```bash
git clone https://github.com/temidaradev/kopuz
cd kopuz
flatpak-builder --user --install --force-clean build-dir packaging/flatpak/com.temidaradev.kopuz.json
flatpak run com.temidaradev.kopuz
```
You can also click on the file and open it with an app provider, for example KDE
discover
### AppImage
> [!IMPORTANT]
> The AppImage requires `webkit2gtk-4.1` and `gtk3` installed on your system.
> Those dependencies are **not** bundled. The system tray icon additionally
> needs the **appindicator** library (e.g. `libayatana-appindicator`); without
> it Kopuz runs fine but shows no tray icon.
>
> On most distros with a modern desktop environment, these are already present.
> You will need to install them manually if they are not yet installed.
On Arch-based distros, if the AppImage crashes with a `WebKitNetworkProcess`
error, either run it with:
```bash
LD_LIBRARY_PATH=/usr/lib ./kopuz_*.AppImage
```
Or create symlinks once (requires sudo):
```bash
sudo mkdir -p /usr/libexec/webkit2gtk-4.1
sudo ln -s /usr/lib/webkit2gtk-4.1/WebKitNetworkProcess /usr/libexec/webkit2gtk-4.1/
sudo ln -s /usr/lib/webkit2gtk-4.1/WebKitWebProcess /usr/libexec/webkit2gtk-4.1/
sudo ln -s /usr/lib/webkit2gtk-4.1/WebKitGPUProcess /usr/libexec/webkit2gtk-4.1/
```
### Build from Source
#### Dependencies
**Using Nix**
> [!TIP]
> [Nix](https://nixos.org) is the primary means of development for Kopuz, and it
> is the recommended method for getting build dependencies in a pure,
> reproducible environment consistent across systems.
```bash
# Using Nix3 CLI
nix develop
```
If you are a [Direnv](https://direnv.net) user, use the provided `.envrc`:
```bash
# Using Direnv
direnv allow
```
Direnv is recommended if you want to keep using your usershell within the
development environment.
> [!NOTE]
> The system tray icon (used by **minimize to tray**) requires the
> **appindicator** library at runtime. It is included in the package
> dependencies below. Without it the tray icon simply won't appear and closing
> the window quits the app instead of hiding it - Kopuz still runs normally. The
> Nix dev shell already provides it.
**Arch Linux Based Systems**
```bash
sudo pacman -S rust cargo dioxus-cli base-devel cmake pkgconf opus alsa-lib xdotool webkit2gtk-4.1 gtk3 libsoup3 openssl libayatana-appindicator
```
**Debian Based Systems**
```bash
sudo apt install rustc cargo build-essential cmake pkg-config libopus-dev libasound2-dev libxdo-dev libwebkit2gtk-4.1-dev libgtk-3-dev libsoup-3.0-dev libssl-dev libayatana-appindicator3-1
cargo install dioxus-cli
```
**Fedora Based Systems**
```bash
sudo dnf groupinstall "Development Tools" "Development Libraries"
sudo dnf install rust cargo cmake pkgconf-pkg-config opus-devel alsa-lib-devel libxdo-devel webkit2gtk4.1-devel gtk3-devel libsoup3-devel openssl-devel libayatana-appindicator-gtk3
cargo install --locked dioxus-cli
```
**openSUSE Based Systems**
```bash
sudo zypper install rust cargo cmake pkg-config libopus-devel alsa-devel xdotool webkit2gtk3-soup2-devel gtk3-devel libsoup3-devel libopenssl-devel libayatana-appindicator3-1
cargo install --locked dioxus-cli
```
#### Developing Kopuz
```bash
# Clone the repository
$ git clone https://github.com/Kopuz-org/kopuz
# Move to the cloned directory
cd kopuz
# Install npm dependencies
npm install
# Serve project with Dioxus CLI
dx serve --package kopuz
```
### macOS
**Quarantine note:** If you downloaded a `.dmg` instead, macOS may block it. Run
once to clear the quarantine flag:
```bash
xattr -d com.apple.quarantine /Applications/Kopuz.app
```
### Where does Kopuz keep its files?
Your settings, scanned library, playlists, and favorites all live in a single
**SQLite** database, `kopuz.db`, in the config directory. Album art and
downloaded tracks stay on disk in the cache directory. (Debug builds use a
separate `kopuz-debug.db` so `dx serve` never touches your real data. You can
override the DB location with the `KOPUZ_DB_PATH` env var.)
On **macOS**:
- `~/Library/Application Support/com.temidaradev.kopuz/kopuz.db` - settings,
library, playlists, favorites
- `~/Library/Caches/com.temidaradev.kopuz/covers/` - cached album art
- `~/Library/Caches/com.temidaradev.kopuz/offline_tracks/` - downloaded tracks
On **Linux** (XDG spec):
- `~/.config/kopuz/kopuz.db` - settings, library, playlists, favorites
- `~/.cache/kopuz/covers/` - cached album art
- `~/.cache/kopuz/offline_tracks/` - downloaded tracks
On **Windows** (AppData):
- `%APPDATA%\temidaradev\kopuz\config\kopuz.db` - settings, library, playlists,
favorites
- `%LOCALAPPDATA%\temidaradev\kopuz\cache\covers\` - cached album art
- `%LOCALAPPDATA%\temidaradev\kopuz\cache\offline_tracks\` - downloaded tracks
> [!NOTE]
> Upgrading from an older version? On first launch Kopuz imports your existing
> `library.json` and `playlists.json` into `kopuz.db`, leaving `*.json.bak`
> backups behind. The old JSON files are no longer read after that.
If covers aren't showing or the library looks off, just delete the cache folder
and hit rescan.
## YouTube Music Setup
Kopuz can use YouTube Music as a streaming backend. Add it from **Settings →
Media servers → Add → YouTube Music**.
### Choosing a mode
The setup dialog offers two methods:
- **Sign in with a browser** - kopuz opens the Google sign-in page in an
**isolated browser profile** (a fresh, separate session; your normal browsing
is never touched), waits for you to log in, and extracts the session cookies.
Pick which installed Chromium-family browser to use (Chrome, Chromium, Brave,
Edge, or Vivaldi). This unlocks your **library, Liked Music, playlists, and
followed artists**.
- **Continue without signing in (anonymous)** - no sign-in, no cookies. You can
**browse, search, open artist/album/playlist pages, start mix radio, and play
public tracks**. Liked Music, library playlists, and following/liking are
disabled (those views show a "sign in to enable" prompt). Music Premium-only
tracks can't be played anonymously.
### Premium tracks
Music Premium-locked tracks fall back to a local
[`yt-dlp`](https://github.com/yt-dlp/yt-dlp) resolve when the primary path
returns `UNPLAYABLE`, so having `yt-dlp` installed helps for those. Anonymous
mode can't play Premium-only content at all.
## SoundCloud Setup
Kopuz can use SoundCloud as a streaming backend. Add it from **Settings → Media
servers → Add → SoundCloud**.
There's no URL or password to type. Kopuz opens `soundcloud.com/signin` in an
**isolated browser profile** (a fresh, separate session; your normal browsing is
never touched), waits for you to log in, and pulls the session's `oauth_token`.
Pick which installed Chromium-family browser to use (Chrome, Chromium, Brave,
Edge, or Vivaldi).
Once signed in you get search, track playback (progressive MP3 plus Go+ AAC/HLS
streams), your **Liked tracks** as favorites, read-only access to your
playlists, and like/unlike. Removing the source cleans up its isolated profile.
## Logs & Debugging
Kopuz logs through [`tracing`](https://docs.rs/tracing). Most of this is
reachable from the app itself - **Settings → Logs** has **Open logs folder**,
**Export logs**, and an **Enable Performance Tracing** toggle - so users never
need a terminal to send a useful report.
### Where the files live
All files sit in the logs directory (the **Open logs folder** button jumps
straight here):
- Linux: `~/.cache/kopuz/logs/`
- macOS: `~/Library/Caches/com.temidaradev.kopuz/logs/`
- Windows: `%LOCALAPPDATA%\temidaradev\kopuz\cache\logs\`
| File | What it is |
| ----------------------- | ------------------------------------------------------------------------------------------------ |
| `latest.log` | The current session. Span timing + events; the live log. |
| `kopuz-