plavno 0.2.0

A lightweight Linux terminal music player with service waves and library shuffle
<div align="center">

# plavno

A lightweight TUI player for Linux with music streams from popular services, library shuffle, and mouse controls.

<img src="intro.png" alt="plavno terminal player with album artwork and an audio-reactive wave" width="791">

[![License: Apache 2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)

[Features](#features) · [Quick start](#quick-start) · [Services](#services) · [Controls](#controls)

</div>

## Features

- **MPRIS desktop integration** — control playback with media keys, desktop media
  widgets, or `playerctl`. Track information and album artwork appear in desktop controls.
- **Service waves and shuffle** — Yandex My Vibe, VK recommendations, library shuffle,
  and Wave Shuffle across connected services.
- **Likes and dislikes** — like/unlike in Yandex or VK, exclude unwanted tracks, and undo dislikes.
- **Mouse and hotkeys** — click controls, drag to seek, scroll for volume, and select track text to copy.
- **Listening history** — search past plays by title or artist and replay tracks.
- **RAM buffering and prefetch** — start playback while downloading; cache adjacent tracks for seeking and replay.
- **Audio-reactive visuals** — an animated wave with album artwork, toggled with `v`.

## Quick start

Install from crates.io (requires Rust, pkg-config, ALSA and D-Bus headers):

```sh
cargo install plavno --locked
plavno sources
```

Build dependencies: `libasound2-dev libdbus-1-dev` on Debian/Ubuntu, or
`alsa-lib-devel dbus-devel` on Fedora.

Alternatively, download a binary from [GitHub Releases](https://github.com/gmelikov/plavno/releases).
Linux x86_64 and ARM64 (`aarch64`) builds require glibc 2.35+, `libasound.so.2`, and `libdbus-1.so.3`
(`libasound2` / `libasound2t64` and `libdbus-1-3` on Debian/Ubuntu). Extract the archive
and run `./plavno`, or place it in `~/.local/bin`.

Audio uses the ALSA default device; PipeWire/PulseAudio needs its ALSA plugin.
Install ffmpeg for HLS playback. Optional Spotify and YouTube helpers are built separately.

To build from source:

```sh
cargo build --release
export PATH="$PWD/target/release:$PATH"
plavno sources
```

Connect a service below, then start it with `plavno --source SOURCE`.
For development, use `cargo run` or `cargo check` and keep the build cache.

## Services

| Service | Source key | Stable | Playback | Connection |
|---|---|:---:|---|---|
| Yandex Music | `yandex` | 🟢 | My Vibe, favorites shuffle, flow presets | OAuth token; full tracks require account access / Yandex Plus |
| VK Music | `vk` | 🟢 | Recommendations, My Music shuffle, flow presets | Installed Chrome/Chromium or manual session import |
| SoundCloud | `soundcloud` | — | Track stations | Browser sign-in or a public seed track |
| Spotify | `spotify` | — | Track radio | Optional Rust helper; Premium and OAuth |
| YouTube Music | `ytmusic` | — | Home mixes and track radio | Optional Rust helper; cookies or a public seed |

### Yandex Music

Get an OAuth token from the [token guide](https://ym.marshal.dev/token), paste it
into `plavno login yandex`, then run `plavno --source yandex`.

### VK Music

Run `plavno login vk` and sign in through installed Chrome/Chromium, then run
`plavno --source vk`. Alternatively, [import a session manually](docs/services.md#manual-vk-session)
with `plavno login vk --manual`.

### SoundCloud

Run `plavno login soundcloud`, sign in through Chrome/Chromium, and choose a
seed track when prompted. Start with `plavno --source soundcloud`.
[Manual setup](docs/services.md#manual-soundcloud-session) also supports public track stations.

### Spotify

[Build the Spotify helper](docs/services.md#spotify-and-youtube-music), then run
`plavno login spotify` and paste a JSON profile with a seed track URI, OAuth token
with `streaming` scope, and client ID. Premium is required. Start with `plavno --source spotify`.

### YouTube Music

[Build the YouTube helper](docs/services.md#spotify-and-youtube-music), then run
`plavno login ytmusic` and paste `{"cookies":"/absolute/path/youtube-cookies.txt"}`
using a Netscape cookie export, or `{"seed":"VIDEO_ID_OR_URL"}` for public radio.
Start with `plavno --source ytmusic`.

See [service setup](docs/services.md) for profile examples and troubleshooting.

## Run

```sh
plavno sources                         # List supported services and connection status
plavno --source yandex                  # Yandex Music My Vibe
plavno --source yandex --favorites      # Shuffle Yandex favorites
plavno --source vk                      # VK recommendations
plavno --source vk --favorites          # Shuffle VK My Music
plavno --source mixed                   # Mix waves from connected services
plavno --file /path/to/track.flac        # Play a local file
plavno --no-wave                        # Start without visualization
```

## Controls

Buttons display their hotkeys and support mouse clicks.

| Key | Action |
|---|---|
| Space / x | Pause or resume / stop |
| p / n | Previous / next track |
| ← / → | Seek 5 seconds; Shift or Ctrl: 30 seconds |
| Home / End | Start / end of track |
| + / - | Volume; also click beside the percentage |
| [ / ] | Playback speed: 0.1–2x, step 0.05; click buttons or scroll over Speed |
| l | Like / unlike in Yandex favorites or VK My Music |
| d / u | Dislike and skip / undo dislike |
| h or / | History: type to search, ↑/↓ select, Enter play |
| s / m | Choose a service / mix service waves |
| w / f | New wave / library shuffle (VK: My Music) |
| g | Flow: Calm, Balanced, Energetic, Work; choose with 1–4 or a click |
| v | Toggle visualization |
| Ctrl+C | Copy selected text; quit when nothing is selected |
| Esc / q | Clear selection or close a view / quit |

Hover over the album artwork: the left third plays the previous track, the center
toggles playback, and the right third plays the next track. Click the progress bar
to jump, or drag it for audible 2–4x scrubbing. Scroll over the bar to seek, over
Speed to change the rate, and elsewhere to change volume. Drag over the title or
artist and press Ctrl+C to copy (requires terminal OSC 52 support). In History and
Sources, click to select, double-click to play, scroll to navigate, and right-click
to close.

Flow changes recommendations. Work requests calm ambient without vocals on Yandex
and calm instrumental tracks on VK. `w` returns from library shuffle to a new wave;
VK filters recent tracks to avoid repeating the initial queue.

## Playback and data

Playback starts while downloading, at the highest available supported quality.
Previous, current, and next audio files stay in RAM for seeking and replay;
RAM use depends on track size. Service audio is not saved to disk.

Configuration lives in `~/.config/plavno`; history and permanent dislikes live in
`~/.local/state/plavno`. `XDG_CONFIG_HOME` and `XDG_STATE_HOME` override these roots.
History stores metadata for the last 2000 plays. Yandex and VK also receive account
dislikes; `u` undoes them. Volume starts at 100%, speed at 1x. Changing speed also
changes pitch.

Media keys and `playerctl` work through session D-Bus, for example:
`playerctl -p plavno play-pause` or `playerctl -p plavno position 5+`.

## Checks

```sh
cargo fmt --check
cargo test
cargo clippy --all-targets -- -D warnings
```

Release steps: [Publishing to crates.io](docs/publishing.md).

## License

[Apache License 2.0](LICENSE).