A self-hosted, full-stack internet radio player with user accounts, audio visualizations, and a Glassmorphism UI.
π΄ Live Demo β radio.djay.ca
[!NOTE] The live demo uses a Cloudflare Worker proxy (
api.djay.ca) to tunnel legacy HTTP streams over HTTPS and extract real-time ICY metadata without browser security warnings.
| Feature | Description |
|---|---|
| 7 VU Meter Styles | Classic Bars, LED, Circular, Waveform, Spectrum, Retro Needle, Neon Glow |
| Live Metadata | Real-time "Now Playing" track & artist info via ICY metadata polling |
| Media Keys | OS lock screen integration + hardware Play/Pause/Next/Prev support |
| Pop-out Player | Compact floating window β syncs background, station list, and filters from the main player. Auto-starts playback. |
| Streaming Proxy | Routes http:// streams through a secure proxy, eliminating Mixed Content warnings |
| Feature | Description |
|---|---|
| AJAX Auth | Login/register/logout without stopping playback or reloading the page |
| Cloud Favorites | Favorites and custom stations sync to your account via the PHP/MySQL backend |
| Custom Backgrounds | Set any image URL as your wallpaper or choose from curated presets |
| Light & Dark Themes | Auto-detects system preference; manually toggleable |
| Genre & Favorites Filter | Filter your station list by genre or show favorites only β persists across sessions |
| Feature | Description |
|---|---|
| Radio Browser API | Search 30,000+ community-driven stations by name, tag, or country |
| Custom Stations | Add and manage your own private stream URLs |
| Add to Favorites | One-click add from search results to your personal library |
| Feature | Description |
|---|---|
| User Management | Edit roles, toggle premium status, ban or delete users |
| Site Config | Manage Google Tag (GA4), AdSense ID, and custom head scripts from a UI |
| Premium Tier | Mark users as premium to suppress ads server-side |
| Role-Based Ads | AdSense automatically disabled for admin and is_premium users β no refresh required |
Browser (Vanilla JS + Web Audio API)
β
βββ player.js β Core player state, playback engine, pub/sub StateManager
βββ settings.js β Auth modals, user settings, favorites, genre filters
βββ visualizer.js β 7 VU meter styles via Web Audio API AnalyserNode
βββ api.js β Fetch wrappers for all PHP API endpoints
β
βΌ
PHP / MySQL Backend (LAMP/LEMP)
β
βββ index.php β Entry point; injects session data, ad scripts, user role
βββ popout.php β Pop-out entry point; same server-side ad injection pattern
βββ api/auth.php β AJAX login / logout / session management
βββ api/favorites.php β User favorites CRUD
βββ api/stations.php β Default & custom station management
βββ api/admin/ β Admin-only endpoints (users, settings)
βββ database/schema.sql β Full MySQL schema
β
βΌ
Cloudflare Worker (api.djay.ca) β optional, for demo/HTTPS deployment
βββ Audio proxy β Tunnels http:// streams over HTTPS
βββ ICY metadata β Extracts Now Playing info from stream headers
| Layer | Technology |
|---|---|
| Backend | PHP 8.x, PDO/MySQL |
| Database | MySQL 5.7+ / MariaDB |
| Frontend | Vanilla JavaScript (ES6+), HTML5, CSS3 |
| Audio | Web Audio API (AnalyserNode, GainNode) |
| Auth | PHP Sessions + AJAX (no JWT, no framework) |
| Proxy | Cloudflare Workers (optional, for demo) |
| Directory | Radio Browser API |
- PHP 8.0+
- MySQL 5.7+ or MariaDB
- A standard LAMP / LEMP web server (Apache or Nginx)
- cPanel-compatible hosting or a VPS β this is a standard PHP project, no Composer/Node required
1. Clone the repository
git clone https://github.com/BrainAV/Radio-Stream-Player-PHP.git .2. Database
# Create a MySQL database and user, then import the schema:
mysql -u youruser -p yourdb < database/schema.sql3. Configure credentials
Copy and edit the config file:
cp api/config.example.php api/config.phpThen set your DB host, name, username, and password in api/config.php.
4. Deploy
Upload to your web root. index.php is the entry point β no .htaccess rewrites required for basic usage.
5. First-time Admin Setup
After deploying, register a user account, then manually set role = 'admin' in the users table:
UPDATE users SET role = 'admin' WHERE user_email = 'you@example.com';Then access the Admin Dashboard at /admin.php.
Run the migration script to add monetization tables:
source database/update_v2.2_monetization.sqlTo test the frontend UI only:
python -m http.server 8000
# Then open http://localhost:8000Account features, favorites, and admin require a live PHP/MySQL environment.
Radio-Stream-Player-PHP/
βββ index.php # Main entry point (serves template-player.html with session data)
βββ popout.php # Pop-out window entry point
βββ admin.php # Admin dashboard entry point
βββ template-player.html # Main player HTML template
βββ popout.html # Pop-out player HTML
βββ styles.css # All styles β Glassmorphism design system
β
βββ player.js # Core player: audio engine, StateManager, media keys
βββ settings.js # Settings modal: auth, favorites, custom stations, filters
βββ visualizer.js # Web Audio API VU meter (7 styles)
βββ api.js # Frontend fetch wrappers
βββ admin.js # Admin dashboard logic
βββ popout-script.js # Pop-out player logic
β
βββ api/
β βββ config.php # DB credentials (not committed β add to .gitignore)
β βββ auth.php # Login/logout AJAX handler
β βββ favorites.php # Favorites CRUD
β βββ stations.php # Station management
β βββ register.php # User registration
β βββ admin/
β βββ users.php # Admin: user management
β βββ settings.php # Admin: site config (GA4, AdSense, custom scripts)
β
βββ database/
β βββ schema.sql # Full MySQL schema (fresh install)
β βββ update_v2.2_monetization.sql # Migration: adds is_premium, site_config table
β
βββ docs/
βββ DEVELOPER_GUIDE.md # Architecture & contribution guide
βββ RELEASE_v2.2.0.md # Release notes
βββ UNSPLASH_GUIDE.md # Background image formatting guide
| Key | Action |
|---|---|
Space / Play/Pause Media Key |
Toggle playback |
Next Track Media Key |
Next station |
Prev Track Media Key |
Previous station |
Tab |
Navigate all controls |
See CHANGELOG.md for the full version history.
Latest: v2.2.0 β Monetization & Pop-out Evolution
Issues and PRs are welcome. For significant changes, please open an issue first to discuss the approach.