Airwave
# ๐ Airwave ### Self-hosted shared radio โ everyone listens in sync     [](https://vuejs.org/) > ๐ง **Turn any link into a shared listening experience** Paste a YouTube, SoundCloud, Mixcloud, or Spotify playlist link โ Airwave creates a **single live stream** โ Everyone hears the **exact same audio, at the exact same time** No accounts. No premium APIs. No โpress play at the same time.โ  --- ## โก Try it in 30 seconds ```bash docker run -d -p 8000:8000 ghcr.io/76696265636f646572/airwave ``` Open โ [http://localhost:8000](http://localhost:8000) Paste a link โ music starts โ share the URL ๐ --- ## ๐ง The idea (why this exists) Many music apps werenโt built for **shared listening**: * Everyone plays their **own stream** * Locked into one platform **Airwave solves this:** * One stream โ multiple listeners * Works across browsers and Sonos * Import Spotify playlists โ automatically matched to playable tracks * Multi-source playback (YouTube, SoundCloud, Mixcloud, direct URLs, optional local files) Simple idea. Huge difference. --- ## โจ What makes Airwave different? ### ๐ One shared live stream * Browsers connect as **SendSpin** clients * All listeners hear the same thing * No per-user transcoding * **Synchronized playback** across devices (SendSpin only) --- ### ๐ Collaborative queue * Anyone can add tracks * Drag & reorder in real time * Shared history --- ### โถ๏ธ Multi-source playback * YouTube (videos + playlists) * SoundCloud (tracks + sets) * Mixcloud (shows) * Direct HTTP(S) URLs to audio when ffmpeg can read them * Local files ๐ Paste almost any music link โ it just works --- ### ๐ฟ Local files & folders * Point Airwave at one or more directories with **`AIRWAVE_LOCAL_MEDIA_ROOTS`** * Browse and queue tracks from the UI (paths must stay inside those roots) * Great for NAS mounts, a music library on disk, or bind-mounted folders in Docker --- ### ๐ต Spotify โ playable music * Import Spotify playlists into your **library** * Auto-match tracks to YouTube, SoundCloud, or Mixcloud * Review and pick the best version for your shared stream --- ### ๐ Sonos integration * Uses `/stream/live.mp3` * Discover speakers on your LAN * Group and control playback * Same stream as browser clients --- ### ๐ฎ Player experience * Play / pause / skip / repeat * Seek (when supported) * Fullscreen โNow Playingโ * Lock screen controls (Media Session) --- ### ๐ก WLED / ambient light sync (sound reactive) * Sync **WLED** lights to Airwave using **LedFX** * Perfect for party mode and room vibe --- ### ๐ Library & playlists * Create and manage playlists * Import YouTube or Spotify playlists * Merge playlists (with deduplication) * Pin and reorder --- ### ๐ Playlist auto-sync * Turn on **Auto-sync** (๐) for any imported playlist * New tracks are added automatically * Your order stays untouched **Optional:** remove tracks that disappear from the source (off by default) --- ## ๐งโ๐คโ๐ง Perfect for * ๐ Parties (everyone queues music) * ๐ Shared household audio * ๐งโ๐ป Remote team listening * ๐ Sonos multi-room setups * ๐ง Friends hanging out online --- ## ๐ง How it works ``` yt-dlp โ ffmpeg โ shared MP3 stream โ all listeners ``` * One pipeline * One stream * Unlimited listeners --- ## ๐ณ Docker (recommended) For full functionality (especially Sonos): ```yaml network_mode: host ``` Set your public URL: ```env AIRWAVE_PUBLIC_BASE_URL=http://192.168.1.50:8000 ``` For **local files**, mount host directories into the container and set `AIRWAVE_LOCAL_MEDIA_ROOTS` to those in-container paths (see **Configuration** below). --- ## โ๏ธ Configuration ```env AIRWAVE_HOST=0.0.0.0 AIRWAVE_PORT=8000 AIRWAVE_PUBLIC_BASE_URL=http://192.168.1.50:8000 AIRWAVE_FFMPEG_PATH=./bin/ffmpeg AIRWAVE_FFPROBE_PATH=./bin/ffprobe AIRWAVE_YT_DLP_PATH=./bin/yt-dlp AIRWAVE_DENO_PATH=./bin/deno # Optional: allow browsing and queuing audio from these directories (server-side paths). # Comma-separated list, or a JSON array string, e.g. ["/music","/data/audio"]. # Leave unset to disable local media. In Docker, bind-mount the host folders and set paths inside the container. AIRWAVE_LOCAL_MEDIA_ROOTS=/path/to/music,/other/library AIRWAVE_MP3_BITRATE=128k AIRWAVE_CHUNK_SIZE=4096 AIRWAVE_STREAM_QUEUE_SIZE=16 AIRWAVE_LOG_LEVEL=info # Optional: SendSpin (browser clients + synchronized playback) AIRWAVE_SENDSPIN_ENABLED=true AIRWAVE_SENDSPIN_PORT=8927 AIRWAVE_SENDSPIN_NAME=Airwave AIRWAVE_SENDSPIN_MDNS_ENABLED=true # Optional: background playlist auto-sync (SyncService). Only playlists with Auto-sync # enabled in the UI are considered each pass. # Target seconds between the *start* of one sync pass and the start of the next (minimum 30). # If a pass takes longer than this, the next pass begins about a second after the long one ends. AIRWAVE_PLAYLIST_SYNC_INTERVAL_SECONDS=3600 # Max playlists to sync at once within a pass (1โ10). AIRWAVE_PLAYLIST_SYNC_MAX_CONCURRENT=2 ``` `AIRWAVE_FFMPEG_PATH` and `AIRWAVE_FFPROBE_PATH` are configured independently. Point each one to the executable you want Airwave to use. `AIRWAVE_CHUNK_SIZE` is how many bytes are read from ffmpegโs stdout per pull into the shared stream (default `4096`). Larger values mean fewer read syscalls; very small values increase overhead and can make occasional stutters more likely. `AIRWAVE_STREAM_QUEUE_SIZE` is the max depth of the in-memory buffer between ffmpeg and connected listeners (default `16`). Raise it if devices such as Sonos underrun the live stream. --- ## ๐งฑ Tech Stack * FastAPI * Vue 3 * yt-dlp * ffmpeg * SQLite --- ## ๐ Architecture (simplified) * FastAPI API โ HTTP + websocket endpoints, app state wiring * StreamEngine โ playback worker & prefetch * FfmpegPipeline โ transcoding & ffprobe probing * MediaSourceResolver โ local files & direct media URLs * PlaylistService โ queue/import orchestration * SyncService โ optional background sync for imported playlists (off per playlist until enabled) * SendSpinServerService โ synchronized playback (optional mDNS discovery) * SharedMp3Hub โ fan-out * SonosService โ LAN speaker discovery, grouping, and control * BinariesService โ yt-dlp/ffmpeg/ffprobe/deno management * Repository โ persistence --- ## ๐ฌ Why Airwave? Because shared music should be: * simple * synced * platform-independent Not: * fragmented * locked-in * out of sync --- ## ๐ค Contributing Ideas, issues, and PRs welcome! ๐ See [CONTRIBUTING.md](./CONTRIBUTING.md) --- ## โญ Support If you like Airwave: * โญ Star the repo * ๐ Report bugs * ๐ก Suggest features * ๐ข Share it --- ## ๐งญ Final thought > Airwave isnโt a music player. > Itโs a **shared radio for the internet.**