363 lines
13 KiB
Org Mode
363 lines
13 KiB
Org Mode
#+TITLE: Asteroid Radio - Internet Streaming Implementation
|
|
#+AUTHOR: Database Implementation Branch
|
|
#+DATE: 2025-09-11
|
|
|
|
* 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.
|
|
|
|
* Key Features
|
|
|
|
** Live Internet Radio Streaming
|
|
- Continuous MP3 streaming at 128kbps stereo
|
|
- Professional audio processing with crossfading and normalization
|
|
- Icecast2 streaming server integration
|
|
- Liquidsoap audio pipeline for reliable broadcasting
|
|
|
|
** Music Library Management
|
|
- Database-backed track storage with metadata extraction
|
|
- Support for MP3, FLAC, OGG, and WAV formats
|
|
- Automatic metadata extraction using taglib
|
|
- Track search, filtering, and sorting capabilities
|
|
|
|
** Web Interface
|
|
- RADIANCE framework with CLIP templating
|
|
- Admin dashboard for library management
|
|
- Web player with HTML5 audio controls
|
|
- Live stream integration with embedded player
|
|
|
|
** Network Broadcasting
|
|
- WSL-compatible networking for internal network access
|
|
- Professional streaming URLs for media players
|
|
- Multi-listener support via Icecast2
|
|
|
|
* Architecture Changes
|
|
|
|
** Framework Migration
|
|
- Migrated from Hunchentoot to RADIANCE web framework
|
|
- Implemented proper domain routing (=/asteroid/=)
|
|
- CLIP templating system for dynamic content
|
|
- Database abstraction layer for track storage
|
|
|
|
** Streaming Stack
|
|
- *Icecast2*: Streaming server (port 8000)
|
|
- *Liquidsoap*: Audio processing and streaming pipeline
|
|
- *RADIANCE*: Web server and API (port 8080)
|
|
- *Database*: Track metadata and playlist storage
|
|
|
|
** File Structure
|
|
#+BEGIN_SRC
|
|
asteroid/
|
|
├── asteroid.lisp # Main server with RADIANCE routes
|
|
├── asteroid.asd # System definition with dependencies
|
|
├── asteroid # Compiled executable binary
|
|
├── module.lisp # RADIANCE module definition
|
|
├── database.lisp # Database abstraction layer
|
|
├── auth-routes.lisp # Authentication and authorization routes
|
|
├── user-management.lisp # User management system
|
|
├── users.lisp # User utilities
|
|
├── playlist-management.lisp # Playlist creation and management
|
|
├── stream-media.lisp # Media streaming functionality
|
|
├── app-utils.lisp # Application utilities
|
|
├── template-utils.lisp # Template rendering utilities
|
|
├── build-executable.lisp # Build script for binary
|
|
├── setup-environment.lisp # Environment setup script
|
|
├── asteroid-radio.liq # Liquidsoap streaming configuration
|
|
├── playlist.m3u # Generated playlist for streaming
|
|
├── Makefile # Build automation
|
|
├── template/ # CLIP HTML templates
|
|
│ ├── front-page.chtml # Main page with live stream
|
|
│ ├── admin.chtml # Admin dashboard
|
|
│ ├── player.chtml # Web player interface
|
|
│ ├── login.chtml # User login page
|
|
│ ├── register.chtml # User registration page
|
|
│ ├── profile.chtml # User profile management
|
|
│ └── users.chtml # User management interface
|
|
├── static/ # CSS, JavaScript, and assets
|
|
│ ├── asteroid.lass # LASS stylesheet source
|
|
│ ├── asteroid.css # Compiled CSS
|
|
│ └── js/ # JavaScript modules
|
|
│ ├── admin.js # Admin panel functionality
|
|
│ ├── player.js # Audio player controls
|
|
│ ├── front-page.js # Front page interactions
|
|
│ ├── auth-ui.js # Authentication UI
|
|
│ ├── profile.js # Profile management
|
|
│ └── users.js # User management UI
|
|
├── config/ # Configuration files
|
|
│ └── radiance-postgres.lisp # PostgreSQL configuration
|
|
├── data/ # Runtime data
|
|
│ └── sessions/ # User session storage
|
|
├── docs/ # Documentation
|
|
│ ├── README.org # Documentation overview
|
|
│ ├── API-ENDPOINTS.org # API endpoint reference
|
|
│ ├── API-REFERENCE.org # Detailed API documentation
|
|
│ ├── DEVELOPMENT.org # Development guide
|
|
│ ├── INSTALLATION.org # Installation instructions
|
|
│ ├── TESTING.org # Testing documentation
|
|
│ ├── PROJECT-OVERVIEW.org # Project architecture overview
|
|
│ ├── POSTGRESQL-SETUP.org # Database setup guide
|
|
│ ├── DOCKER-STREAMING.org # Docker deployment guide
|
|
│ ├── PLAYLIST-SYSTEM.org # Playlist system documentation
|
|
│ ├── TRACK-PAGINATION-SYSTEM.org # Pagination documentation
|
|
│ └── USER-MANAGEMENT-SYSTEM.org # User system documentation
|
|
├── docker/ # Docker deployment
|
|
│ ├── docker-compose.yml # Docker Compose configuration
|
|
│ ├── Dockerfile.liquidsoap # Liquidsoap container
|
|
│ ├── asteroid-radio-docker.liq # Docker Liquidsoap config
|
|
│ ├── icecast.xml # Icecast configuration
|
|
│ ├── init-db.sql # Database initialization
|
|
│ ├── start.sh # Docker startup script
|
|
│ └── stop.sh # Docker shutdown script
|
|
├── music/ # Music library
|
|
│ ├── incoming/ # Upload staging area
|
|
│ └── library/ # Processed music files
|
|
├── test-server.sh # Server testing script
|
|
├── test-user-api.sh # User API testing script
|
|
├── run-all-tests.sh # Comprehensive test suite
|
|
├── comprehensive-performance-test.sh # Performance testing
|
|
├── analyze-performance.py # Performance analysis tool
|
|
├── simple-analysis.py # Simple analysis utilities
|
|
├── design.org # Design documentation
|
|
├── TODO.org # Project TODO list
|
|
└── project-summary.org # Project summary and status
|
|
#+END_SRC
|
|
|
|
* Track Upload Workflow
|
|
|
|
** Current Implementation (Manual Upload)
|
|
1. *Copy files to staging*: Place MP3/FLAC files in =music/incoming/=
|
|
2. *Access admin panel*: Navigate to =http://[IP]:8080/asteroid/admin=
|
|
3. *Process files*: Click "Copy Files from Incoming" button
|
|
4. *Database update*: Files are moved to =music/library/= and metadata extracted
|
|
5. *Automatic playlist*: =playlist.m3u= is regenerated for streaming
|
|
|
|
** File Processing Steps
|
|
1. Files copied from =music/incoming/= to =music/library/=
|
|
2. Metadata extracted using taglib (title, artist, album, duration, bitrate)
|
|
3. Database record created with file path and metadata
|
|
4. Playlist file updated for Liquidsoap streaming
|
|
5. Files immediately available for on-demand streaming
|
|
|
|
** Supported Formats
|
|
- *MP3*: Primary format, best compatibility
|
|
- *FLAC*: Lossless audio, high quality
|
|
- *OGG*: Open source format
|
|
- *WAV*: Uncompressed audio
|
|
|
|
* Icecast2 Integration
|
|
|
|
** Configuration
|
|
- *Server*: localhost:8000
|
|
- *Mount point*: =/asteroid.mp3=
|
|
- *Password*: =b3l0wz3r0= (configured in Liquidsoap)
|
|
- *Format*: MP3 128kbps stereo
|
|
|
|
** Installation (Ubuntu/Debian)
|
|
#+BEGIN_SRC bash
|
|
sudo apt update
|
|
sudo apt install icecast2
|
|
sudo systemctl enable icecast2
|
|
sudo systemctl start icecast2
|
|
#+END_SRC
|
|
|
|
** Stream Access
|
|
- *Direct URL*: =http://[IP]:8000/asteroid.mp3=
|
|
- *Admin interface*: =http://[IP]:8000/admin/=
|
|
- *Statistics*: =http://[IP]:8000/status.xsl=
|
|
|
|
* Liquidsoap Integration
|
|
|
|
** Configuration File: =asteroid-radio.liq=
|
|
#+BEGIN_SRC liquidsoap
|
|
#!/usr/bin/liquidsoap
|
|
|
|
# Set log level for debugging
|
|
settings.log.level := 4
|
|
|
|
# Create playlist from directory
|
|
radio = playlist(mode="randomize", reload=3600, "/path/to/music/library/")
|
|
|
|
# Add audio processing
|
|
radio = amplify(1.0, radio)
|
|
|
|
# Fallback with sine wave for debugging
|
|
radio = fallback(track_sensitive=false, [radio, sine(440.0)])
|
|
|
|
# Output to Icecast2
|
|
output.icecast(
|
|
%mp3(bitrate=128),
|
|
host="localhost",
|
|
port=8000,
|
|
password="b3l0wz3r0",
|
|
mount="asteroid.mp3",
|
|
name="Asteroid Radio",
|
|
description="Music for Hackers - Streaming from the Asteroid",
|
|
genre="Electronic/Alternative",
|
|
url="http://localhost:8080/asteroid/",
|
|
radio
|
|
)
|
|
#+END_SRC
|
|
|
|
** Installation (Ubuntu/Debian)
|
|
#+BEGIN_SRC bash
|
|
sudo apt update
|
|
sudo apt install liquidsoap
|
|
#+END_SRC
|
|
|
|
** Features
|
|
- *Random playlist*: Shuffles music library continuously
|
|
- *Auto-reload*: Playlist refreshes every hour
|
|
- *Audio processing*: Amplification and normalization
|
|
- *Fallback*: Sine tone if no music available (debugging)
|
|
- *Metadata*: Station info broadcast to listeners
|
|
|
|
* Network Access
|
|
|
|
** Local Development
|
|
- *Web Interface*: =http://localhost:8080/asteroid/=
|
|
- *Live Stream*: =http://localhost:8000/asteroid.mp3=
|
|
- *Admin Panel*: =http://localhost:8080/asteroid/admin=
|
|
|
|
** WSL Network Access
|
|
- *WSL IP*: Check with =ip addr show eth0=
|
|
- *Web Interface*: =http://[WSL-IP]:8080/asteroid/=
|
|
- *Live Stream*: =http://[WSL-IP]:8000/asteroid.mp3=
|
|
|
|
** Internal Network Broadcasting
|
|
- Services bind to all interfaces (0.0.0.0)
|
|
- Accessible from any device on local network
|
|
- Compatible with media players (VLC, iTunes, etc.)
|
|
|
|
* Usage Instructions
|
|
|
|
** Starting the Radio Station
|
|
#+BEGIN_SRC bash
|
|
# Launch all services
|
|
./start-asteroid-radio.sh
|
|
#+END_SRC
|
|
|
|
** Stopping the Radio Station
|
|
#+BEGIN_SRC bash
|
|
# Stop all services
|
|
./stop-asteroid-radio.sh
|
|
#+END_SRC
|
|
|
|
** Adding Music
|
|
1. Copy MP3/FLAC files to =music/incoming/=
|
|
2. Visit admin panel: =http://[IP]:8080/asteroid/admin=
|
|
3. Click "Copy Files from Incoming"
|
|
4. Files are processed and added to streaming playlist
|
|
|
|
** Listening to the Stream
|
|
- *Web Browser*: Visit main page for embedded player
|
|
- *Media Player*: Open =http://[IP]:8000/asteroid.mp3=
|
|
- *Mobile Apps*: Use internet radio apps with stream URL
|
|
|
|
* API Endpoints
|
|
|
|
** Track Management
|
|
- =GET /api/tracks= - List all tracks with metadata
|
|
- =GET /tracks/{id}/stream= - Stream individual track
|
|
- =POST /api/scan-library= - Scan and update music library
|
|
- =POST /api/copy-files= - Process files from incoming directory
|
|
|
|
** Player Control
|
|
- =POST /api/player/play= - Start playback
|
|
- =POST /api/player/pause= - Pause playback
|
|
- =POST /api/player/stop= - Stop playback
|
|
- =GET /api/status= - Get server status
|
|
|
|
** Search and Filter
|
|
- =GET /api/tracks?search={query}= - Search tracks
|
|
- =GET /api/tracks?sort={field}= - Sort by field
|
|
- =GET /api/tracks?artist={name}= - Filter by artist
|
|
|
|
* Database Schema
|
|
|
|
** Tracks Collection
|
|
#+BEGIN_SRC lisp
|
|
(db:create "tracks" '((title :text)
|
|
(artist :text)
|
|
(album :text)
|
|
(duration :integer)
|
|
(file-path :text)
|
|
(format :text)
|
|
(bitrate :integer)
|
|
(added-date :integer)
|
|
(play-count :integer)))
|
|
#+END_SRC
|
|
|
|
** Playlists Collection (Future)
|
|
#+BEGIN_SRC lisp
|
|
(db:create "playlists" '((name :text)
|
|
(description :text)
|
|
(created-date :integer)
|
|
(track-ids :text)))
|
|
#+END_SRC
|
|
|
|
* Dependencies
|
|
|
|
** Lisp Dependencies (asteroid.asd)
|
|
- =:radiance= - Web framework
|
|
- =:r-clip= - Templating system
|
|
- =:lass= - CSS generation
|
|
- =:cl-json= - JSON handling
|
|
- =:alexandria= - Utilities
|
|
- =:local-time= - Time handling
|
|
|
|
** System Dependencies
|
|
- =icecast2= - Streaming server
|
|
- =liquidsoap= - Audio processing
|
|
- =taglib= - Metadata extraction (via audio-streams)
|
|
|
|
* Development Notes
|
|
|
|
** RADIANCE Configuration
|
|
- Domain: "asteroid"
|
|
- Routes use =#@= syntax for URL patterns
|
|
- Database abstraction via =db:= functions
|
|
- CLIP templates with =data-text= attributes
|
|
|
|
** Database Queries
|
|
- Use quoted symbols for field names: =(:= '_id id)=
|
|
- RADIANCE returns hash tables with string keys
|
|
- Primary key is "_id" internally, "id" in JSON responses
|
|
|
|
** Streaming Considerations
|
|
- MP3 files with spaces in names require playlist.m3u approach
|
|
- Liquidsoap fallback prevents stream silence
|
|
- Icecast2 mount points must match Liquidsoap configuration
|
|
|
|
* Future Enhancements
|
|
|
|
** Planned Features
|
|
- Playlist creation and management interface
|
|
- Now-playing status tracking and display
|
|
- Direct browser file uploads with progress
|
|
- Listener statistics and analytics
|
|
- Scheduled programming and automation
|
|
|
|
** Technical Improvements
|
|
- WebSocket integration for real-time updates
|
|
- Advanced audio processing options
|
|
- Multi-bitrate streaming support
|
|
- Mobile-responsive interface enhancements
|
|
|
|
* Troubleshooting
|
|
|
|
** Common Issues
|
|
- *No audio in stream*: Check Liquidsoap logs, verify MP3 files
|
|
- *Database errors*: Ensure proper field name quoting in queries
|
|
- *Network access*: Verify WSL IP and firewall settings
|
|
- *File upload issues*: Check permissions on music directories
|
|
|
|
** Debugging
|
|
- Enable Liquidsoap debug logging: =settings.log.level := 4=
|
|
- Check Icecast admin interface for stream status
|
|
- Monitor RADIANCE logs for web server issues
|
|
- Verify database connectivity and collections
|
|
|
|
* License
|
|
|
|
This implementation maintains compatibility with the original Asteroid Radio project license while adding comprehensive streaming capabilities for internet radio broadcasting.
|