Para escuchar música mientras trabajo usaba el navegador, con una pestaña para cada cosa: una para el lofi, otra para un artista en particular y otra para la radio. Cada cambio me sacaba de la terminal, que es donde paso el día.

Pero lo que más me molestaba era otra cosa: nada de eso se sentía mío. No tenía mis colores ni estaba armado a mi gusto. Yo quería abrirlo y sentirme cómodo con lo que veía.

Lo más cercano que conocía era gentle-stream, de Gentleman Programming. Me gustaba su interfaz, pero es un generador de música y yo buscaba un reproductor. La otra pieza era cliamp: también me gustaba su interfaz, y su radio ya la escuchaba desde antes.

Así nació velo: un reproductor para la terminal que le debe mucho a esos dos proyectos.

Qué hace

velo es un reproductor de música para la terminal. Le indicas tu carpeta, indexa la biblioteca a partir de las etiquetas de tus archivos y te deja recorrerla por artista, álbum, pista o género.

  • Biblioteca local. El índice vive en SQLite, se actualiza en segundo plano en cada inicio y tiene búsqueda difusa en toda la biblioteca.
  • Reproducción sin cortes. MP3, FLAC, M4A/AAC, OGG Vorbis, Opus y WAV, sin silencio entre una pista y la siguiente.
  • Una cola editable. Agregas, reordenas, quitas y mezclas sin detener la música.
  • Radio por internet. El directorio Radio Browser, los canales de cliamp o cualquier URL de streaming.
  • Servidores Subsonic. Navidrome, Airsonic o Gonic se sincronizan en el mismo índice. Todavía en acceso anticipado.
  • Lo que esperas de un reproductor serio. ReplayGain con protección contra saturación, modo bit-perfect, selección del dispositivo de salida y las teclas multimedia del sistema.
  • Carátulas, nueve visualizadores y trece temas. O los colores de tu propia terminal.

Las teclas son las de Vim: j y k para moverte, / para buscar, enter para reproducir. Con ? ves todas.

La vista de pistas de la biblioteca mientras suena una canción: el bloque de reproducción con su reloj y su espectro, y debajo la lista de pistas

Si activas el fondo transparente, velo deja ver el de tu terminal. Así se ve en mi escritorio, con un canal de lofi sonando:

Los favoritos, las listas y el historial se guardan en archivos TOML que puedes abrir y editar. Y no hay telemetría: velo solo contacta lo que tú le indicas, más una consulta diaria a GitHub para saber si hay una versión nueva, que se apaga con una línea de configuración.

Lo que ya existía

Reproductores para la terminal hay muchos y varios son muy buenos. La verdad es que no probé a fondo la mayoría. Los miré como referencia mientras diseñaba velo, para ver qué resolvía cada uno y cómo.

De ahí salió una decisión. Algunos de los más conocidos, como ncmpcpp y rmpc, son clientes de MPD: antes de escuchar una canción tienes que instalar, configurar y mantener corriendo un servidor aparte.

Yo quería lo contrario: un solo binario. Lo instalas, le dices dónde está tu música y suena. Sin daemon, sin servidor y sin cuenta.

Cómo funciona por dentro

El callback de audio solo copia memoria. El sistema operativo le pide muestras a velo cada pocos milisegundos, y si no llegan a tiempo se escucha un clic. Por eso lo caro (decodificar, cambiar la frecuencia de muestreo, aplicar ReplayGain) ocurre en otro hilo, un búfer por delante. Los dos hilos se comunican por una cola circular sin bloqueos. El callback mide cuántas muestras hay listas, las copia y rellena el resto con silencio. No reserva memoria, no toma locks y no escribe logs.

Sin cortes significa sin cortes. La pista siguiente se decodifica antes de que termine la actual y se une a ella sin insertar silencio. Los codificadores con pérdida agregan relleno al inicio y al final de cada archivo, y velo lo recorta en la unión. En un disco en vivo o en uno conceptual, la diferencia se escucha.

Un solo binario, en serio. Cada dependencia pasó por esa regla. SQLite va compilado dentro. Opus no tiene decodificador en Symphonia, la biblioteca que decodifica el resto de los formatos, así que libopus se compila de forma estática. Para las teclas multimedia en Linux elegí una implementación de D-Bus en Rust puro, porque la opción por defecto exigía tener una biblioteca del sistema instalada.

Los servidores remotos pasan por una caché. Una pista de Subsonic se descarga una vez, sin transcodificar, y se reproduce desde el disco. Así el salto, la reproducción sin cortes y ReplayGain funcionan igual que con un archivo local.

Un canal de radio mientras suena: la fila en vivo con su cantidad de oyentes y debajo las canciones del canal

Cómo lo construí

El repositorio no lo esconde, así que lo cuento yo: velo pasó del primer commit a la versión 1.0.0 en seis días, con 479 commits y 75 versiones publicadas. No escribí esas 70 mil líneas de Rust a mano. Las escribieron agentes de IA, con el mismo sistema que describí en mi stack de desarrollo con IA.

Lo que sí hice fue dirigir. Cada funcionalidad empezó como un documento con requisitos numerados que citan mis propias palabras, y cada tarea se cerró contra esos requisitos. Hay 21 de esos documentos en la carpeta odd/tasks del repositorio, a la vista de cualquiera.

El código tampoco se acepta por fe. Hay más de 1200 pruebas, y un solo script corre el formato, el linter con las advertencias tratadas como errores y todas las pruebas. Es el mismo que corre la integración continua.

No todo salió según el plan. velo fue mi primera vez con muchas de estas tecnologías y con casi todos los conceptos de audio. Gapless, ReplayGain y bit-perfect eran los términos más técnicos para mí, y no entendía del todo lo que implicaban. Así que cuando el agente propuso un alcance lo acepté, y encima pedí sumar los servidores Subsonic, que casi no uso. Está en el primer documento del proyecto, con mis propias palabras. Después hubo momentos en los que no sabía lo suficiente para cuestionarlo, y simplemente lo dejé seguir.

velo terminó siendo más grande de lo que yo necesitaba. No estuvo mal: esas funciones dejaron la aplicación más completa. Pero me quedó claro que cuando no entiendes el tema dejas de dirigir y empiezas a aprobar.

Pruébalo

velo corre en macOS y Linux. Con Homebrew:

brew install alvaldes/tap/velo

O con el script de instalación, que verifica la suma de comprobación y no pide sudo:

curl -fsSL https://alvaldes.github.io/velo/install.sh | sh

Después ejecutas velo, presionas o y escribes la ruta de tu carpeta de música. En el sitio hay un reproductor al que le puedes dar play antes de instalar nada.

Para ver las carátulas necesitas una terminal que hable el protocolo de kitty, sixel o iTerm2. Windows no está probado.

Es de código abierto, bajo licencia MIT. Si algo no funciona o se te ocurre una mejora, abre un issue en el repositorio.