Skip to content

Latest commit

 

History

81 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bbeat

Servidor de música personal self-hosted. Webapp responsive mobile-first (+ app nativa de Android) que descarga música automáticamente desde URLs públicas y la sirve a tus dispositivos.

Pegas una URL de Spotify, YouTube o SoundCloud y Bbeat extrae la metadata, descarga el audio, lo etiqueta y organiza (Artista/Álbum/NN - Título.ext), lo indexa y lo deja listo para reproducir. Si la pista ya existe no la vuelve a bajar (detecta el duplicado por ID de origen y, si el ID no casa, por título + artista + duración): solo la enlaza al destino que elijas.

Pensado para uso personal o entre amigos en una instancia compartida: cada usuario tiene sus favoritos, su historial y su "Wrapped", y puede descargar canciones para escucharlas sin conexión. Además habla la API Subsonic, así que puedes escuchar tu música desde cualquier cliente compatible (ideal para iPhone: Amperfy, play:Sub, substreamer… o Symfonium en cualquier plataforma).

Aviso: exponer Bbeat a internet es bajo tu responsabilidad (ToS de las plataformas, copyright). Trae auth, pero el rate limiting aún no está incluido.

Estado

Listo para uso real, probado en producción.

Pieza Estado
App nativa de Android (Capacitor): offline real a disco, segundo plano, multi-servidor listo
API Subsonic: navegar, buscar, reproducir, crear/editar playlists, favoritos y scrobble desde clientes de terceros (iPhone, etc.) listo
Reproductor con Media Session (controles en lockscreen), cola, shuffle/repeat listo
"Now Playing" full-screen con color de la portada + letras sincronizadas (LRCLIB) listo
Favoritos, historial, "más escuchadas" y Wrapped listo
Descargas offline (PWA en IndexedDB / app nativa a disco) listo
Audio en Opus (copia del stream sin recodificar: mínimo tamaño, máxima calidad) listo
Carátula propia por pista (con miniatura de YouTube de fallback) listo
Pool global: cualquier usuario ve y reproduce todo el catálogo listo
Ingesta Spotify / YouTube / SoundCloud + playlists y mixes (con deselección) listo
Playlists multi-artista (una colección "Various Artists", no N álbumes) listo
Biblioteca por "guardados" (Guardados / Explorar), álbumes con dueño listo
Auth JWT + admin (registrar/banear/promover) · dedup por ID externo + título/artista/duración listo
Subir ficheros locales, editar/borrar pistas y álbumes desde la UI listo

Pool global: Pistas, álbumes, búsqueda y streaming son compartidos — cualquier usuario autenticado ve y reproduce todo el catálogo de la instancia. Lo que define tu biblioteca personal es guardar; el dueño de un álbum solo controla quién puede editarlo. Pensado para instancias entre gente de confianza.

Stack

  • Backend: FastAPI · SQLModel · SQLite · SpotifyScraper · yt-dlp · Mutagen · bcrypt · PyJWT · FFmpeg
  • Frontend: SvelteKit 5 · Tailwind 4 · TypeScript · PWA (Service Worker)
  • App Android: Capacitor (envuelve el mismo frontend) — ver ANDROID.md

Self-hosting

Requisitos: Python 3.12+, Node 22+, FFmpeg.

  1. Backend: crea un venv e instala backend/requirements.txt; copia backend/.env.examplebackend/.env.
  2. Frontend: cd frontend && npm install && npm run build (el backend sirve ese build estático).
  3. Arranca: python -m app.main desde backend/ y abre http://localhost:8787.

El primer usuario que se registra pasa a admin automáticamente.

Para producción, como servicio systemd (con loginctl enable-linger para sobrevivir a reboots) o con Docker (docker compose up -d). La app de Android se compila aparte — ver ANDROID.md.

Configuración

Todo en backend/.env (ver .env.example). Lo más relevante:

