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/dashboard/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/gositeme/domains/soundstudiopro.com/public_html/radio/dashboard/live_stream.php
<?php
/**
 * Live Stream Management Dashboard
 */

session_start();
require_once __DIR__ . '/../../config/database.php';
require_once __DIR__ . '/../includes/functions.php';

// Check if station is logged in
if (!isset($_SESSION['radio_station_id'])) {
    header('Location: /radio/login.php');
    exit;
}

$station_id = $_SESSION['radio_station_id'];
$station = getRadioStation($station_id);

if (!$station) {
    session_destroy();
    header('Location: /radio/login.php');
    exit;
}

$pdo = getDBConnection();

// Get stream status
$stmt = $pdo->prepare("
    SELECT rs.*, 
           (SELECT COUNT(*) FROM radio_listeners WHERE stream_id = rs.id AND disconnected_at IS NULL) as current_listeners
    FROM radio_streams rs
    WHERE rs.station_id = ?
    ORDER BY rs.started_at DESC
    LIMIT 1
");
$stmt->execute([$station_id]);
$stream = $stmt->fetch();

// Get current track
$now_playing = null;
if ($stream) {
    $stmt = $pdo->prepare("
        SELECT np.*, mt.title, mt.audio_url, mt.image_url, mt.duration,
               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
        ORDER BY np.started_at DESC
        LIMIT 1
    ");
    $stmt->execute([$stream['id']]);
    $now_playing = $stmt->fetch();
}

// Get queue
$queue = [];
if ($stream) {
    $stmt = $pdo->prepare("
        SELECT q.*, mt.title, mt.audio_url, mt.image_url,
               u.name as artist_name
        FROM radio_stream_queue q
        JOIN music_tracks mt ON q.track_id = mt.id
        LEFT JOIN users u ON mt.user_id = u.id
        WHERE q.stream_id = ? AND q.played_at IS NULL
        ORDER BY q.priority DESC, q.vote_count DESC, q.queued_at ASC
        LIMIT 20
    ");
    $stmt->execute([$stream['id']]);
    $queue = $stmt->fetchAll();
}

$page_title = 'Live Stream Management - ' . htmlspecialchars($station['station_name']);
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?= $page_title ?></title>
    <link rel="stylesheet" href="/assets/css/main.css">
    <style>
        .live-stream-dashboard {
            max-width: 1400px;
            margin: 2rem auto;
            padding: 2rem;
        }
        .stream-controls {
            background: white;
            padding: 2rem;
            border-radius: 12px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin-bottom: 2rem;
        }
        .stream-status {
            display: flex;
            align-items: center;
            gap: 1rem;
            margin-bottom: 1.5rem;
        }
        .status-indicator {
            width: 16px;
            height: 16px;
            border-radius: 50%;
            background: #ef4444;
            animation: pulse 2s ease-in-out infinite;
        }
        .status-indicator.offline {
            background: #9ca3af;
            animation: none;
        }
        @keyframes pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.5; }
        }
        .control-buttons {
            display: flex;
            gap: 1rem;
            margin-top: 1.5rem;
        }
        .btn {
            padding: 0.75rem 1.5rem;
            border: none;
            border-radius: 8px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s;
        }
        .btn-primary {
            background: #667eea;
            color: white;
        }
        .btn-primary:hover {
            background: #5568d3;
        }
        .btn-danger {
            background: #ef4444;
            color: white;
        }
        .btn-danger:hover {
            background: #dc2626;
        }
        .btn-secondary {
            background: #6b7280;
            color: white;
        }
        .now-playing-section {
            background: white;
            padding: 2rem;
            border-radius: 12px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin-bottom: 2rem;
        }
        .now-playing-card {
            display: flex;
            align-items: center;
            gap: 2rem;
        }
        .track-artwork {
            width: 150px;
            height: 150px;
            border-radius: 12px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            overflow: hidden;
        }
        .track-artwork img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        .queue-section {
            background: white;
            padding: 2rem;
            border-radius: 12px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .queue-item {
            display: flex;
            align-items: center;
            gap: 1rem;
            padding: 1rem;
            border-bottom: 1px solid #eee;
        }
        .queue-item:last-child {
            border-bottom: none;
        }
        .queue-item-artwork {
            width: 60px;
            height: 60px;
            border-radius: 8px;
            background: #f3f4f6;
            overflow: hidden;
        }
        .queue-item-artwork img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        .queue-item-info {
            flex: 1;
        }
        .queue-item-title {
            font-weight: 600;
            margin-bottom: 0.25rem;
        }
        .queue-item-artist {
            font-size: 0.9rem;
            color: #6b7280;
        }
        .queue-item-votes {
            color: #667eea;
            font-weight: 600;
        }
        .form-group {
            margin-bottom: 1rem;
        }
        .form-group label {
            display: block;
            margin-bottom: 0.5rem;
            font-weight: 600;
        }
        .form-group input {
            width: 100%;
            padding: 0.75rem;
            border: 1px solid #ddd;
            border-radius: 8px;
            font-size: 1rem;
        }
    </style>
</head>
<body>
    <?php include __DIR__ . '/../../includes/header.php'; ?>
    
    <div class="live-stream-dashboard">
        <div style="margin-bottom: 2rem;">
            <a href="/radio/dashboard/" style="color: #667eea; text-decoration: none;">← Back to Dashboard</a>
        </div>
        
        <h1 style="margin-bottom: 2rem;">Live Stream Management</h1>
        
        <div class="stream-controls">
            <div class="stream-status">
                <div class="status-indicator <?= ($stream && $stream['is_live']) ? '' : 'offline' ?>"></div>
                <div>
                    <h2 style="margin: 0;">
                        <?= ($stream && $stream['is_live']) ? 'Stream is LIVE' : 'Stream is OFFLINE' ?>
                    </h2>
                    <?php if ($stream && $stream['is_live']): ?>
                        <p style="margin: 0.5rem 0 0 0; color: #6b7280;">
                            <?= number_format($stream['current_listeners']) ?> listeners
                            <?php if ($stream['started_at']): ?>
                                • Started <?= date('M j, Y g:i A', strtotime($stream['started_at'])) ?>
                            <?php endif; ?>
                        </p>
                    <?php endif; ?>
                </div>
            </div>
            
            <?php if (!$stream || !$stream['is_live']): ?>
                <form id="start-stream-form">
                    <div class="form-group">
                        <label>Stream Name</label>
                        <input type="text" name="stream_name" value="<?= htmlspecialchars($station['station_name']) ?> Live Stream" required>
                    </div>
                    <div class="form-group">
                        <label>Stream URL (optional)</label>
                        <input type="url" name="stream_url" placeholder="https://your-stream-server.com/stream">
                    </div>
                    <div class="control-buttons">
                        <button type="submit" class="btn btn-primary">Start Stream</button>
                    </div>
                </form>
            <?php else: ?>
                <div class="control-buttons">
                    <button onclick="stopStream()" class="btn btn-danger">Stop Stream</button>
                    <a href="/radio/live.php?station=<?= $station_id ?>" target="_blank" class="btn btn-secondary">View Live Player</a>
                </div>
            <?php endif; ?>
        </div>
        
        <?php if ($stream && $stream['is_live'] && $now_playing): ?>
            <div class="now-playing-section">
                <h2>Now Playing</h2>
                <div class="now-playing-card">
                    <div class="track-artwork">
                        <?php if ($now_playing['image_url']): ?>
                            <img src="<?= htmlspecialchars($now_playing['image_url']) ?>" alt="<?= htmlspecialchars($now_playing['title']) ?>">
                        <?php else: ?>
                            <div style="display: flex; align-items: center; justify-content: center; height: 100%; font-size: 3rem;">🎵</div>
                        <?php endif; ?>
                    </div>
                    <div style="flex: 1;">
                        <h3 style="margin: 0 0 0.5rem 0;"><?= htmlspecialchars($now_playing['title']) ?></h3>
                        <p style="margin: 0; color: #6b7280;"><?= htmlspecialchars($now_playing['artist_name'] ?? 'Unknown Artist') ?></p>
                        <p style="margin: 0.5rem 0 0 0; color: #6b7280; font-size: 0.9rem;">
                            Started <?= date('g:i A', strtotime($now_playing['started_at'])) ?>
                        </p>
                    </div>
                </div>
            </div>
        <?php endif; ?>
        
        <?php if ($stream && $stream['is_live'] && count($queue) > 0): ?>
            <div class="queue-section">
                <h2>Queue (<?= count($queue) ?> tracks)</h2>
                <?php foreach ($queue as $item): ?>
                    <div class="queue-item">
                        <div class="queue-item-artwork">
                            <?php if ($item['image_url']): ?>
                                <img src="<?= htmlspecialchars($item['image_url']) ?>" alt="<?= htmlspecialchars($item['title']) ?>">
                            <?php else: ?>
                                <div style="display: flex; align-items: center; justify-content: center; height: 100%;">🎵</div>
                            <?php endif; ?>
                        </div>
                        <div class="queue-item-info">
                            <div class="queue-item-title"><?= htmlspecialchars($item['title']) ?></div>
                            <div class="queue-item-artist"><?= htmlspecialchars($item['artist_name'] ?? 'Unknown Artist') ?></div>
                        </div>
                        <div class="queue-item-votes"><?= $item['vote_count'] ?> votes</div>
                        <button onclick="playTrack(<?= $item['track_id'] ?>)" class="btn btn-primary" style="padding: 0.5rem 1rem;">Play Now</button>
                    </div>
                <?php endforeach; ?>
            </div>
        <?php endif; ?>
    </div>
    
    <script>
        const apiKey = '<?= htmlspecialchars($station['api_key'] ?? '') ?>';
        const apiSecret = '<?= htmlspecialchars($station['api_secret'] ?? '') ?>';
        
        // Start stream
        document.getElementById('start-stream-form')?.addEventListener('submit', async (e) => {
            e.preventDefault();
            const formData = new FormData(e.target);
            const data = Object.fromEntries(formData);
            
            try {
                const response = await fetch('/radio/api/v1/stream/start', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': 'Bearer ' + apiKey
                    },
                    body: JSON.stringify(data)
                });
                
                const result = await response.json();
                if (result.success) {
                    location.reload();
                } else {
                    alert(result.error || 'Failed to start stream');
                }
            } catch (error) {
                console.error('Error:', error);
                alert('Failed to start stream');
            }
        });
        
        // Stop stream
        async function stopStream() {
            if (!confirm('Are you sure you want to stop the stream?')) return;
            
            try {
                const response = await fetch('/radio/api/v1/stream/stop', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': 'Bearer ' + apiKey
                    }
                });
                
                const result = await response.json();
                if (result.success) {
                    location.reload();
                } else {
                    alert(result.error || 'Failed to stop stream');
                }
            } catch (error) {
                console.error('Error:', error);
                alert('Failed to stop stream');
            }
        }
        
        // Play track now
        async function playTrack(trackId) {
            try {
                const response = await fetch('/radio/api/v1/stream/now_playing', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': 'Bearer ' + apiKey
                    },
                    body: JSON.stringify({ track_id: trackId })
                });
                
                const result = await response.json();
                if (result.success) {
                    location.reload();
                } else {
                    alert(result.error || 'Failed to play track');
                }
            } catch (error) {
                console.error('Error:', error);
                alert('Failed to play track');
            }
        }
    </script>
    
    <?php include __DIR__ . '/../../includes/footer.php'; ?>
</body>
</html>


CasperSecurity Mini