01. La Filosofía Local-First: Tu música te pertenece
En el panorama actual del consumo multimedia, los usuarios hemos sido empujados a una relación de arrendamiento forzado: suscripciones mensuales, catálogos que desaparecen por disputas de licencias discográficas, telemetría invasiva rastreando cada segundo de escucha, y aplicaciones de escritorio que son en realidad navegadores Chromium empaquetados devorando 800 MB de RAM en reposo.
Davusic nació como respuesta directa a esta degradación técnica. Diseñado como el sucesor natural y refinado de mis proyectos multimedia anteriores (como el motor de audio Hi-Fi desarrollado para Dabot en Discord), Davusic adopta una filosofía local-first incondicional:
- Soberanía total de datos: Tu biblioteca musical, playlists, canciones favoritas (Me gusta), historial de reproducción y ponderaciones de preferencias se almacenan exclusivamente en local (en formatos abiertos JSON y SQLite). Cero servidores propietarios, cero registro de cuentas obligatorias y cero analíticas en la nube.
- Referencias ligeras, no descargas compulsivas: Las playlists importadas guardan la metadata esencial (título, artista, álbum, identificadores de búsqueda). El audio se resuelve en tiempo real mediante streaming sobre demanda y se conserva en una caché temporal acotada, eliminando la necesidad de saturar tu almacenamiento con cientos de gigabytes innecesarios.
- Eficiencia nativa: Construido en Rust para ofrecer tiempos de inicio instantáneos (<100 ms), un consumo de memoria inferior a 60 MB en reproducción y latencia de audio imperceptible.
02. Arquitectura de Sistemas: Tauri 2 + Rust vs Chromium/Electron
La decisión más crítica de diseño radicó en desechar Electron. Incrustar una instancia completa de V8, Blink y renderizado web para simplemente decodificar audio y pintar una lista es un desperdicio intolerable de recursos del sistema.
Optamos por Tauri v2 con backend en Rust 1.85+ y un frontend estático zero-bundler. No existe package.json, ni webpack, ni Vite, ni Node.js ejecutándose en tiempo de ejecución: los ficheros web (HTML semántico, CSS reactivo puro y JavaScript nativo) se compilan y se incrustan como assets binarios directamente dentro del ejecutable final.
| Métrica de Rendimiento | Reproductor Típico Electron | Davusic (Tauri 2 + Rust) |
|---|---|---|
| Uso de RAM en reposo | ~350 MB – 850 MB | 35 MB – 58 MB |
| Tiempo de arranque en frío | 1.8 s – 4.2 s | < 95 ms |
| Tamaño del ejecutable | 180 MB – 240 MB | ~14 MB (binario stripped) |
| Renderizado Web | Chromium bundled monobloque | WebKitGTK (Linux) / WebView2 (Windows) |
| Pipeline de audio | HTML5 Audio WebAudio (vía Chromium) | ALSA / PipeWire nativo (rodio) |
03. Motor de Audio Nativo: Rodio, Symphonia y Lofty
Uno de los problemas endémicos de los reproductores basados en Chromium es delegar la reproducción en el elemento <audio> del navegador, lo que añade capas de resampleo indeseadas, problemas de buffering inconsistente y cuelgues si el hilo principal de JavaScript sufre bloqueos por animaciones complejas.
En Davusic, el audio vive íntegramente en un hilo dedicado en Rust bautizado como davusic-audio. Empleamos el crate rodio 0.23 acoplado al conjunto completo de decodificadores de Symphonia.
// Desacoplamiento del hilo de audio con rodio y Symphonia
use rodio::{Decoder, OutputStream, Sink};
use std::fs::File;
use std::io::BufReader;
use std::sync::atomic::{AtomicU64, Ordering};
/// Generador atómico para anular reproducciones concurrentes atrasadas
static PLAY_GENERATION: AtomicU64 = AtomicU64::new(0);
pub struct AudioEngine {
_stream: OutputStream,
stream_handle: rodio::OutputStreamHandle,
sink: Sink,
}
impl AudioEngine {
pub fn new() -> Result<Self, String> {
let (_stream, stream_handle) = OutputStream::try_default()
.map_err(|e| format!("Fallo al inicializar endpoint de audio ALSA/PipeWire: {}", e))?;
let sink = Sink::try_new(&stream_handle)
.map_err(|e| format!("Fallo creando rodio Sink: {}", e))?;
Ok(Self { _stream, stream_handle, sink })
}
pub fn play_file(&mut self, path: &std::path::Path) -> Result<(), String> {
let file = File::open(path).map_err(|e| e.to_string())?;
let source = Decoder::new(BufReader::new(file))
.map_err(|e| format!("Codec no soportado por Symphonia: {}", e))?;
self.sink.stop();
self.sink.append(source);
self.sink.play();
Ok(())
}
}
Prevención de Race Conditions con Generaciones Atómicas
Cuando un usuario hace clic rápidamente en 5 canciones consecutivas en la interfaz, un reproductor ingenuo lanzaría 5 tareas asíncronas concurrentes. Si la tercera descarga o lectura tarda más que la quinta, la tercera podría sobrescribir la reproducción final, provocando que empiece a sonar la canción incorrecta.
Para resolver esto de forma matemáticamente elegante, implementamos play_generation: AtomicU64. Cada solicitud de reproducción incrementa este contador. Cuando el backend termina de preparar el buffer de audio o el stream, verifica si el valor de generación coincide con el actual. Si no coincide, aborta inmediatamente la carga descartando el audio obsoleto sin bloquear el procesador.
Indexación Ultra-Rápida de Metadatos con Lofty
Para el escaneo de bibliotecas locales, utilizamos el crate lofty 0.25. A diferencia de lectores de tags basados en llamadas a ffmpeg o librerías pesadas en C, Lofty lee directamente los encabezados de archivo en memoria:
- Formatos soportados: FLAC, MP3 (ID3v1, ID3v2.3, ID3v2.4), OGG Vorbis, Opus, M4A/AAC, WAV, AIFF y WavPack.
- Extracción de carátulas embebidas: Extracción zero-copy de carátulas JPEG/PNG hacia el protocolo custom
cover://, evitando escribir archivos temporales duplicados en disco. - Rendimiento: Escaneo de más de 12.000 pistas locales en apenas 3.8 segundos en un SSD NVMe sobre Linux.
04. Streaming Efímero y Caché Inteligente con yt-dlp
Davusic no necesita que tengas cada canción descargada previamente en tu disco duro para poder escucharla. Si buscas una canción que no está en tu biblioteca local o importas una playlist desde un servicio externo, entra en acción el subsistema youtube.rs.
Bajo el capó, Davusic orquesta yt-dlp con una gestión de procesos estrictamente controlada:
- Búsqueda Unificada: Al escribir en la barra de búsqueda (
Ctrl + K), se disparan dos hilos paralelos: búsqueda instantánea en la base de datos local y consulta en YouTube Music / YouTube (ytsearch12: artista canción). - Resolución On-Demand: Al pulsar reproducir en una pista remota, Davusic ejecuta
yt-dlpsolicitando únicamente el mejor stream de solo audio (-f bestaudio/best -x). - Almacenamiento Efímero: El fragmento de audio se transfiere directamente al directorio de caché del usuario:
~/.cache/davusic/streams/<video_id>.opus(en Linux) o%LOCALAPPDATA%\davusic\cache\(en Windows). - Poda Automática de Caché: Para no saturar el disco de forma silenciosa, Davusic incluye un recolector de basura (LRU Cache Pruning) configurable que elimina automáticamente los archivos descargados que superen la cuota máxima definida (por defecto 2 GB) o que lleven más de 30 días sin ser reproducidos.
yt-dlp instalado en su sistema operativo, Davusic no falla con un error críptico: descarga de forma autónoma el binario oficial securizado desde los releases de GitHub y lo aloja en ~/.local/share/davusic/bin/yt-dlp, dándole permisos de ejecución automáticamente.
05. La Frontera Legal de Spotify & Importación Universal con Exportify
Muchos clientes no oficiales de música cometen el grave error de intentar eludir el DRM de Spotify, extraer claves Widevine o utilizar librerías como librespot que violan los términos de servicio y suelen resultar en el baneo de las cuentas de usuario.
En Davusic establecimos una frontera legal inquebrantable:
- Cero Evasión de DRM: Davusic nunca reproduce audio de los servidores de Spotify, ni usa el Web Playback SDK ni lee cookies de aplicaciones de terceros instaladas en el ordenador.
- OAuth 2.0 PKCE Oficial: La integración con Spotify es 100% oficial mediante el estándar Proof Key for Code Exchange (RFC 7636). El flujo solicita exclusivamente permisos de lectura:
playlist-read-private,playlist-read-collaborativeyuser-library-read. - Tokens Protegidos: El token de sesión se almacena en
~/.config/davusic/spotify.jsoncon permisos estrictos Unix0600(solo lectura/escritura por el propietario).
Integración Nativa con Exportify y Fuentes Múltiples
Para aquellos usuarios que no deseen enlazar su cuenta de Spotify mediante OAuth, Davusic incorpora un parser universal de listas de reproducción en playlist_import.rs:
# Formatos reconocidos por el motor de importación:
[1] Exportify ZIP / CSV -> Exportación estándar de Spotify con cabeceras completas
[2] Google Takeout -> CSV / TSV extraídos de YouTube Music
[3] M3U / M3U8 Estándar -> Listas de reproducción de reproductores de escritorio clásicos
[4] JSON Estructurado -> Esquema nativo Davusic de listas compartidas
[5] Texto Plano (Raw) -> Listas en formato "Artista - Canción" pegadas a mano
Además, Davusic puede hacer el camino inverso: la función Exportar a Exportify genera un archivo ZIP con un CSV por cada playlist con las columnas normalizadas (Track Name, Artist Name(s), Album Name, Duration (ms), Track URI, Playlist Name), permitiendo migrar tu colección a cualquier otra plataforma sin vendor lock-in.
06. Letras Dinámicas con LRCLIB y Algoritmo de Recomendación Local
El reproductor integra soporte completo para letras de canciones a través de la API abierta de LRCLIB. Cuando una pista comienza a sonar:
- El backend consulta a LRCLIB pasando título, artista, álbum y duración exacta en segundos.
- Si existen marcas de tiempo (formato
[mm:ss.xx]), Davusic parsea la letra sincronizada (LRC). - En la interfaz inmersiva, los versos se desplazan automáticamente en sincronía con la reproducción de
rodio. Al hacer clic sobre cualquier estrofa de la letra, el reproductor realiza un seek instantáneo a esa posición exacta.
El Motor "Para ti": Machine Learning Local y Privado
La sección Para ti construye recomendaciones musicales sin enviar tus hábitos a ningún servidor. Cada vez que escuchas una canción completa (+1 punto), la agregas a tus Me gusta (+3 puntos), la saltas en los primeros 15 segundos (-2 puntos) o buscas reiteradamente a un artista, Davusic actualiza una matriz local de afinidad de géneros y artistas.
Cuando tu cola de reproducción llega a su fin, Davusic activa la Radio Automática: genera una cola infinita basada en tu perfil de afinidad local, encadenando temas relacionados desde tu biblioteca o mediante sugerencias de streaming.
07. Integración de Escritorio Linux: D-Bus MPRIS y Wayland (Niri)
Uno de los aspectos más descuidados en reproductores multiplataforma es la integración con el ecosistema Linux. Davusic implementa la especificación completa MPRIS v2 (Media Player Remote Interfacing Specification) a través de D-Bus mediante el crate mpris-server.
Esto permite:
- Control total desde las teclas multimedia de tu teclado (Play, Pausa, Siguiente, Anterior, Stop).
- Integración en barras de estado nativas de Wayland como Waybar o widgets de KDE Plasma / GNOME Shell.
- Visualización de la carátula en alta resolución en las notificaciones del sistema y en la pantalla de bloqueo.
- Control de volumen y scrubber de posición bidireccional desde herramientas como
playerctl:
# Comprobar estado del reproductor Davusic
$ playerctl --player=davusic status
Playing
# Obtener metadatos de la pista actual
$ playerctl --player=davusic metadata --format "{{ artist }} - {{ title }} ({{ duration(position) }} / {{ duration(mpris:length) }})"
Cyberpunk Ambient - Night City Rain (01:42 / 04:15)
# Saltar a una posición específica mediante D-Bus
$ playerctl --player=davusic position 120
Optimizado para Niri Scrollable Window Manager
Davusic incluye una configuración dedicada para el gestor de ventanas Wayland Niri en CachyOS. El instalador configura automáticamente la regla de ventana en ~/.config/niri/davusic.kdl para que la aplicación abra con el tamaño óptimo (1480×940) y respetando las esquinas redondeadas y sombras del compositor.
08. Guía Completa de Compilación e Instalación
Davusic es software libre distribuido bajo licencia MIT. Puedes compilarlo desde el código fuente o instalarlo mediante paquetes listos para producción.
1. Dependencias de Sistema
# En Arch Linux / CachyOS / Manjaro:
$ sudo pacman -S --needed base-devel rust webkit2gtk-4.1 gtk3 librsvg pkgconf alsa-lib
# En Debian / Ubuntu / Linux Mint:
$ sudo apt-get install -y \
build-essential pkg-config \
libwebkit2gtk-4.1-dev libgtk-3-dev \
libayatana-appindicator3-dev librsvg2-dev \
libasound2-dev patchelf
2. Clonar el Repositorio y Compilar
# Clonar el repositorio oficial
$ git clone https://github.com/davito-03/davusic.git
$ cd davusic
# Ejecutar los tests de Rust y validación de UI
$ cargo test
# Compilar binario optimizado en modo release
$ cargo build --release
3. Instalación Rápida en el Usuario Actual
El repositorio incluye un script de despliegue automatizado install.sh que instala el binario en ~/.local/bin/davusic, genera las entradas de escritorio en ~/.local/share/applications/davusic.desktop, registra los iconos en todos los tamaños y configura la regla para Niri:
$ ./scripts/install.sh
==> Instalando Davusic en ~/.local/bin/davusic...
==> Copiando iconos a ~/.local/share/icons/hicolor/...
==> Registrando davusic.desktop y actualizando base de datos de escritorio...
==> Regla Niri actualizada en ~/.config/niri/davusic.kdl
==> ¡Instalación completada con éxito! Ya puedes lanzar 'davusic'.
4. Generación de Paquetes .deb y AppImage
Si prefieres generar paquetes autocontenidos para tu distribución, utiliza cargo-tauri:
$ cargo tauri build --bundles deb,appimage
# Los paquetes generados quedarán en:
target/release/bundle/deb/davusic_0.1.0_amd64.deb
target/release/bundle/appimage/davusic_0.1.0_amd64.AppImage
5. Instalación en Windows 10/11
Davusic soporta Windows de forma nativa mediante el WebView2 Runtime. Puedes descargar los instaladores .exe (NSIS) o .msi directamente desde los Releases oficiales de GitHub, o compilar desde PowerShell con el toolchain MSVC:
PS > cargo build --release
PS > cargo tauri build
# Genera instaladores en target\release\bundle\nsis\ y bundle\msi\
09. Conclusiones & Roadmap
Davusic demuestra que no es necesario claudicar ante el consumo desmedido de memoria de Electron ni ceder el control de nuestros datos personales para disfrutar de una experiencia musical de primera clase en el escritorio. La combinación de Tauri 2, el rendimiento implacable de Rust y el desacoplamiento de servicios mediante herramientas consolidadas como yt-dlp ofrece la solución perfecta: velocidad inmediata, respeto estricto a la privacidad y longevidad técnica.
- Ecualizador Paramétrico de 10 bandas: Integración en Rust mediante filtros biquad en tiempo real sobre el flujo de
rodio. - Sincronización P2P local: Compartir playlists y biblioteca entre dispositivos en la misma red local mediante descubrimiento mDNS/ZeroConf sin servidores intermedios.
- Maduración de la versión Android: Llevar el motor nativo de reproducción y caché offline a dispositivos móviles, superando la vista previa actual.