A real-time internet radio streaming server built with Go that broadcasts a single continuous audio stream to all connected listeners.
- Single continuous audio stream - All users hear the same playback in real-time
- No seeking or per-user control - Traditional radio-style broadcast
- MP3 streaming over HTTP - Chunked transfer encoding for real-time delivery
- Fan-out broadcaster pattern - Efficiently serves multiple clients
- FIFO queue management - Songs play in order they were added
- Admin API - RESTful endpoints for managing songs and queue
- SQLite persistence - Stores songs, queue, history, and state
- FFmpeg integration - Ensures consistent audio format
- Slow client handling - Automatically drops clients that can't keep up
- Go 1.21 or higher
- FFmpeg installed and available in PATH
- SQLite (included via Go driver)
- Clone the repository:
git clone <repository-url>
cd radio/backend- Install dependencies:
go mod download- Ensure FFmpeg is installed:
ffmpeg -versionCreate a .env file in the backend directory:
PORT=8080
SONG_DIR=../songs
DB_PATH=./radio.db
STREAM_TIMEOUT=5PORT: HTTP server port (default: 8080)SONG_DIR: Directory containing MP3 filesDB_PATH: SQLite database file pathSTREAM_TIMEOUT: Timeout for slow clients in seconds
cd backend
go run cmd/server/main.goThe server will start on the configured port with the following endpoints:
- Stream:
http://localhost:8080/stream - Admin API:
http://localhost:8080/api/* - Health check:
http://localhost:8080/health
curl -X POST http://localhost:8080/api/songs \
-H "Content-Type: application/json" \
-d '{
"title": "Song Title",
"artist": "Artist Name",
"duration": 180,
"location": "/path/to/song.mp3"
}'curl http://localhost:8080/api/songscurl -X POST http://localhost:8080/api/queue/{song_id}curl http://localhost:8080/api/queuecurl http://localhost:8080/api/now-playingcurl http://localhost:8080/api/history?limit=50Use any media player that supports HTTP streaming:
ffplay http://localhost:8080/streamOr open in a browser:
http://localhost:8080/stream
radio/
├── backend/
│ ├── cmd/server/
│ │ └── main.go # Application entry point
│ ├── internal/
│ │ ├── admin/
│ │ │ ├── handler.go # Admin API handlers
│ │ │ └── routes.go # Route registration
│ │ ├── config/
│ │ │ └── config.go # Configuration loading
│ │ ├── database/
│ │ │ ├── migrations.go # Database schema
│ │ │ └── sqlite.go # SQLite connection
│ │ ├── playback/
│ │ │ ├── engine.go # Playback engine
│ │ │ └── ffmpeg.go # FFmpeg integration
│ │ ├── queue/
│ │ │ └── manager.go # Queue management
│ │ └── stream/
│ │ ├── broadcaster.go # Fan-out broadcaster
│ │ └── handler.go # HTTP stream handler
│ ├── .env # Environment variables
│ ├── go.mod # Go module definition
│ ├── go.sum # Go dependencies
│ └── article.md # Core concepts documentation
└── songs/ # MP3 files directory
POST /api/songs- Add a new songGET /api/songs- List all songsDELETE /api/songs/:id- Delete a song
POST /api/queue/:songId- Add song to queueGET /api/queue- Get current queueDELETE /api/queue/:id- Remove from queue
GET /api/now-playing- Get currently playing songGET /api/history- Get playback history
GET /health- Health check
Run unit tests:
cd backend
go test ./...Run tests with coverage:
go test -cover ./...For detailed explanations of the core concepts and patterns used in this project, see article.md.
Topics covered:
- Fan-out broadcaster pattern
- SQLite for persistence
- FFmpeg for audio streaming
- Chunked HTTP transfer encoding
- FIFO queue management
- Slow client detection
- Real-time throttling
Current version: v0.1.0
MIT License