velo

Your music, in the terminal.

velo reads your files' own tags, plays them gaplessly and draws the cover art. It is one Rust binary: no daemon, no server, no account, no telemetry.

Install
brew install alvaldes/tap/velo curl -fsSL https://alvaldes.github.io/velo/install.sh | sh git clone https://github.com/alvaldes/velo && cd velo && cargo install --path .

macOS and Linux. The tap follows each release within the hour, and brew upgrade velo moves you to the next one. The script picks the binary for this machine, checks it against the .sha256 CI published beside it, and puts velo in ~/.local/bin. No sudo. A clone and cargo: needs Rust 1.88 or newer, cmake or a system libopus, and the ALSA development headers on Linux.

All install options in the README

♫ HoliznaCC0 – Wave Maker ( Lofi , Dreamy , Retro )
0:00 / 3:05■ stopped track 80 of 120
Radio › Lofi [120 songs]

Your folder is the library

Four views
Artists, albums, tracks and genres, indexed from the tags and refreshed in the background at every launch.
Fuzzy search
/ searches the whole library: lofi finds Lo-Fi Scientists.
A queue you edit
a appends without stopping playback, tab goes to the queue and back, z shuffles what is left.
Favourites and playlists
f marks a favourite and S saves the queue as a playlist. e renames it, J and K reorder its tracks.
Or your own server
Early access: Navidrome, Airsonic, Gonic and any other server that speaks the Subsonic API. velo --sync brings its library into the same index, and a remote track plays through a local cache.
Recently played
A source of its own on the first screen: what you played, newest first, stations included.
/ and four letters

It plays the file, not an approximation of it

Gapless
A join trims what the encoder inserted, so the seam carries music only: the LAME delay and padding for MP3, the edit list for M4A.
ReplayGain
Read from the files' own tags and applied with clipping protection: a track that declares its own peak is never pushed past full scale. The transport says which mode is on, RG track or RG album, and velo --replaygain-scan measures an album and writes the tags it is missing.
Bit-perfect
bit_perfect = true reopens the device at each track's own rate. ReplayGain and the volume step aside, and one status line says so.
Pick the output
d lists the machine's audio devices with the one in use marked. enter moves playback there and keeps the position in the track, and velo remembers the choice.
Formats
MP3, FLAC, M4A/AAC, OGG Vorbis, OGG Opus and WAV, with no dynamic dependency.
A track playing, with the list it came from underneath

Radio that reads like radio

58,000 stations in the Radio Browser directory

241 countries, with yours listed first

  • The stations come from Radio Browser, a directory its community keeps, asked through its public mirrors.
  • Browse by country, region or tag. f favourites a station or pins a place.
  • A live row carries ● live and the listener count when the service reports one.
  • u plays any stream URL without saving it.
  • Changing station crossfades: what you were hearing keeps playing until the new stream sounds, then one fades into the other.
  • A station that cannot play is marked ✗ and says why at once, and i drafts the bug report for you to send.
Every country with its station count, while the music keeps playing

cliamp radio is the first row

Channels that the cliamp project runs itself, always on and with no account. In velo they lead the radio view: a channel opens on its live row, with the listeners it has right now, and then its songs, each one a track you can play, seek and queue.

Lofi, Meditative, Synthwave, EDM, Omarchy, Chiptunes, Amiga and eight NoCopyrightSounds channels.

I listen to these channels a lot. Thank you to the people behind cliamp for building the service and keeping it free and always on.

The service is theirs, not velo's, at radio.cliamp.stream. If you would rather not see it, cliamp = false under [radio] hides the section.

It looks like your terminal

Your colours
ctrl+p opens the settings card. The theme has its own picker that previews as the cursor moves, and transparent background is one switch: whatever is behind the window shows through, which is what this page is doing.
Thirteen themes
velo's own, catppuccin latte and mocha, dracula, gruvbox, monokai, nord, one dark and light, solarized dark and light and tokyo night are built into the binary, plus default terminal, which draws with whatever palette your terminal already has. Every one of them ships as its own TOML file in ~/.config/velo/themes/, commented and ready to copy and edit; a theme of your own is one more file there.
Nine visualizers
bars, bars-outline, wave, scatter, flame, matrix, scope, mirror and none. v cycles them, ctrl+v picks one with a live preview, and V gives it the whole screen.
Cover art
Drawn where the terminal speaks the kitty, sixel or iTerm2 protocol. Elsewhere the status line says why it is hidden.
ctrl+v: nine shapes, and the one under the cursor is already on screen
Try a theme on the picture above, the way the picker previews it

Driven from the keyboard

Sixteen of the keys. The footer names the ones the screen you are on needs, ? opens the full, filterable list inside velo, and the system's media keys reach play, next and previous on macOS and on a Linux desktop with MPRIS.

j k
move down and up
enter
open, or play from here
esc
back one level
space
pause and resume
← →
seek 5 s, 30 s with shift
:
jump to 70%, 1:20 or 90 s
/
fuzzy search
1–4
artists, albums, tracks, genres
tab
to the queue and back
a
append to the queue
x
remove from the queue
z
shuffle what is left
r
repeat: off, all, one
+ -
volume, 5% at a time
f
favourite
R
radio

It answers without the interface too

Some questions need no screen. These run without a terminal, so they work over ssh and inside a script, and each one says how it went in its exit code.

$ velo history --json            # what played, newest first
$ velo playlist import mix.m3u   # .m3u, .m3u8 and .pls
$ velo --replaygain-scan *.flac  # measure loudness: a dry run
$ velo --radio-test <URL>        # can this stream play?
$ velo --index                   # refresh the library, print counts

Where it runs

Linux and macOS, on x86_64 and aarch64, as one binary with no dynamic dependency. Windows is untested. Cover art needs a terminal that speaks the kitty, sixel or iTerm2 protocol.

What velo sends

No usage data: no analytics endpoint, no install id, no first-run question. One request is its own, the update check to api.github.com, once a day with no identifier, and check = "never" turns it off.

Not yet

YouTube links, played through yt-dlp, are planned in issue #70. Subsonic cannot stream a track before the whole file is cached. Playlists are saved, renamed and reordered, and have no editor beyond that.

Install it, open it, point it at your music

$ brew install alvaldes/tap/velo
$ velo

Inside velo, o asks where your music is and tab completes the folder as you type. velo indexes it, remembers it, and refreshes the index in the background at every launch. Linux or macOS.

o, two letters and tab

Made by Angel L. Valdés

A software engineer in Mexico. velo is free software under the MIT license, written in the open: the issues, the changelog and every release are on GitHub, and reports and pull requests are welcome.