Variable Default Notas
BBEAT_HOST / BBEAT_PORT 0.0.0.0:8787 Bind del servidor
BBEAT_DEBUG false true = autoreload (no usar en prod)
BBEAT_MUSIC_DIR ../data/music Dónde se guarda la biblioteca
BBEAT_AUDIO_FORMAT opus Formato de descarga (opus = copia del stream Opus, sin recodificar)
BBEAT_MAX_CONCURRENT_JOBS 1 Descargas en paralelo (ojo con la RAM en hosts pequeños)
BBEAT_TRANSCODE_CONCURRENCY 2 Procesos ffmpeg simultáneos de transcoding Subsonic (limita pico de CPU)
BBEAT_TRANSCACHE_MAX_MB 1024 Tope en disco de la cache de transcoding; al superarlo purga los menos usados (0 = sin límite)
BBEAT_CORS_ORIGINS http://localhost:5173 Orígenes extra; los del WebView nativo se permiten siempre

Los secretos (JWT key, cookies opcionales de Spotify) viven en data/secrets/ con permisos 600. La carpeta data/ está fuera de git.

Cómo funciona

  1. Pegas una URL en /import; el backend resuelve la metadata sin descargar (SpotifyScraper o yt-dlp) y muestra un preview.
  2. Eliges el destino: auto (canción suelta / su álbum / colección multi-artista según el tipo), nuevo o añadir a uno tuyo; en playlists puedes (des)marcar pistas.
  3. Un worker procesa la cola: busca en YouTube el mejor match (con scoring que penaliza reacciones, directos y vídeos sin relación), descarga el audio en Opus, etiqueta, embebe carátula e indexa.

El audio viene de YouTube v?a yt-dlp; se prefiere el stream Opus y se copia sin recodificar.

No usamos la API pública de Spotify porque desde nov-2024 exige Premium en el dev app hasta para search; SpotifyScraper cubre la metadata sin credenciales.

Clientes Subsonic (iPhone y demás)

Bbeat implementa la API Subsonic, el estándar de facto de los servidores de música self-hosted. Sirve para escuchar desde apps de terceros — útil sobre todo en iPhone, donde no hay app nativa de Bbeat.

  1. En Ajustes → Acceso Subsonic, genera tu token (es un secreto aparte de tu contraseña).
  2. En el cliente, añade un servidor con la URL de tu instancia, tu usuario y el token como contraseña.

Clientes recomendados: Amperfy, play:Sub o substreamer (iOS); Symfonium, Tempo o DSub (Android); Sonixd / Feishin (escritorio). Funciona el browsing por artistas/álbumes/canciones, búsqueda, crear/editar/borrar playlists, favoritos (estrella ↔ "me gusta") y scrobble (alimenta tu historial y Wrapped).

Las playlists creadas desde un cliente Subsonic son las mismas que ves en la app de Bbeat (colecciones multi-artista). Borrar una playlist solo elimina la lista, nunca los ficheros de audio. Solo puedes editar/borrar las playlists de las que eres dueño.

Por qué un token y no tu contraseña: Subsonic exige poder validar md5(contraseña+salt), pero Bbeat guarda las contraseñas con bcrypt (irreversible). El token dedicado es regenerable y revocable desde Ajustes en cualquier momento.

Transcoding: por defecto el stream sirve el Opus tal cual. Si un cliente pide otro formato (format=mp3|aac|ogg), Bbeat transcodifica on-the-fly con FFmpeg y cachea el resultado en disco. El nº de procesos ffmpeg y el tamaño de la cache se ajustan con BBEAT_TRANSCODE_CONCURRENCY y BBEAT_TRANSCACHE_MAX_MB.

Exponer a internet (opcional)

Lo más simple es ponerlo detrás de Cloudflare: un record A a tu IP con proxy activado, port forward del router al puerto del backend, y SSL/TLS en modo Flexible + Always Use HTTPS. Para mayor seguridad, Cloudflare Tunnel + Access (sin abrir puertos). Recuerda que el rate limiting aún no está incluido.

Roadmap

  • Cola persistente (sobrevive al cierre, con posición)
  • Editar/mover pistas en bulk · importar de Apple Music / Deezer

Licencia

MIT. Ver LICENSE. El uso es bajo tu responsabilidad: cumplir los ToS de cada plataforma y la legislación de copyright es cosa del operador.

About

Self-hosted personal music server with Spotify ingest

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages