An open API service indexing awesome lists of open source software.

https://github.com/noflowwater/yukebox

Self-hosted YouTube audio player for Bluetooth speakers
https://github.com/noflowwater/yukebox

bluetooth docker fastify music-player nextjs self-hosted typescript youtube

Last synced: 4 months ago
JSON representation

Self-hosted YouTube audio player for Bluetooth speakers

Awesome Lists containing this project

README

          

# YukeBox

> Self-hosted YouTube audio player for Bluetooth speakers

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Docker](https://img.shields.io/badge/Docker-ready-blue.svg)](docker-compose.yml)
[![Version](https://img.shields.io/badge/version-0.2.4-green.svg)](https://github.com/noFlowWater/yukebox/releases)
[![GHCR](https://img.shields.io/badge/GHCR-images-blue.svg)](https://github.com/noFlowWater/yukebox/pkgs/container)

Search or paste a YouTube URL — YukeBox streams audio directly to your Bluetooth speaker via the web.
No cloud. No subscriptions. Just your music, your speaker, your server.

---

## Features

- **Instant Playback** — Search YouTube or paste a URL, audio starts in seconds
- **Queue Management** — Add, reorder, remove tracks with auto-advance
- **Scheduled Playback** — Set alarms or timed playlists that auto-start
- **Multi-Speaker** — Register and switch between Bluetooth speakers on the fly
- **Bluetooth Management** — Scan, pair, and connect BT speakers from the web UI with auto-reconnect
- **Favorites** — Save your favorite tracks for quick access
- **Real-time Status** — Live playback updates via Server-Sent Events
- **Multi-User Auth** — Role-based access control (Admin / User)
- **Accessibility** — Dark/light theme, text scaling, reduced motion, timezone support
- **One-Command Deploy** — Docker Compose with automated setup script

---

## Quick Start

### Prerequisites

- **Linux** (Ubuntu 22.04+, Fedora 34+, Debian 12+)
- **Docker** + Docker Compose
- **PulseAudio** or **PipeWire** (with `pipewire-pulse`)
- **Bluetooth speaker** paired and connected

### Install & Run

```bash
git clone https://github.com/noFlowWater/yukebox.git
cd yukebox
./setup.sh
```

`setup.sh` handles everything: detects your audio socket, generates secrets, pulls pre-built images from GHCR, and launches the containers.

Open **http://localhost:3000** and create your first account.

### Uninstall

```bash
./cleanup.sh # interactive
./cleanup.sh --all # remove everything
```

---

## Bluetooth Setup

YukeBox can manage Bluetooth speakers directly from the **Admin Panel** — scan for devices, pair, connect, and disconnect without touching the terminal.

1. Open the Admin Panel
2. Scroll to **Bluetooth Devices**
3. Click **Scan** to discover nearby speakers
4. Click **Pair & Connect** on any discovered device

Connected speakers are automatically registered and ready to use. Auto-reconnect handles temporary disconnections.

Alternative: CLI pairing (before running setup)

```bash
bluetoothctl scan on
bluetoothctl pair
bluetoothctl connect
bluetoothctl trust

# Verify PulseAudio sees it
pactl list sinks short
# Should show: bluez_sink.XX_XX_XX_XX_XX_XX.*
```

Or use your desktop's Bluetooth settings (GNOME Settings, KDE System Settings, etc.)

---

## Configuration

All settings live in `.env` (auto-generated by `setup.sh`):

| Variable | Default | Description |
|----------|---------|-------------|
| `PORT` | `3000` | Web UI port |
| `NODE_ENV` | `production` | Environment |
| `PULSE_SOCKET` | (auto-detected) | Host PulseAudio socket path |
| `PULSE_COOKIE` | (auto-detected) | PulseAudio cookie path |
| `JWT_SECRET` | (auto-generated) | Auth token signing key |
| `MPV_SOCKET` | `/tmp/mpv-socket` | mpv IPC socket (advanced) |
| `DB_PATH` | `/app/data/yukebox.db` | SQLite database path (advanced) |

---

## Architecture

```
┌─────────────────────────────────────────────┐
│ Browser (any device on network) │
│ http://host:3000 │
└──────────────┬──────────────────────────────┘

┌──────────────▼──────────────────────────────┐
│ Docker Compose │
│ ┌────────────────┐ ┌───────────────────┐ │
│ │ Frontend │ │ Backend │ │
│ │ Next.js 15 │──│ Fastify + TS │ │
│ │ shadcn/ui │ │ SQLite │ │
│ │ :3000 │ │ mpv + yt-dlp │ │
│ └────────────────┘ │ SSE streaming │ │
│ │ :4000 (internal) │ │
│ └──────┬──┬─────────┘ │
└─────────────────────────────┼──┼────────────┘
PulseAudio ───┘ └─── D-Bus (bluetoothctl)
┌─────────────────────┐
│ Bluetooth Speaker │
└─────────────────────┘
```

| Layer | Stack |
|-------|-------|
| Backend | Fastify + TypeScript (ESM) |
| Auth | JWT (jose) + httpOnly Cookie + bcryptjs |
| Database | SQLite (better-sqlite3) |
| Bluetooth | bluetoothctl via D-Bus system bus |
| Frontend | Next.js 15 + shadcn/ui |
| Real-time | Server-Sent Events (SSE) |
| Deploy | Docker Compose |
| Images | GHCR (linux/amd64, linux/arm64) |

Only port **3000** is exposed. The frontend proxies API requests internally — no CORS configuration needed.

---

## HTTPS (Optional)

For external access, use nginx as a reverse proxy. See [`nginx.example.conf`](nginx.example.conf) for a starter template.

---

## Development

```bash
# Backend (terminal 1)
cd backend && npm install && npm run dev

# Frontend (terminal 2)
cd frontend && npm install && npm run dev
```

Backend runs on `:4000`, frontend on `:3000`. Next.js rewrites proxy `/api/*` to the backend.

```bash
# Run backend tests
cd backend && npm test
```

---

## Troubleshooting

No sound from Bluetooth speaker

1. Check connection: `bluetoothctl devices Connected`
2. Check PulseAudio: `pactl list sinks short`
3. Restart audio: `systemctl --user restart pulseaudio`

"PulseAudio socket not found" during setup

- PipeWire users: install `pipewire-pulse` and restart: `systemctl --user restart pipewire-pulse`
- Verify socket: `ls ${XDG_RUNTIME_DIR}/pulse/native`

Can't connect from phone/other device

- Use `http://:3000` instead of `localhost`
- Check firewall: `sudo ufw allow 3000`

Container can't access PulseAudio

- Verify `PULSE_SOCKET` in `.env` matches your socket path
- Check audio group: your user must be in the `audio` group

---

## Contributing

Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

---

## License

[MIT](LICENSE)