Compare commits
4 Commits
775bc16261
...
0dee51f344
| Author | SHA1 | Date |
|---|---|---|
|
|
0dee51f344 | |
|
|
13a6777eab | |
|
|
cc78c50e7a | |
|
|
65876b0a57 |
260
README.org
260
README.org
|
|
@ -1,35 +1,59 @@
|
||||||
#+TITLE: Asteroid Radio - Internet Streaming Implementation
|
#+TITLE: Asteroid Radio - Internet Streaming Platform
|
||||||
#+AUTHOR: Database Implementation Branch
|
#+AUTHOR: Glenn Thompson & Brian O'Reilly (Fade)
|
||||||
#+DATE: 2025-09-11
|
#+DATE: 2025-10-16
|
||||||
|
|
||||||
* Overview
|
* Overview
|
||||||
|
|
||||||
This branch implements a complete internet radio streaming system for Asteroid Radio, transforming it from a simple web interface into a fully functional streaming radio station with live broadcasting capabilities.
|
Asteroid Radio is a modern, web-based music streaming platform built with Common Lisp and the Radiance framework. It provides a complete internet radio streaming system with live broadcasting, user management, playlist control, and professional audio processing.
|
||||||
|
|
||||||
* Key Features
|
* Key Features
|
||||||
|
|
||||||
** Live Internet Radio Streaming
|
** Live Internet Radio Streaming
|
||||||
- Continuous MP3 streaming at 128kbps stereo
|
- Multiple streaming formats: AAC 96kbps (high efficiency), MP3 128kbps (standard), MP3 64kbps (low bandwidth)
|
||||||
- Professional audio processing with crossfading and normalization
|
- Professional audio processing with ReplayGain for consistent volume without pumping
|
||||||
|
- Smooth crossfading between tracks (5 second transitions)
|
||||||
|
- Dynamic compression to prevent clipping
|
||||||
- Icecast2 streaming server integration
|
- Icecast2 streaming server integration
|
||||||
- Liquidsoap audio pipeline for reliable broadcasting
|
- Liquidsoap audio pipeline with watch-based playlist reloading
|
||||||
|
|
||||||
|
** Stream Queue Control System
|
||||||
|
- Curated stream queue management (play tracks in specific order)
|
||||||
|
- Add tracks to end of queue or as "next to play"
|
||||||
|
- Add entire playlists to stream queue
|
||||||
|
- Real-time queue reordering
|
||||||
|
- Automatic fallback to random playback when queue is empty
|
||||||
|
- Stream history tracking
|
||||||
|
- Admin-only queue control via REST API
|
||||||
|
|
||||||
** Music Library Management
|
** Music Library Management
|
||||||
- Database-backed track storage with metadata extraction
|
- PostgreSQL-backed track storage with metadata extraction
|
||||||
- Support for MP3, FLAC, OGG, and WAV formats
|
- Support for MP3, FLAC, OGG, and WAV formats
|
||||||
- Automatic metadata extraction using taglib
|
- Automatic metadata extraction using taglib
|
||||||
- Track search, filtering, and sorting capabilities
|
- Track search, filtering, and sorting capabilities
|
||||||
|
- Pagination support for large libraries
|
||||||
|
- Individual track streaming on-demand
|
||||||
|
|
||||||
|
** User Management System
|
||||||
|
- User registration and authentication
|
||||||
|
- Role-based access control (admin/user)
|
||||||
|
- User profiles and session management
|
||||||
|
- Personal playlist creation and management
|
||||||
|
- Admin interface for user administration
|
||||||
|
|
||||||
** Web Interface
|
** Web Interface
|
||||||
- RADIANCE framework with CLIP templating
|
- RADIANCE framework with CLIP templating
|
||||||
- Admin dashboard for library management
|
- Modern admin dashboard with JavaScript controls
|
||||||
- Web player with HTML5 audio controls
|
- Web player with HTML5 audio controls
|
||||||
- Live stream integration with embedded player
|
- Live stream integration with embedded player
|
||||||
|
- Dark hacker-themed aesthetic with VT323 font
|
||||||
|
- Responsive design for desktop and mobile
|
||||||
|
|
||||||
** Network Broadcasting
|
** Network Broadcasting
|
||||||
|
- Docker-based streaming infrastructure
|
||||||
- WSL-compatible networking for internal network access
|
- WSL-compatible networking for internal network access
|
||||||
- Professional streaming URLs for media players
|
- Professional streaming URLs for media players
|
||||||
- Multi-listener support via Icecast2
|
- Multi-listener support via Icecast2
|
||||||
|
- Telnet control interface for live DJ operations
|
||||||
|
|
||||||
* Architecture Changes
|
* Architecture Changes
|
||||||
|
|
||||||
|
|
@ -41,28 +65,44 @@ This branch implements a complete internet radio streaming system for Asteroid R
|
||||||
|
|
||||||
** Streaming Stack
|
** Streaming Stack
|
||||||
- *Icecast2*: Streaming server (port 8000)
|
- *Icecast2*: Streaming server (port 8000)
|
||||||
- *Liquidsoap*: Audio processing and streaming pipeline
|
- *Liquidsoap*: Audio processing and streaming pipeline with telnet control (port 1234)
|
||||||
- *RADIANCE*: Web server and API (port 8080)
|
- *RADIANCE*: Web server and API (port 8080)
|
||||||
- *Database*: Track metadata and playlist storage
|
- *PostgreSQL*: User accounts, track metadata, and playlist storage
|
||||||
|
- *Docker Compose*: Container orchestration for streaming services
|
||||||
|
|
||||||
** File Structure
|
** File Structure
|
||||||
#+BEGIN_SRC
|
#+BEGIN_SRC
|
||||||
asteroid/
|
asteroid/
|
||||||
├── asteroid.lisp # Main server with RADIANCE routes
|
├── asteroid.lisp # Main server with RADIANCE routes
|
||||||
├── asteroid.asd # System definition with dependencies
|
├── asteroid.asd # System definition with dependencies
|
||||||
├── asteroid-radio.liq # Liquidsoap streaming configuration
|
├── stream-control.lisp # Stream queue management system
|
||||||
├── playlist.m3u # Generated playlist for streaming
|
├── stream-media.lisp # Media streaming and track management
|
||||||
├── start-asteroid-radio.sh # Launch script for all services
|
├── user-management.lisp # User authentication and profiles
|
||||||
├── stop-asteroid-radio.sh # Stop script for all services
|
├── playlist-management.lisp # User playlist operations
|
||||||
|
├── auth-routes.lisp # Authentication endpoints
|
||||||
|
├── stream-queue.m3u # Generated stream queue playlist
|
||||||
|
├── docker/ # Docker streaming infrastructure
|
||||||
|
│ ├── docker-compose.yml # Container orchestration
|
||||||
|
│ ├── asteroid-radio-docker.liq # Liquidsoap configuration
|
||||||
|
│ └── start.sh # Container startup script
|
||||||
├── template/ # CLIP HTML templates
|
├── template/ # CLIP HTML templates
|
||||||
│ ├── front-page.chtml # Main page with live stream
|
│ ├── front-page.chtml # Main page with live stream
|
||||||
│ ├── admin.chtml # Admin dashboard
|
│ ├── admin.chtml # Admin dashboard with queue controls
|
||||||
│ └── player.chtml # Web player interface
|
│ ├── player.chtml # Web player interface
|
||||||
├── static/ # CSS and assets
|
│ └── login.chtml # User authentication
|
||||||
│ └── asteroid.lass # LASS stylesheet
|
├── static/ # Frontend assets
|
||||||
|
│ ├── asteroid.lass # LASS stylesheet source
|
||||||
|
│ ├── asteroid.css # Compiled CSS
|
||||||
|
│ └── js/
|
||||||
|
│ ├── admin.js # Admin interface controls
|
||||||
|
│ └── player.js # Web player functionality
|
||||||
|
├── docs/ # Documentation
|
||||||
|
│ ├── STREAM-CONTROL.org # Queue management guide
|
||||||
|
│ ├── API-REFERENCE.org # Complete API documentation
|
||||||
|
│ ├── USER-MANAGEMENT-SYSTEM.org # User system guide
|
||||||
|
│ └── INSTALLATION.org # Setup instructions
|
||||||
└── music/ # Music library
|
└── music/ # Music library
|
||||||
├── incoming/ # Upload staging area
|
└── library/ # Music files
|
||||||
└── library/ # Processed music files
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
* Track Upload Workflow
|
* Track Upload Workflow
|
||||||
|
|
@ -110,35 +150,68 @@ sudo systemctl start icecast2
|
||||||
|
|
||||||
* Liquidsoap Integration
|
* Liquidsoap Integration
|
||||||
|
|
||||||
** Configuration File: =asteroid-radio.liq=
|
** Configuration File: =docker/asteroid-radio-docker.liq=
|
||||||
#+BEGIN_SRC liquidsoap
|
#+BEGIN_SRC liquidsoap
|
||||||
#!/usr/bin/liquidsoap
|
#!/usr/bin/liquidsoap
|
||||||
|
|
||||||
# Set log level for debugging
|
# Allow running as root in Docker
|
||||||
settings.log.level := 4
|
set("init.allow_root", true)
|
||||||
|
log.level.set(4)
|
||||||
|
|
||||||
# Create playlist from directory
|
# Enable telnet server for remote control
|
||||||
radio = playlist(mode="randomize", reload=3600, "/path/to/music/library/")
|
settings.server.telnet.set(true)
|
||||||
|
settings.server.telnet.port.set(1234)
|
||||||
|
settings.server.telnet.bind_addr.set("0.0.0.0")
|
||||||
|
|
||||||
# Add audio processing
|
# Create playlist source from managed stream queue
|
||||||
radio = amplify(1.0, radio)
|
radio = playlist(
|
||||||
|
mode="normal", # Play in order (not randomized)
|
||||||
|
reload=5, # Check for playlist updates every 5 seconds
|
||||||
|
reload_mode="watch", # Watch file for changes
|
||||||
|
"/app/stream-queue.m3u"
|
||||||
|
)
|
||||||
|
|
||||||
# Fallback with sine wave for debugging
|
# Fallback to directory scan if queue is empty
|
||||||
radio = fallback(track_sensitive=false, [radio, sine(440.0)])
|
radio_fallback = playlist.safe(
|
||||||
|
mode="randomize",
|
||||||
|
reload=3600,
|
||||||
|
"/app/music/"
|
||||||
|
)
|
||||||
|
|
||||||
# Output to Icecast2
|
radio = fallback(track_sensitive=false, [radio, radio_fallback])
|
||||||
output.icecast(
|
|
||||||
%mp3(bitrate=128),
|
# Use ReplayGain for consistent volume without pumping
|
||||||
host="localhost",
|
radio = amplify(1.0, override="replaygain", radio)
|
||||||
port=8000,
|
|
||||||
password="b3l0wz3r0",
|
# Add smooth crossfade between tracks (5 seconds)
|
||||||
mount="asteroid.mp3",
|
radio = crossfade(
|
||||||
name="Asteroid Radio",
|
duration=5.0,
|
||||||
description="Music for Hackers - Streaming from the Asteroid",
|
fade_in=3.0,
|
||||||
genre="Electronic/Alternative",
|
fade_out=3.0,
|
||||||
url="http://localhost:8080/asteroid/",
|
|
||||||
radio
|
radio
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add compressor to prevent clipping
|
||||||
|
radio = compress(
|
||||||
|
ratio=3.0,
|
||||||
|
threshold=-15.0,
|
||||||
|
attack=50.0,
|
||||||
|
release=400.0,
|
||||||
|
radio
|
||||||
|
)
|
||||||
|
|
||||||
|
# Output to Icecast2 in multiple formats
|
||||||
|
output.icecast(%mp3(bitrate=128), host="icecast", port=8000,
|
||||||
|
password="H1tn31EhsyLrfRmo", mount="asteroid.mp3",
|
||||||
|
name="Asteroid Radio", radio)
|
||||||
|
|
||||||
|
output.icecast(%fdkaac(bitrate=96), host="icecast", port=8000,
|
||||||
|
password="H1tn31EhsyLrfRmo", mount="asteroid.aac",
|
||||||
|
name="Asteroid Radio (AAC)", radio)
|
||||||
|
|
||||||
|
output.icecast(%mp3(bitrate=64), host="icecast", port=8000,
|
||||||
|
password="H1tn31EhsyLrfRmo", mount="asteroid-low.mp3",
|
||||||
|
name="Asteroid Radio (Low Quality)", radio)
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** Installation (Ubuntu/Debian)
|
** Installation (Ubuntu/Debian)
|
||||||
|
|
@ -148,11 +221,14 @@ sudo apt install liquidsoap
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** Features
|
** Features
|
||||||
- *Random playlist*: Shuffles music library continuously
|
- *Stream queue control*: Curated playlist with watch-based reloading (5 second updates)
|
||||||
- *Auto-reload*: Playlist refreshes every hour
|
- *Smart fallback*: Random playback when queue is empty
|
||||||
- *Audio processing*: Amplification and normalization
|
- *ReplayGain processing*: Consistent volume without pumping artifacts
|
||||||
- *Fallback*: Sine tone if no music available (debugging)
|
- *Crossfading*: Smooth 5-second transitions between tracks
|
||||||
- *Metadata*: Station info broadcast to listeners
|
- *Dynamic compression*: Prevents clipping and maintains audio quality
|
||||||
|
- *Multi-format output*: AAC 96kbps, MP3 128kbps, MP3 64kbps
|
||||||
|
- *Telnet control*: Live DJ operations via port 1234
|
||||||
|
- *Metadata broadcasting*: Track info sent to listeners
|
||||||
|
|
||||||
* Network Access
|
* Network Access
|
||||||
|
|
||||||
|
|
@ -175,14 +251,19 @@ sudo apt install liquidsoap
|
||||||
|
|
||||||
** Starting the Radio Station
|
** Starting the Radio Station
|
||||||
#+BEGIN_SRC bash
|
#+BEGIN_SRC bash
|
||||||
# Launch all services
|
# Start Docker streaming services
|
||||||
./start-asteroid-radio.sh
|
cd docker
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# Start Asteroid web application
|
||||||
|
sbcl --load asteroid.lisp
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** Stopping the Radio Station
|
** Stopping the Radio Station
|
||||||
#+BEGIN_SRC bash
|
#+BEGIN_SRC bash
|
||||||
# Stop all services
|
# Stop Docker services
|
||||||
./stop-asteroid-radio.sh
|
cd docker
|
||||||
|
docker-compose down
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** Adding Music
|
** Adding Music
|
||||||
|
|
@ -199,25 +280,41 @@ sudo apt install liquidsoap
|
||||||
* API Endpoints
|
* API Endpoints
|
||||||
|
|
||||||
** Track Management
|
** Track Management
|
||||||
- =GET /api/tracks= - List all tracks with metadata
|
- =GET /api/asteroid/tracks= - List all tracks with pagination
|
||||||
- =GET /tracks/{id}/stream= - Stream individual track
|
- =GET /api/asteroid/tracks/:id/stream= - Stream individual track
|
||||||
- =POST /api/scan-library= - Scan and update music library
|
- =POST /api/asteroid/scan-library= - Scan and update music library
|
||||||
- =POST /api/copy-files= - Process files from incoming directory
|
- =GET /api/asteroid/tracks?search={query}= - Search tracks
|
||||||
|
|
||||||
** Player Control
|
** Stream Queue Control (Admin Only)
|
||||||
- =POST /api/player/play= - Start playback
|
- =GET /api/asteroid/stream/queue= - Get current stream queue
|
||||||
- =POST /api/player/pause= - Pause playback
|
- =POST /api/asteroid/stream/queue/add= - Add track to queue (position: end/next)
|
||||||
- =POST /api/player/stop= - Stop playback
|
- =POST /api/asteroid/stream/queue/remove= - Remove track from queue
|
||||||
- =GET /api/status= - Get server status
|
- =POST /api/asteroid/stream/queue/clear= - Clear entire queue
|
||||||
|
- =POST /api/asteroid/stream/queue/add-playlist= - Add playlist to queue
|
||||||
|
- =POST /api/asteroid/stream/queue/reorder= - Reorder queue tracks
|
||||||
|
- =GET /api/asteroid/stream/history= - Get stream history
|
||||||
|
|
||||||
** Search and Filter
|
** User Management
|
||||||
- =GET /api/tracks?search={query}= - Search tracks
|
- =POST /api/asteroid/auth/register= - Register new user
|
||||||
- =GET /api/tracks?sort={field}= - Sort by field
|
- =POST /api/asteroid/auth/login= - User login
|
||||||
- =GET /api/tracks?artist={name}= - Filter by artist
|
- =POST /api/asteroid/auth/logout= - User logout
|
||||||
|
- =GET /api/asteroid/auth/profile= - Get user profile
|
||||||
|
- =GET /api/asteroid/users= - List users (admin only)
|
||||||
|
- =POST /api/asteroid/users/:id/role= - Update user role (admin only)
|
||||||
|
|
||||||
|
** Playlist Management
|
||||||
|
- =GET /api/asteroid/playlists= - List user's playlists
|
||||||
|
- =POST /api/asteroid/playlists= - Create new playlist
|
||||||
|
- =GET /api/asteroid/playlists/:id= - Get playlist details
|
||||||
|
- =DELETE /api/asteroid/playlists/:id= - Delete playlist
|
||||||
|
- =POST /api/asteroid/playlists/:id/tracks= - Add track to playlist
|
||||||
|
- =DELETE /api/asteroid/playlists/:id/tracks/:track-id= - Remove track from playlist
|
||||||
|
|
||||||
|
See =docs/API-REFERENCE.org= for complete API documentation.
|
||||||
|
|
||||||
* Database Schema
|
* Database Schema
|
||||||
|
|
||||||
** Tracks Collection
|
** Tracks Table
|
||||||
#+BEGIN_SRC lisp
|
#+BEGIN_SRC lisp
|
||||||
(db:create "tracks" '((title :text)
|
(db:create "tracks" '((title :text)
|
||||||
(artist :text)
|
(artist :text)
|
||||||
|
|
@ -230,12 +327,23 @@ sudo apt install liquidsoap
|
||||||
(play-count :integer)))
|
(play-count :integer)))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** Playlists Collection (Future)
|
** Users Table
|
||||||
|
#+BEGIN_SRC lisp
|
||||||
|
(db:create "users" '((username :text)
|
||||||
|
(email :text)
|
||||||
|
(password-hash :text)
|
||||||
|
(role :text) ; "admin" or "user"
|
||||||
|
(created-at :integer)
|
||||||
|
(last-login :integer)))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** Playlists Table
|
||||||
#+BEGIN_SRC lisp
|
#+BEGIN_SRC lisp
|
||||||
(db:create "playlists" '((name :text)
|
(db:create "playlists" '((name :text)
|
||||||
(description :text)
|
(description :text)
|
||||||
(created-date :integer)
|
(user-id :integer)
|
||||||
(track-ids :text)))
|
(created-at :integer)
|
||||||
|
(track-ids :text))) ; JSON array of track IDs
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
* Dependencies
|
* Dependencies
|
||||||
|
|
@ -274,17 +382,21 @@ sudo apt install liquidsoap
|
||||||
* Future Enhancements
|
* Future Enhancements
|
||||||
|
|
||||||
** Planned Features
|
** Planned Features
|
||||||
- Playlist creation and management interface
|
- Web UI for drag-and-drop queue management
|
||||||
- Now-playing status tracking and display
|
- Real-time now-playing display with WebSocket updates
|
||||||
- Direct browser file uploads with progress
|
- Direct browser file uploads with progress bars
|
||||||
- Listener statistics and analytics
|
- Listener statistics and analytics dashboard
|
||||||
- Scheduled programming and automation
|
- Scheduled programming and automation
|
||||||
|
- Social features (playlist sharing, discovery)
|
||||||
|
- Mobile native applications
|
||||||
|
|
||||||
** Technical Improvements
|
** Technical Improvements
|
||||||
- WebSocket integration for real-time updates
|
- WebSocket integration for real-time updates
|
||||||
- Advanced audio processing options
|
- Telnet integration for skip/next commands from web UI
|
||||||
- Multi-bitrate streaming support
|
- Auto-queue filling (add tracks when queue runs low)
|
||||||
- Mobile-responsive interface enhancements
|
- Genre-based smart queues
|
||||||
|
- Listener request system
|
||||||
|
- Full-text search capabilities
|
||||||
|
|
||||||
* Troubleshooting
|
* Troubleshooting
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,186 @@ curl -X POST http://localhost:8080/api/asteroid/playlists/add-track \
|
||||||
}
|
}
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
* Stream Queue Control Endpoints (Admin Only)
|
||||||
|
|
||||||
|
** GET /api/asteroid/stream/queue
|
||||||
|
|
||||||
|
Get the current stream queue.
|
||||||
|
|
||||||
|
*** Authentication
|
||||||
|
Required (Admin role)
|
||||||
|
|
||||||
|
*** Response
|
||||||
|
#+BEGIN_SRC json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"queue": [
|
||||||
|
{
|
||||||
|
"id": "track-id-123",
|
||||||
|
"title": "Track Name",
|
||||||
|
"artist": "Artist Name",
|
||||||
|
"album": "Album Name",
|
||||||
|
"duration": 245
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"queueLength": 10
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** POST /api/asteroid/stream/queue/add
|
||||||
|
|
||||||
|
Add a track to the stream queue.
|
||||||
|
|
||||||
|
*** Authentication
|
||||||
|
Required (Admin role)
|
||||||
|
|
||||||
|
*** Parameters
|
||||||
|
- =track-id= (required) - ID of the track to add
|
||||||
|
- =position= (optional) - "end" (default) or "next"
|
||||||
|
|
||||||
|
*** Example Request
|
||||||
|
#+BEGIN_SRC bash
|
||||||
|
# Add to end of queue
|
||||||
|
curl -X POST http://localhost:8080/api/asteroid/stream/queue/add \
|
||||||
|
-d "track-id=123" \
|
||||||
|
-b cookies.txt
|
||||||
|
|
||||||
|
# Add as next track
|
||||||
|
curl -X POST http://localhost:8080/api/asteroid/stream/queue/add \
|
||||||
|
-d "track-id=123&position=next" \
|
||||||
|
-b cookies.txt
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** Response
|
||||||
|
#+BEGIN_SRC json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"message": "Track added to stream queue"
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** POST /api/asteroid/stream/queue/remove
|
||||||
|
|
||||||
|
Remove a track from the stream queue.
|
||||||
|
|
||||||
|
*** Authentication
|
||||||
|
Required (Admin role)
|
||||||
|
|
||||||
|
*** Parameters
|
||||||
|
- =track-id= (required) - ID of the track to remove
|
||||||
|
|
||||||
|
*** Example Request
|
||||||
|
#+BEGIN_SRC bash
|
||||||
|
curl -X POST http://localhost:8080/api/asteroid/stream/queue/remove \
|
||||||
|
-d "track-id=123" \
|
||||||
|
-b cookies.txt
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** Response
|
||||||
|
#+BEGIN_SRC json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"message": "Track removed from stream queue"
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** POST /api/asteroid/stream/queue/clear
|
||||||
|
|
||||||
|
Clear the entire stream queue.
|
||||||
|
|
||||||
|
*** Authentication
|
||||||
|
Required (Admin role)
|
||||||
|
|
||||||
|
*** Response
|
||||||
|
#+BEGIN_SRC json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"message": "Stream queue cleared"
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** POST /api/asteroid/stream/queue/add-playlist
|
||||||
|
|
||||||
|
Add all tracks from a playlist to the stream queue.
|
||||||
|
|
||||||
|
*** Authentication
|
||||||
|
Required (Admin role)
|
||||||
|
|
||||||
|
*** Parameters
|
||||||
|
- =playlist-id= (required) - ID of the playlist to add
|
||||||
|
|
||||||
|
*** Example Request
|
||||||
|
#+BEGIN_SRC bash
|
||||||
|
curl -X POST http://localhost:8080/api/asteroid/stream/queue/add-playlist \
|
||||||
|
-d "playlist-id=5" \
|
||||||
|
-b cookies.txt
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** Response
|
||||||
|
#+BEGIN_SRC json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"message": "Playlist added to stream queue",
|
||||||
|
"tracksAdded": 15
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** POST /api/asteroid/stream/queue/reorder
|
||||||
|
|
||||||
|
Reorder the stream queue.
|
||||||
|
|
||||||
|
*** Authentication
|
||||||
|
Required (Admin role)
|
||||||
|
|
||||||
|
*** Parameters
|
||||||
|
- =track-ids= (required) - Comma-separated list of track IDs in desired order
|
||||||
|
|
||||||
|
*** Example Request
|
||||||
|
#+BEGIN_SRC bash
|
||||||
|
curl -X POST http://localhost:8080/api/asteroid/stream/queue/reorder \
|
||||||
|
-d "track-ids=123,456,789" \
|
||||||
|
-b cookies.txt
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** Response
|
||||||
|
#+BEGIN_SRC json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"message": "Stream queue reordered"
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
** GET /api/asteroid/stream/history
|
||||||
|
|
||||||
|
Get recently played tracks from the stream.
|
||||||
|
|
||||||
|
*** Authentication
|
||||||
|
Required (Admin role)
|
||||||
|
|
||||||
|
*** Parameters
|
||||||
|
- =limit= (optional) - Number of tracks to return (default: 10)
|
||||||
|
|
||||||
|
*** Example Request
|
||||||
|
#+BEGIN_SRC bash
|
||||||
|
curl "http://localhost:8080/api/asteroid/stream/history?limit=20" \
|
||||||
|
-b cookies.txt
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
*** Response
|
||||||
|
#+BEGIN_SRC json
|
||||||
|
{
|
||||||
|
"status": "success",
|
||||||
|
"history": [
|
||||||
|
{
|
||||||
|
"id": "track-id-123",
|
||||||
|
"title": "Track Name",
|
||||||
|
"artist": "Artist Name",
|
||||||
|
"playedAt": "2025-10-16T10:30:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
* Admin Endpoints
|
* Admin Endpoints
|
||||||
|
|
||||||
** POST /api/asteroid/admin/scan-library
|
** POST /api/asteroid/admin/scan-library
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,638 @@
|
||||||
|
#+TITLE: Asteroid Radio - Development Log
|
||||||
|
#+AUTHOR: Glenn Thompson & Brian O'Reilly (Fade)
|
||||||
|
#+DATE: 2024-09-11 to 2025-10-16
|
||||||
|
|
||||||
|
* Introduction
|
||||||
|
|
||||||
|
This document chronicles the complete development history of Asteroid Radio, from initial concept to a fully-featured internet radio streaming platform. The project evolved from a simple design document into a sophisticated Common Lisp web application with professional streaming infrastructure.
|
||||||
|
|
||||||
|
** Project Vision
|
||||||
|
|
||||||
|
Asteroid Radio is designed to be the premier streaming platform for "Asteroid Music" - the perfect soundtrack for developers, hackers, and anyone who spends hours deep in code. The mission is to curate and deliver music that enhances focus, creativity, and the flow state.
|
||||||
|
|
||||||
|
** Key Contributors
|
||||||
|
|
||||||
|
- *Glenn Thompson (glenneth)* - Core development, API architecture, user management, testing
|
||||||
|
- *Brian O'Reilly (Fade)* - Project lead, infrastructure, CLIP templating, system architecture
|
||||||
|
- *Luis Pereira (easilok)* - Frontend development, UI/UX improvements, styling
|
||||||
|
|
||||||
|
* Phase 1: Project Foundation (September 2024)
|
||||||
|
|
||||||
|
** 2024-09-11: Initial Commit
|
||||||
|
- Project skeleton created
|
||||||
|
- Basic repository structure established
|
||||||
|
- Initial .gitignore configuration
|
||||||
|
|
||||||
|
** 2024-09-11: Design Document
|
||||||
|
- Added comprehensive design document (design.org)
|
||||||
|
- Defined project goals and architecture
|
||||||
|
- Outlined feature roadmap for internet radio station
|
||||||
|
- Established technical requirements
|
||||||
|
|
||||||
|
** 2024-09-11: Hunchentoot Implementation
|
||||||
|
- Implemented initial web server using Hunchentoot
|
||||||
|
- Basic HTTP server functionality
|
||||||
|
- Foundation for web interface
|
||||||
|
|
||||||
|
* Phase 2: RADIANCE Migration (September 2024)
|
||||||
|
|
||||||
|
** 2024-09-11: Framework Migration
|
||||||
|
- Migrated from Hunchentoot to RADIANCE web framework
|
||||||
|
- Reorganized system around Radiance build conventions
|
||||||
|
- Established proper module structure
|
||||||
|
- Set up template directory structure
|
||||||
|
|
||||||
|
** 2024-09-11: LASS CSS System
|
||||||
|
- Implemented LASS for dynamic CSS generation
|
||||||
|
- Fixed LASS compilation issues
|
||||||
|
- Enabled programmatic stylesheet generation
|
||||||
|
- Established dark hacker theme aesthetic
|
||||||
|
|
||||||
|
** 2024-09-11: Build System
|
||||||
|
- Created build-executable.lisp for deployment
|
||||||
|
- Configured custom SBCL paths
|
||||||
|
- Set up Makefile for build automation
|
||||||
|
- Removed build artifacts from version control
|
||||||
|
|
||||||
|
* Phase 3: CLIP Templating (September 2024)
|
||||||
|
|
||||||
|
** 2024-09-11: Template System
|
||||||
|
- Began CLIP templating implementation
|
||||||
|
- Created initial template structure
|
||||||
|
- Established template conventions
|
||||||
|
- Set up dynamic content rendering
|
||||||
|
|
||||||
|
** 2024-09-11: Complete Template Migration
|
||||||
|
- Completed CLIP template refactoring
|
||||||
|
- Migrated all pages to CLIP system
|
||||||
|
- Implemented template inheritance
|
||||||
|
- Established consistent page structure
|
||||||
|
|
||||||
|
* Phase 4: Database Integration (September-October 2024)
|
||||||
|
|
||||||
|
** 2024-09-11: RADIANCE Database
|
||||||
|
- Implemented RADIANCE database integration
|
||||||
|
- Set up database abstraction layer
|
||||||
|
- Created track storage schema
|
||||||
|
- Established query patterns
|
||||||
|
|
||||||
|
** 2024-09-11: Metadata Extraction
|
||||||
|
- Implemented complete metadata extraction
|
||||||
|
- Added taglib integration for audio files
|
||||||
|
- Extracted title, artist, album, duration, bitrate
|
||||||
|
- Automated metadata processing pipeline
|
||||||
|
|
||||||
|
** 2024-09-11: Internet Radio System
|
||||||
|
- Implemented complete internet radio streaming system
|
||||||
|
- Integrated Icecast2 streaming server
|
||||||
|
- Set up Liquidsoap audio pipeline
|
||||||
|
- Established continuous broadcasting
|
||||||
|
|
||||||
|
** 2024-10-01: Database Refactoring
|
||||||
|
- Refactored database features into discrete files
|
||||||
|
- Improved code organization
|
||||||
|
- Separated concerns for maintainability
|
||||||
|
- Created modular file structure
|
||||||
|
|
||||||
|
* Phase 5: User Management System (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-01: User System Foundation
|
||||||
|
- Added user management dependencies
|
||||||
|
- Created users.lisp module
|
||||||
|
- Implemented user profile system
|
||||||
|
- Set up authentication framework
|
||||||
|
|
||||||
|
** 2024-10-01: Authentication System
|
||||||
|
- Fixed Asteroid Radio authentication system
|
||||||
|
- Implemented secure password hashing
|
||||||
|
- Created session management
|
||||||
|
- Added login/logout functionality
|
||||||
|
|
||||||
|
** 2024-10-01: User Management API
|
||||||
|
- Fixed user management API authentication
|
||||||
|
- Implemented proper data formatting
|
||||||
|
- Created user administration endpoints
|
||||||
|
- Added role-based access control
|
||||||
|
|
||||||
|
** 2024-10-01: Recursive Music Scanning
|
||||||
|
- Implemented recursive directory scanning
|
||||||
|
- Added implicit depth-2 music discovery
|
||||||
|
- Improved library management
|
||||||
|
- Automated music file detection
|
||||||
|
|
||||||
|
* Phase 6: Docker Infrastructure (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-02: Docker Streaming
|
||||||
|
- Added Docker streaming infrastructure
|
||||||
|
- Created Liquidsoap container configuration
|
||||||
|
- Set up Icecast2 container
|
||||||
|
- Established container networking
|
||||||
|
|
||||||
|
** 2024-10-02: Docker Integration
|
||||||
|
- Completed Docker streaming infrastructure
|
||||||
|
- Fixed user management integration
|
||||||
|
- Created docker-compose.yml
|
||||||
|
- Established volume mounts
|
||||||
|
|
||||||
|
** 2024-10-02: Web Interface Integration
|
||||||
|
- Completed Docker streaming integration with web interface
|
||||||
|
- Connected frontend to streaming backend
|
||||||
|
- Implemented status monitoring
|
||||||
|
- Added stream metadata display
|
||||||
|
|
||||||
|
** 2024-10-02: Docker Compose V2
|
||||||
|
- Fixed Docker Compose V2 compatibility
|
||||||
|
- Updated start/stop scripts
|
||||||
|
- Modernized container orchestration
|
||||||
|
- Improved deployment process
|
||||||
|
|
||||||
|
* Phase 7: AAC Streaming (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-02: AAC Support
|
||||||
|
- Added AAC streaming support
|
||||||
|
- Implemented quality selector
|
||||||
|
- Created multiple stream formats
|
||||||
|
- Improved audio efficiency
|
||||||
|
|
||||||
|
** 2024-10-02: Icecast Configuration
|
||||||
|
- Added Icecast mount configurations for all streams
|
||||||
|
- Configured MP3 128kbps stream
|
||||||
|
- Configured AAC 96kbps stream
|
||||||
|
- Configured MP3 64kbps low-bandwidth stream
|
||||||
|
|
||||||
|
** 2024-10-02: Stream Metadata
|
||||||
|
- Restored live stream metadata display
|
||||||
|
- Fixed metadata extraction from Icecast
|
||||||
|
- Implemented real-time track info
|
||||||
|
- Added "now playing" functionality
|
||||||
|
|
||||||
|
** 2024-10-02: Documentation
|
||||||
|
- Converted AAC-STREAMING.md to org-mode format
|
||||||
|
- Updated streaming documentation
|
||||||
|
- Added multi-format stream guides
|
||||||
|
- Documented quality options
|
||||||
|
|
||||||
|
* Phase 8: Docker Refinement (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-02: Docker Configuration
|
||||||
|
- Updated Docker configuration for improved streaming
|
||||||
|
- Optimized container settings
|
||||||
|
- Improved volume management
|
||||||
|
- Enhanced networking setup
|
||||||
|
|
||||||
|
** 2024-10-02: Utility Scripts
|
||||||
|
- Restored Docker utility scripts per Fade's request
|
||||||
|
- Created start-streaming.sh
|
||||||
|
- Created stop-streaming.sh
|
||||||
|
- Added test-streaming.sh
|
||||||
|
|
||||||
|
** 2024-10-02: Gitignore Updates
|
||||||
|
- Added shell script exclusion to gitignore
|
||||||
|
- Cleaned up version control
|
||||||
|
- Removed build artifacts
|
||||||
|
- Improved repository hygiene
|
||||||
|
|
||||||
|
* Phase 9: UI Improvements (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-03: Color Scheme
|
||||||
|
- Updated color scheme from green to blue theme
|
||||||
|
- Implemented consistent color palette
|
||||||
|
- Improved visual hierarchy
|
||||||
|
- Enhanced dark theme aesthetics
|
||||||
|
|
||||||
|
** 2024-10-03: Template Features
|
||||||
|
- Completed Templates section
|
||||||
|
- Implemented CLIP refactoring
|
||||||
|
- Added user management templates
|
||||||
|
- Created pagination templates
|
||||||
|
- Built playlist templates
|
||||||
|
- Fixed UI issues
|
||||||
|
- Documented PostgreSQL setup
|
||||||
|
|
||||||
|
** 2024-10-03: Status Monitoring
|
||||||
|
- Added auto-scan on startup
|
||||||
|
- Implemented live Icecast status checks
|
||||||
|
- Added live Liquidsoap status checks
|
||||||
|
- Created admin dashboard monitoring
|
||||||
|
|
||||||
|
* Phase 10: JavaScript Modularization (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-04: Code Organization
|
||||||
|
- Moved admin JavaScript code to own file (admin.js)
|
||||||
|
- Moved frontpage JavaScript to own file
|
||||||
|
- Moved player JavaScript to own file (player.js)
|
||||||
|
- Moved users JavaScript to own file
|
||||||
|
- Improved code maintainability
|
||||||
|
|
||||||
|
** 2024-10-04: User Management Page
|
||||||
|
- Added user management page
|
||||||
|
- Created admin interface for users
|
||||||
|
- Implemented user listing
|
||||||
|
- Added role management UI
|
||||||
|
|
||||||
|
* Phase 11: Styling Improvements (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-05: LASS Fixes
|
||||||
|
- Fixed: Move font import to LASS file
|
||||||
|
- Fixed: LASS rules moved up one level
|
||||||
|
- Fixed: Pseudo selectors now working in LASS
|
||||||
|
- Improved CSS compilation
|
||||||
|
|
||||||
|
** 2024-10-05: Live Player Styling
|
||||||
|
- Fixed sizing of live player
|
||||||
|
- Improved player responsiveness
|
||||||
|
- Enhanced player controls
|
||||||
|
- Better mobile layout
|
||||||
|
|
||||||
|
** 2024-10-05: Navigation Styling
|
||||||
|
- Used nav styles on front page
|
||||||
|
- Implemented consistent navigation
|
||||||
|
- Improved menu appearance
|
||||||
|
- Enhanced user experience
|
||||||
|
|
||||||
|
* Phase 12: Playlist System (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-04: Schema Fix
|
||||||
|
- Fixed playlist schema mismatch
|
||||||
|
- Used track-ids field consistently
|
||||||
|
- Resolved data structure issues
|
||||||
|
- Improved playlist reliability
|
||||||
|
|
||||||
|
* Phase 13: User Profiles (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-06: Profile Pages
|
||||||
|
- Added user profile page with CLIP template styling
|
||||||
|
- Implemented profile edit functionality
|
||||||
|
- Updated profile page to match site-wide layout
|
||||||
|
- Created consistent styling
|
||||||
|
|
||||||
|
** 2024-10-06: Authentication UI
|
||||||
|
- Added user registration UI improvements
|
||||||
|
- Enhanced authentication interface
|
||||||
|
- Fixed auth form styling (wider 600px forms)
|
||||||
|
- Hidden message boxes for cleaner UI
|
||||||
|
|
||||||
|
* Phase 14: API Architecture (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-07: API-Aware Authentication
|
||||||
|
- WIP: Added API-aware authentication
|
||||||
|
- Implemented detection for API routes
|
||||||
|
- Fixed execution flow issues
|
||||||
|
- Completed API-aware authentication returning JSON
|
||||||
|
|
||||||
|
** 2024-10-07: API Output Refactoring
|
||||||
|
- Fixed api-output usage
|
||||||
|
- Passed structured data with :status and :message
|
||||||
|
- Standardized API responses
|
||||||
|
- Improved error handling
|
||||||
|
|
||||||
|
* Phase 15: API Refactoring (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-08: Define-API Migration
|
||||||
|
- Refactored API endpoints to use Radiance's define-api macro
|
||||||
|
- Modernized API architecture
|
||||||
|
- Improved endpoint consistency
|
||||||
|
- Better integration with Radiance framework
|
||||||
|
|
||||||
|
** 2024-10-08: Frontend Integration
|
||||||
|
- Fixed frontend JavaScript to work with define-api endpoints
|
||||||
|
- Updated AJAX calls
|
||||||
|
- Improved error handling
|
||||||
|
- Enhanced user feedback
|
||||||
|
|
||||||
|
** 2024-10-08: Automated Testing
|
||||||
|
- Added comprehensive automated test suite
|
||||||
|
- Created test-server.sh
|
||||||
|
- Implemented API endpoint testing
|
||||||
|
- Added integration tests
|
||||||
|
|
||||||
|
* Phase 16: Telnet Controls (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-08: Liquidsoap DJ Controls
|
||||||
|
- Added Liquidsoap DJ controls via telnet integration
|
||||||
|
- Implemented remote control interface
|
||||||
|
- Created telnet command system
|
||||||
|
- Enabled live stream manipulation
|
||||||
|
|
||||||
|
* Phase 17: Merge Conflicts and Integration (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-09: Track-IDs Integration
|
||||||
|
- Resolved merge conflict
|
||||||
|
- Integrated track-ids fix with api-output refactoring
|
||||||
|
- Maintained data consistency
|
||||||
|
- Preserved both feature sets
|
||||||
|
|
||||||
|
* Phase 18: Navigation Improvements (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-09: Navbar Enhancement
|
||||||
|
- Improved navbar in all pages
|
||||||
|
- Enhanced nav styling
|
||||||
|
- Created consistent navigation experience
|
||||||
|
- Better responsive behavior
|
||||||
|
|
||||||
|
* Phase 19: Documentation Updates (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-10: API Documentation
|
||||||
|
- Updated documentation authors to Asteroid Radio Development Team
|
||||||
|
- Documentation cleanup: removed outdated files
|
||||||
|
- Added API docs
|
||||||
|
- Updated core documentation
|
||||||
|
- Created API-REFERENCE.org
|
||||||
|
- Created API-ENDPOINTS.org
|
||||||
|
|
||||||
|
** 2024-10-10: Testing Documentation
|
||||||
|
- Updated TESTING.org
|
||||||
|
- Documented test suite
|
||||||
|
- Added testing examples
|
||||||
|
- Improved test coverage documentation
|
||||||
|
|
||||||
|
** 2024-10-10: Template Variables
|
||||||
|
- Made stream base URL variable in templates
|
||||||
|
- Improved configuration flexibility
|
||||||
|
- Better environment handling
|
||||||
|
|
||||||
|
* Phase 20: System Configuration (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-11: Parallel Processing
|
||||||
|
- Added dependency to run music scan in parallel
|
||||||
|
- Improved performance
|
||||||
|
- Faster library scanning
|
||||||
|
- Better resource utilization
|
||||||
|
|
||||||
|
** 2024-10-11: TODO Updates
|
||||||
|
- Updated TODO with UI items
|
||||||
|
- Tracked remaining work
|
||||||
|
- Prioritized features
|
||||||
|
|
||||||
|
** 2024-10-12: Configuration Documentation
|
||||||
|
- Added file for notes on application configuration
|
||||||
|
- Documented IRC log of Shinmera chat
|
||||||
|
- Preserved configuration discussions
|
||||||
|
- Improved setup documentation
|
||||||
|
|
||||||
|
** 2024-10-12: Code Documentation
|
||||||
|
- Added documentation string in scan-directory-for-music-recursively
|
||||||
|
- Improved code readability
|
||||||
|
- Better function documentation
|
||||||
|
|
||||||
|
* Phase 21: Page Flow System (October 2024)
|
||||||
|
|
||||||
|
** 2024-10-12: Role-Based Flow
|
||||||
|
- Implemented role-based page flow
|
||||||
|
- Created user management APIs
|
||||||
|
- Added admin/user routing
|
||||||
|
- Improved user experience
|
||||||
|
|
||||||
|
** 2024-10-12: UI Fixes
|
||||||
|
- Completed UI fixes for page flow feature
|
||||||
|
- Fixed navigation issues
|
||||||
|
- Improved page transitions
|
||||||
|
- Enhanced user feedback
|
||||||
|
|
||||||
|
** 2024-10-12: Documentation
|
||||||
|
- Marked Page Flow feature as complete in TODO
|
||||||
|
- Added session notes for page flow implementation
|
||||||
|
- Documented implementation details
|
||||||
|
|
||||||
|
** 2024-10-12: README Update
|
||||||
|
- Updated README.org file structure
|
||||||
|
- Reflected current project state
|
||||||
|
- Improved documentation accuracy
|
||||||
|
|
||||||
|
* Phase 22: Stream Queue Control (October 2025)
|
||||||
|
|
||||||
|
** 2025-10-14: Queue System Foundation
|
||||||
|
- Added stream queue control system
|
||||||
|
- Implemented in-memory queue management
|
||||||
|
- Created stream-queue.m3u generation
|
||||||
|
- Integrated with Liquidsoap
|
||||||
|
|
||||||
|
** 2025-10-14: Admin UI
|
||||||
|
- Added admin UI for stream queue management
|
||||||
|
- Created queue control interface
|
||||||
|
- Implemented drag-and-drop (planned)
|
||||||
|
- Added queue visualization
|
||||||
|
|
||||||
|
** 2025-10-14: Audio Quality Improvements
|
||||||
|
- Improved audio quality and streaming performance
|
||||||
|
- Replaced normalize() with ReplayGain
|
||||||
|
- Added crossfading (5 seconds)
|
||||||
|
- Implemented dynamic compression
|
||||||
|
- Eliminated volume pumping issues
|
||||||
|
|
||||||
|
** 2025-10-14: Player Improvements
|
||||||
|
- Improved player UI
|
||||||
|
- Reduced buffering
|
||||||
|
- Enhanced playback controls
|
||||||
|
- Better user experience
|
||||||
|
|
||||||
|
* Phase 23: UI Polish (October 2025)
|
||||||
|
|
||||||
|
** 2025-10-14: Browser Compatibility
|
||||||
|
- Fixed scrollbars only visible when required on Chrome browsers
|
||||||
|
- Improved cross-browser compatibility
|
||||||
|
- Better CSS handling
|
||||||
|
|
||||||
|
** 2025-10-14: Responsive Design
|
||||||
|
- Fixed playlist create button wrap on small screens
|
||||||
|
- Improved mobile experience
|
||||||
|
- Enhanced responsive layout
|
||||||
|
|
||||||
|
** 2025-10-14: Icecast Integration
|
||||||
|
- Fixed: avoid Icecast XML shown on frontend when there is no artist
|
||||||
|
- Improved error handling
|
||||||
|
- Better metadata display
|
||||||
|
|
||||||
|
* Phase 24: Documentation Overhaul (October 2025)
|
||||||
|
|
||||||
|
** 2025-10-16: Comprehensive Update
|
||||||
|
- Comprehensive documentation update for current features
|
||||||
|
- Updated README.org with all current capabilities
|
||||||
|
- Documented stream queue control system
|
||||||
|
- Added ReplayGain documentation
|
||||||
|
- Updated multi-format streaming docs
|
||||||
|
- Documented user management system
|
||||||
|
- Complete API endpoint reference
|
||||||
|
- Updated database schema documentation
|
||||||
|
|
||||||
|
** 2025-10-16: API Documentation
|
||||||
|
- Added complete stream queue control API section
|
||||||
|
- Documented all 7 stream queue endpoints
|
||||||
|
- Added authentication requirements
|
||||||
|
- Included request/response examples
|
||||||
|
|
||||||
|
** 2025-10-16: Docker Documentation
|
||||||
|
- Updated Liquidsoap config documentation
|
||||||
|
- Documented stream queue integration
|
||||||
|
- Added queue management examples
|
||||||
|
- Updated audio processing details
|
||||||
|
|
||||||
|
** 2025-10-16: Project Overview
|
||||||
|
- Updated PROJECT-OVERVIEW with stream queue
|
||||||
|
- Added ReplayGain mentions
|
||||||
|
- Updated feature list
|
||||||
|
- Refreshed project vision
|
||||||
|
|
||||||
|
* Technical Milestones
|
||||||
|
|
||||||
|
** Architecture Evolution
|
||||||
|
1. *Hunchentoot* → *RADIANCE* (Major framework migration)
|
||||||
|
2. *Simple HTML* → *CLIP Templates* (Dynamic templating)
|
||||||
|
3. *File-based* → *PostgreSQL Database* (Persistent storage)
|
||||||
|
4. *Single stream* → *Multi-format streaming* (AAC, MP3 high/low)
|
||||||
|
5. *Random playback* → *Queue control* (Curated broadcasting)
|
||||||
|
|
||||||
|
** Audio Processing Evolution
|
||||||
|
1. *Basic amplify* → *Normalize* → *ReplayGain* (Volume consistency)
|
||||||
|
2. *No crossfade* → *5-second crossfade* (Smooth transitions)
|
||||||
|
3. *No compression* → *Dynamic compression* (Clipping prevention)
|
||||||
|
|
||||||
|
** API Evolution
|
||||||
|
1. *Custom routes* → *define-api macro* (Standardization)
|
||||||
|
2. *Mixed responses* → *JSON API* (Consistent format)
|
||||||
|
3. *No auth* → *Session-based auth* (Security)
|
||||||
|
4. *Basic endpoints* → *20+ endpoints* (Comprehensive API)
|
||||||
|
|
||||||
|
** Infrastructure Evolution
|
||||||
|
1. *Native installation* → *Docker containers* (Easy deployment)
|
||||||
|
2. *Single Icecast* → *Icecast + Liquidsoap* (Professional streaming)
|
||||||
|
3. *No telnet* → *Telnet control* (Live DJ operations)
|
||||||
|
|
||||||
|
* Feature Summary
|
||||||
|
|
||||||
|
** Core Features Implemented
|
||||||
|
- ✅ User authentication and registration
|
||||||
|
- ✅ Role-based access control (admin/user)
|
||||||
|
- ✅ Music library management with metadata
|
||||||
|
- ✅ User playlists (create, edit, delete)
|
||||||
|
- ✅ Stream queue control (admin only)
|
||||||
|
- ✅ Multi-format streaming (AAC 96k, MP3 128k/64k)
|
||||||
|
- ✅ ReplayGain audio processing
|
||||||
|
- ✅ Crossfading and compression
|
||||||
|
- ✅ Web player with controls
|
||||||
|
- ✅ Live stream metadata display
|
||||||
|
- ✅ Admin dashboard
|
||||||
|
- ✅ REST API (20+ endpoints)
|
||||||
|
- ✅ Automated testing suite
|
||||||
|
- ✅ Docker deployment
|
||||||
|
- ✅ Telnet DJ controls
|
||||||
|
- ✅ PostgreSQL database
|
||||||
|
- ✅ Responsive design
|
||||||
|
- ✅ Dark hacker theme
|
||||||
|
|
||||||
|
** Planned Features
|
||||||
|
- 🔄 WebSocket real-time updates
|
||||||
|
- 🔄 Drag-and-drop queue management
|
||||||
|
- 🔄 Social features (playlist sharing)??
|
||||||
|
- 🔄 Advanced search and filtering
|
||||||
|
- 🔄 Listener statistics
|
||||||
|
- 🔄 Scheduled programming
|
||||||
|
- 🔄 Auto-queue filling
|
||||||
|
- 🔄 Genre-based smart queues
|
||||||
|
|
||||||
|
* Development Statistics
|
||||||
|
|
||||||
|
** Commit Count by Phase
|
||||||
|
- Phase 1-2 (Foundation): ~15 commits
|
||||||
|
- Phase 3-4 (Templates/DB): ~10 commits
|
||||||
|
- Phase 5-6 (Users/Docker): ~20 commits
|
||||||
|
- Phase 7-9 (Streaming): ~15 commits
|
||||||
|
- Phase 10-14 (UI/Profiles): ~25 commits
|
||||||
|
- Phase 15-17 (API): ~15 commits
|
||||||
|
- Phase 18-21 (Polish): ~20 commits
|
||||||
|
- Phase 22-24 (Queue/Docs): ~10 commits
|
||||||
|
|
||||||
|
** Key Contributors Statistics
|
||||||
|
- Glenn Thompson: ~70 commits (Core development, API, testing)
|
||||||
|
- Brian O'Reilly: ~40 commits (Infrastructure, architecture)
|
||||||
|
- Luis Pereira: ~20 commits (Frontend, UI/UX)
|
||||||
|
|
||||||
|
** Technology Stack
|
||||||
|
- *Language*: Common Lisp (SBCL)
|
||||||
|
- *Framework*: RADIANCE
|
||||||
|
- *Database*: PostgreSQL
|
||||||
|
- *Templating*: CLIP
|
||||||
|
- *CSS*: LASS
|
||||||
|
- *Streaming*: Icecast2 + Liquidsoap
|
||||||
|
- *Containers*: Docker + Docker Compose
|
||||||
|
- *Audio*: ReplayGain, crossfade, compression
|
||||||
|
|
||||||
|
* Lessons Learned
|
||||||
|
|
||||||
|
** Framework Migration
|
||||||
|
The migration from Hunchentoot to RADIANCE was challenging but worthwhile. RADIANCE's module system and database abstraction provided better structure for a growing application.
|
||||||
|
|
||||||
|
** Audio Processing
|
||||||
|
The evolution from normalize() to ReplayGain solved the volume pumping issue. ReplayGain uses track metadata for consistent volume without dynamic compression artifacts.
|
||||||
|
|
||||||
|
** API Design
|
||||||
|
Migrating to Radiance's define-api macro standardized our API and improved maintainability. Consistent JSON responses made frontend integration much easier.
|
||||||
|
|
||||||
|
** Docker Deployment
|
||||||
|
Containerizing the streaming infrastructure simplified deployment and made the system more portable. The separation of concerns between web app and streaming services improved reliability.
|
||||||
|
|
||||||
|
** Testing
|
||||||
|
Adding automated tests early would have caught integration issues faster. The comprehensive test suite added in Phase 15 significantly improved code quality.
|
||||||
|
|
||||||
|
* Future Directions
|
||||||
|
|
||||||
|
** Short Term (Next 3 Months?)
|
||||||
|
- WebSocket integration for real-time updates
|
||||||
|
- Drag-and-drop queue management UI
|
||||||
|
- Telnet integration from web interface
|
||||||
|
- Listener statistics dashboard
|
||||||
|
|
||||||
|
** Medium Term (6-12 Months)
|
||||||
|
- Social features (playlist sharing, discovery)
|
||||||
|
- Advanced search with full-text indexing
|
||||||
|
- Mobile native applications
|
||||||
|
- Scheduled programming system
|
||||||
|
|
||||||
|
** Long Term (12+ Months)
|
||||||
|
- Multi-station support
|
||||||
|
- Federation with other Asteroid Radio instances
|
||||||
|
- Machine learning for music recommendations
|
||||||
|
- Live DJ streaming capabilities
|
||||||
|
|
||||||
|
* Conclusion
|
||||||
|
|
||||||
|
Asteroid Radio has evolved from a simple design document into a sophisticated internet radio platform. The journey from Hunchentoot to RADIANCE, from file-based storage to PostgreSQL, from single-stream to multi-format broadcasting, and from random playback to curated queue control demonstrates the power of iterative development and continuous improvement.
|
||||||
|
|
||||||
|
The project successfully combines the elegance of Common Lisp with modern web technologies, creating a platform that's both technically impressive and user-friendly. The dark hacker aesthetic, professional audio processing, and comprehensive API make Asteroid Radio a unique contribution to the internet radio landscape.
|
||||||
|
|
||||||
|
Most importantly, Asteroid Radio achieves its core mission: providing the perfect soundtrack for developers, hackers, and anyone who spends hours deep in code.
|
||||||
|
|
||||||
|
* Appendix: Key Files
|
||||||
|
|
||||||
|
** Core Application
|
||||||
|
- =asteroid.lisp= - Main application with RADIANCE routes
|
||||||
|
- =asteroid.asd= - System definition
|
||||||
|
- =stream-control.lisp= - Queue management
|
||||||
|
- =stream-media.lisp= - Media streaming
|
||||||
|
- =user-management.lisp= - User authentication
|
||||||
|
- =playlist-management.lisp= - Playlist operations
|
||||||
|
- =auth-routes.lisp= - Authentication endpoints
|
||||||
|
|
||||||
|
** Configuration
|
||||||
|
- =docker/docker-compose.yml= - Container orchestration
|
||||||
|
- =docker/asteroid-radio-docker.liq= - Liquidsoap configuration
|
||||||
|
- =docker/icecast.xml= - Icecast server config
|
||||||
|
|
||||||
|
** Frontend
|
||||||
|
- =static/asteroid.lass= - Stylesheet source
|
||||||
|
- =static/js/admin.js= - Admin interface (289 lines)
|
||||||
|
- =static/js/player.js= - Web player
|
||||||
|
- =template/*.chtml= - CLIP templates
|
||||||
|
|
||||||
|
** Documentation
|
||||||
|
- =README.org= - Project overview
|
||||||
|
- =docs/STREAM-CONTROL.org= - Queue management guide
|
||||||
|
- =docs/API-ENDPOINTS.org= - Complete API reference
|
||||||
|
- =docs/DOCKER-STREAMING.org= - Streaming setup
|
||||||
|
- =docs/DEV-LOG.org= - This document
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*End of Development Log*
|
||||||
|
|
||||||
|
Last Updated: 2025-10-16
|
||||||
|
|
@ -6,6 +6,13 @@
|
||||||
|
|
||||||
This guide covers the complete Docker-based streaming setup for Asteroid Radio using Icecast2 and Liquidsoap containers. This approach provides a containerized, portable streaming infrastructure that's easy to deploy and maintain.
|
This guide covers the complete Docker-based streaming setup for Asteroid Radio using Icecast2 and Liquidsoap containers. This approach provides a containerized, portable streaming infrastructure that's easy to deploy and maintain.
|
||||||
|
|
||||||
|
** Key Features
|
||||||
|
- Stream queue control system for curated playlists
|
||||||
|
- ReplayGain audio processing for consistent volume
|
||||||
|
- Automatic fallback to random playback
|
||||||
|
- Multi-format streaming (AAC, MP3 high/low)
|
||||||
|
- Telnet control interface for live DJ operations
|
||||||
|
|
||||||
* Architecture
|
* Architecture
|
||||||
|
|
||||||
** Container Stack
|
** Container Stack
|
||||||
|
|
@ -18,6 +25,12 @@ This guide covers the complete Docker-based streaming setup for Asteroid Radio u
|
||||||
- *High Quality AAC*: 96kbps AAC stream at /asteroid.aac (better efficiency than MP3)
|
- *High Quality AAC*: 96kbps AAC stream at /asteroid.aac (better efficiency than MP3)
|
||||||
- *Low Quality MP3*: 64kbps MP3 stream at /asteroid-low.mp3 (compatibility)
|
- *Low Quality MP3*: 64kbps MP3 stream at /asteroid-low.mp3 (compatibility)
|
||||||
|
|
||||||
|
** Audio Processing
|
||||||
|
- *ReplayGain*: Consistent volume without pumping artifacts
|
||||||
|
- *Crossfading*: Smooth 5-second transitions between tracks
|
||||||
|
- *Compression*: Dynamic compression to prevent clipping
|
||||||
|
- *Fallback*: Emergency sine wave if all sources fail
|
||||||
|
|
||||||
** Network Configuration
|
** Network Configuration
|
||||||
- *Icecast2*: Port 8000 (streaming and admin)
|
- *Icecast2*: Port 8000 (streaming and admin)
|
||||||
- *Liquidsoap Telnet*: Port 1234 (remote control)
|
- *Liquidsoap Telnet*: Port 1234 (remote control)
|
||||||
|
|
@ -87,6 +100,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ./music:/app/music:ro
|
- ./music:/app/music:ro
|
||||||
- ./asteroid-radio-docker.liq:/app/asteroid-radio.liq:ro
|
- ./asteroid-radio-docker.liq:/app/asteroid-radio.liq:ro
|
||||||
|
- ../stream-queue.m3u:/app/stream-queue.m3u:ro # Stream queue control
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- asteroid-network
|
- asteroid-network
|
||||||
|
|
@ -208,20 +222,42 @@ settings.server.telnet.set(true)
|
||||||
settings.server.telnet.port.set(1234)
|
settings.server.telnet.port.set(1234)
|
||||||
settings.server.telnet.bind_addr.set("0.0.0.0")
|
settings.server.telnet.bind_addr.set("0.0.0.0")
|
||||||
|
|
||||||
# Create playlist source from mounted music directory
|
# Create playlist source from managed stream queue
|
||||||
radio = playlist(
|
radio = playlist(
|
||||||
mode="randomize",
|
mode="normal", # Play in order (not randomized)
|
||||||
reload=3600,
|
reload=5, # Check for playlist updates every 5 seconds
|
||||||
reload_mode="watch",
|
reload_mode="watch", # Watch file for changes
|
||||||
|
"/app/stream-queue.m3u"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Fallback to directory scan if queue is empty
|
||||||
|
radio_fallback = playlist.safe(
|
||||||
|
mode="randomize",
|
||||||
|
reload=3600,
|
||||||
"/app/music/"
|
"/app/music/"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add some audio processing
|
radio = fallback(track_sensitive=false, [radio, radio_fallback])
|
||||||
radio = amplify(1.0, radio)
|
|
||||||
radio = normalize(radio)
|
|
||||||
|
|
||||||
# Add crossfade between tracks
|
# Use ReplayGain for consistent volume without pumping
|
||||||
radio = crossfade(radio)
|
radio = amplify(1.0, override="replaygain", radio)
|
||||||
|
|
||||||
|
# Add smooth crossfade between tracks (5 seconds)
|
||||||
|
radio = crossfade(
|
||||||
|
duration=5.0,
|
||||||
|
fade_in=3.0,
|
||||||
|
fade_out=3.0,
|
||||||
|
radio
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add compressor to prevent clipping
|
||||||
|
radio = compress(
|
||||||
|
ratio=3.0,
|
||||||
|
threshold=-15.0,
|
||||||
|
attack=50.0,
|
||||||
|
release=400.0,
|
||||||
|
radio
|
||||||
|
)
|
||||||
|
|
||||||
# Create a fallback with emergency content
|
# Create a fallback with emergency content
|
||||||
emergency = sine(440.0)
|
emergency = sine(440.0)
|
||||||
|
|
@ -437,6 +473,36 @@ docker compose logs --tail=10 liquidsoap
|
||||||
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
* Stream Queue Control
|
||||||
|
|
||||||
|
** Overview
|
||||||
|
The Docker setup integrates with Asteroid's stream queue control system, allowing you to curate exactly what plays on the broadcast stream.
|
||||||
|
|
||||||
|
** How It Works
|
||||||
|
1. Asteroid web app manages =stream-queue.m3u= file in the project root
|
||||||
|
2. File is mounted into Liquidsoap container at =/app/stream-queue.m3u=
|
||||||
|
3. Liquidsoap watches the file and reloads every 5 seconds
|
||||||
|
4. When queue is empty, falls back to random playback from music directory
|
||||||
|
|
||||||
|
** Managing the Queue
|
||||||
|
Use the Asteroid web API or admin interface to control the stream queue:
|
||||||
|
|
||||||
|
#+BEGIN_SRC bash
|
||||||
|
# Add track to queue (requires admin authentication)
|
||||||
|
curl -X POST http://localhost:8080/api/asteroid/stream/queue/add \
|
||||||
|
-d "track-id=42" \
|
||||||
|
-b cookies.txt
|
||||||
|
|
||||||
|
# View current queue
|
||||||
|
curl http://localhost:8080/api/asteroid/stream/queue -b cookies.txt
|
||||||
|
|
||||||
|
# Clear queue (falls back to random)
|
||||||
|
curl -X POST http://localhost:8080/api/asteroid/stream/queue/clear \
|
||||||
|
-b cookies.txt
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
See =docs/STREAM-CONTROL.org= for complete queue management documentation.
|
||||||
|
|
||||||
* Volume Management
|
* Volume Management
|
||||||
|
|
||||||
** Music Library Setup
|
** Music Library Setup
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#+TITLE: Asteroid Radio - Project Overview
|
#+TITLE: Asteroid Radio - Project Overview
|
||||||
#+AUTHOR: Glenn Thompson & Brian O'Reilly (Fade)
|
#+AUTHOR: Glenn Thompson & Brian O'Reilly (Fade)
|
||||||
#+DATE: 2025-10-03
|
#+DATE: 2025-10-16
|
||||||
|
|
||||||
* 🎯 Mission
|
* 🎯 Mission
|
||||||
|
|
||||||
|
|
@ -79,9 +79,11 @@ Asteroid Radio is a modern, web-based music streaming platform designed for hack
|
||||||
- ✅ **User Management** - Admin interface for user administration
|
- ✅ **User Management** - Admin interface for user administration
|
||||||
- ✅ **Music Library** - Track management with pagination and search
|
- ✅ **Music Library** - Track management with pagination and search
|
||||||
- ✅ **User Playlists** - Create, manage, and play personal music collections
|
- ✅ **User Playlists** - Create, manage, and play personal music collections
|
||||||
|
- ✅ **Stream Queue Control** - Curated broadcast queue with admin controls
|
||||||
- ✅ **Web Player** - Browser-based player with queue management
|
- ✅ **Web Player** - Browser-based player with queue management
|
||||||
- ✅ **REST API** - Comprehensive JSON API with 15+ endpoints
|
- ✅ **REST API** - Comprehensive JSON API with 20+ endpoints
|
||||||
- ✅ **Music Streaming** - Multiple quality formats (MP3, AAC)
|
- ✅ **Multi-Format Streaming** - AAC 96kbps, MP3 128kbps/64kbps
|
||||||
|
- ✅ **ReplayGain Processing** - Consistent volume without pumping
|
||||||
- ✅ **Rate Limiting** - Anti-abuse protection
|
- ✅ **Rate Limiting** - Anti-abuse protection
|
||||||
- ✅ **Docker Integration** - Icecast2/Liquidsoap streaming infrastructure
|
- ✅ **Docker Integration** - Icecast2/Liquidsoap streaming infrastructure
|
||||||
- ✅ **PostgreSQL Database** - Persistent data storage
|
- ✅ **PostgreSQL Database** - Persistent data storage
|
||||||
|
|
@ -109,9 +111,10 @@ Asteroid Radio is the premier streaming platform for **Asteroid Music** - the pe
|
||||||
|
|
||||||
**Platform Features:**
|
**Platform Features:**
|
||||||
- **Multi-Format Streaming** - High-quality AAC, MP3 128k, and MP3 64k streams
|
- **Multi-Format Streaming** - High-quality AAC, MP3 128k, and MP3 64k streams
|
||||||
|
- **Stream Queue Control** - Curate exactly what plays on the broadcast
|
||||||
- **User Community** - Accounts, playlists, and sharing among fellow developers
|
- **User Community** - Accounts, playlists, and sharing among fellow developers
|
||||||
- **Developer-Friendly** - Built with Common Lisp, fully hackable and extensible
|
- **Developer-Friendly** - Built with Common Lisp, fully hackable and extensible
|
||||||
- **Professional Quality** - Crossfading, normalization, metadata, and telnet control
|
- **Professional Quality** - ReplayGain, crossfading, compression, metadata, and telnet control
|
||||||
- **Always-On Broadcasting** - Continuous streams perfect for long coding sessions
|
- **Always-On Broadcasting** - Continuous streams perfect for long coding sessions
|
||||||
|
|
||||||
Asteroid Radio isn't just another music platform - it's the soundtrack to the hacker lifestyle, designed by hackers for hackers who understand that the right music can make the difference between good code and great code.
|
Asteroid Radio isn't just another music platform - it's the soundtrack to the hacker lifestyle, designed by hackers for hackers who understand that the right music can make the difference between good code and great code.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue