CoolFace
Apppublic

KEXEL/git

sourceHugging Faceupdated 1mo agoView on Hugging Face
0likes
rdapp.html451 linesDownload Raw Back to root
1<!DOCTYPE html>2<html lang="pt-BR">3<head>4    <meta charset="UTF-8">5    <meta name="viewport" content="width=device-width, initial-scale=1.0">6    <title>Web Radio Player</title>7    <script src="https://cdn.tailwindcss.com"></script>8    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">9    <style>10        @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');11        12        body {13            font-family: 'Poppins', sans-serif;14            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);15            color: #fff;16            min-height: 100vh;17        }18        19        .radio-container {20            background: rgba(255, 255, 255, 0.05);21            backdrop-filter: blur(10px);22            border-radius: 20px;23            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);24            overflow: hidden;25        }26        27        .station-card {28            transition: all 0.3s ease;29            cursor: pointer;30            background: rgba(255, 255, 255, 0.03);31            border: 1px solid rgba(255, 255, 255, 0.1);32        }33        34        .station-card:hover {35            transform: translateY(-5px);36            background: rgba(255, 255, 255, 0.1);37            border-color: rgba(255, 255, 255, 0.3);38        }39        40        .station-card.active {41            background: rgba(59, 130, 246, 0.2);42            border-color: rgba(59, 130, 246, 0.5);43        }44        45        .progress-bar {46            height: 4px;47            background: rgba(255, 255, 255, 0.1);48        }49        50        .progress {51            height: 100%;52            background: linear-gradient(90deg, #3b82f6 0%, #8b5cf6 100%);53            width: 0%;54            transition: width 0.1s linear;55        }56        57        .volume-slider::-webkit-slider-thumb {58            -webkit-appearance: none;59            width: 15px;60            height: 15px;61            border-radius: 50%;62            background: #fff;63            cursor: pointer;64        }65        66        .now-playing-artwork {67            animation: rotate 20s linear infinite;68            animation-play-state: paused;69        }70        71        .now-playing-artwork.playing {72            animation-play-state: running;73        }74        75        @keyframes rotate {76            from { transform: rotate(0deg); }77            to { transform: rotate(360deg); }78        }79        80        .equalizer {81            display: flex;82            align-items: flex-end;83            height: 30px;84            gap: 3px;85        }86        87        .equalizer-bar {88            width: 4px;89            background: #3b82f6;90            border-radius: 2px;91            animation: equalize 1.5s infinite ease-in-out;92        }93        94        .equalizer-bar:nth-child(1) { animation-delay: 0.1s; height: 60%; }95        .equalizer-bar:nth-child(2) { animation-delay: 0.3s; height: 30%; }96        .equalizer-bar:nth-child(3) { animation-delay: 0.5s; height: 75%; }97        .equalizer-bar:nth-child(4) { animation-delay: 0.2s; height: 40%; }98        .equalizer-bar:nth-child(5) { animation-delay: 0.4s; height: 65%; }99        100        @keyframes equalize {101            0%, 100% { transform: scaleY(1); }102            50% { transform: scaleY(1.5); }103        }104    </style>105</head>106<body class="flex items-center justify-center p-4">107    <div class="radio-container w-full max-w-4xl">108        <!-- Header -->109        <div class="p-6 bg-gradient-to-r from-blue-600 to-purple-600 flex justify-between items-center">110            <div>111                <h1 class="text-2xl font-bold">Web Radio Player</h1>112                <p class="text-sm opacity-80">Escolha sua estação favorita</p>113            </div>114            <div class="flex items-center space-x-2">115                <div class="equalizer hidden" id="equalizer">116                    <div class="equalizer-bar"></div>117                    <div class="equalizer-bar"></div>118                    <div class="equalizer-bar"></div>119                    <div class="equalizer-bar"></div>120                    <div class="equalizer-bar"></div>121                </div>122                <span class="text-sm" id="current-time">00:00</span>123            </div>124        </div>125        126        <!-- Main Content -->127        <div class="grid grid-cols-1 md:grid-cols-3 gap-0">128            <!-- Station List -->129            <div class="p-4 md:col-span-1 bg-gray-900 bg-opacity-50 overflow-y-auto max-h-[500px]">130                <div class="mb-4 relative">131                    <input type="text" placeholder="Buscar rádio..." class="w-full bg-gray-800 bg-opacity-50 border border-gray-700 rounded-lg px-4 py-2 text-white focus:outline-none focus:ring-2 focus:ring-blue-500">132                    <i class="fas fa-search absolute right-3 top-3 text-gray-400"></i>133                </div>134                135                <h3 class="font-medium text-gray-300 mb-3">Categorias</h3>136                <div class="flex flex-wrap gap-2 mb-4">137                    <span class="px-3 py-1 bg-blue-600 bg-opacity-30 rounded-full text-xs cursor-pointer hover:bg-opacity-50">Todas</span>138                    <span class="px-3 py-1 bg-gray-700 rounded-full text-xs cursor-pointer hover:bg-gray-600">Pop</span>139                    <span class="px-3 py-1 bg-gray-700 rounded-full text-xs cursor-pointer hover:bg-gray-600">Rock</span>140                    <span class="px-3 py-1 bg-gray-700 rounded-full text-xs cursor-pointer hover:bg-gray-600">Eletrônica</span>141                    <span class="px-3 py-1 bg-gray-700 rounded-full text-xs cursor-pointer hover:bg-gray-600">Jazz</span>142                </div>143                144                <h3 class="font-medium text-gray-300 mb-3">Estações</h3>145                <div class="space-y-2" id="station-list">146                    <!-- Stations will be added here by JavaScript -->147                </div>148            </div>149            150            <!-- Now Playing -->151            <div class="p-6 md:col-span-2 flex flex-col bg-gray-900 bg-opacity-30">152                <div class="flex flex-col md:flex-row items-center mb-6">153                    <div class="relative mb-4 md:mb-0 md:mr-6">154                        <div class="now-playing-artwork w-40 h-40 rounded-full overflow-hidden border-4 border-white border-opacity-10">155                            <img src="https://source.unsplash.com/random/400x400/?music" alt="Album Art" class="w-full h-full object-cover" id="station-artwork">156                        </div>157                        <div class="absolute -bottom-2 -right-2 bg-blue-600 rounded-full p-2 shadow-lg">158                            <i class="fas fa-music text-white"></i>159                        </div>160                    </div>161                    162                    <div class="text-center md:text-left">163                        <h2 class="text-xl font-bold" id="station-name">Selecione uma estação</h2>164                        <p class="text-gray-300 mb-2" id="station-genre">Gênero</p>165                        <p class="text-sm text-gray-400" id="current-song">Nenhuma música tocando</p>166                    </div>167                </div>168                169                <!-- Progress Bar -->170                <div class="progress-bar mb-4 rounded-full">171                    <div class="progress rounded-full" id="progress-bar"></div>172                </div>173                174                <!-- Controls -->175                <div class="flex justify-between items-center mb-6">176                    <button class="text-gray-400 hover:text-white" id="btn-shuffle">177                        <i class="fas fa-random"></i>178                    </button>179                    180                    <button class="text-gray-400 hover:text-white" id="btn-prev">181                        <i class="fas fa-step-backward text-2xl"></i>182                    </button>183                    184                    <button class="bg-blue-600 hover:bg-blue-700 rounded-full w-12 h-12 flex items-center justify-center text-white" id="btn-play">185                        <i class="fas fa-play"></i>186                    </button>187                    188                    <button class="text-gray-400 hover:text-white" id="btn-next">189                        <i class="fas fa-step-forward text-2xl"></i>190                    </button>191                    192                    <button class="text-gray-400 hover:text-white" id="btn-repeat">193                        <i class="fas fa-redo"></i>194                    </button>195                </div>196                197                <!-- Volume Control -->198                <div class="flex items-center">199                    <i class="fas fa-volume-down text-gray-400 mr-2"></i>200                    <input type="range" min="0" max="100" value="70" class="volume-slider w-full h-1 bg-gray-700 rounded-lg appearance-none cursor-pointer" id="volume-control">201                    <i class="fas fa-volume-up text-gray-400 ml-2"></i>202                </div>203            </div>204        </div>205        206        <!-- Footer -->207        <div class="p-4 bg-gray-900 bg-opacity-50 text-center text-sm text-gray-400">208            Web Radio Player © 2025 - Todos os direitos reservados209        </div>210    </div>211 212    <script>213        // Sample radio stations data214        const stations = [215            {216                id: 1,217                name: "Radio Pop Hits",218                genre: "Pop",219                url: "https://stream.laut.fm/pophits",220                image: "https://source.unsplash.com/random/300x300/?pop,music",221                currentSong: "Dua Lipa - Don't Start Now"222            },223            {224                id: 2,225                name: "Rock FM",226                genre: "Rock",227                url: "https://stream.laut.fm/rockfm",228                image: "https://source.unsplash.com/random/300x300/?rock,music",229                currentSong: "Foo Fighters - Everlong"230            },231            {232                id: 3,233                name: "Jazz Lounge",234                genre: "Jazz",235                url: "https://stream.laut.fm/jazzlounge",236                image: "https://source.unsplash.com/random/300x300/?jazz,music",237                currentSong: "Miles Davis - So What"238            },239            {240                id: 4,241                name: "EDM Festival",242                genre: "Eletrônica",243                url: "https://stream.laut.fm/edmfestival",244                image: "https://source.unsplash.com/random/300x300/?electronic,music",245                currentSong: "Swedish House Mafia - Don't You Worry Child"246            },247            {248                id: 5,249                name: "Classical Radio",250                genre: "Clássica",251                url: "https://stream.laut.fm/classicalradio",252                image: "https://source.unsplash.com/random/300x300/?classical,music",253                currentSong: "Beethoven - Symphony No. 5"254            },255            {256                id: 6,257                name: "Hip Hop Nation",258                genre: "Hip Hop",259                url: "https://stream.laut.fm/hiphopnation",260                image: "https://source.unsplash.com/random/300x300/?hiphop,music",261                currentSong: "Kendrick Lamar - HUMBLE."262            }263        ];264 265        // DOM Elements266        const stationList = document.getElementById('station-list');267        const stationName = document.getElementById('station-name');268        const stationGenre = document.getElementById('station-genre');269        const currentSong = document.getElementById('current-song');270        const stationArtwork = document.getElementById('station-artwork');271        const btnPlay = document.getElementById('btn-play');272        const btnPrev = document.getElementById('btn-prev');273        const btnNext = document.getElementById('btn-next');274        const btnShuffle = document.getElementById('btn-shuffle');275        const btnRepeat = document.getElementById('btn-repeat');276        const volumeControl = document.getElementById('volume-control');277        const progressBar = document.getElementById('progress-bar');278        const equalizer = document.getElementById('equalizer');279        const currentTime = document.getElementById('current-time');280 281        // Audio context282        const audio = new Audio();283        let isPlaying = false;284        let currentStationIndex = 0;285        let progressInterval;286        let updateTimeInterval;287 288        // Initialize the app289        function init() {290            renderStations();291            setupEventListeners();292        }293 294        // Render stations list295        function renderStations() {296            stationList.innerHTML = '';297            stations.forEach((station, index) => {298                const stationElement = document.createElement('div');299                stationElement.className = 'station-card p-3 rounded-lg';300                stationElement.innerHTML = `301                    <div class="flex items-center">302                        <img src="${station.image}" alt="${station.name}" class="w-12 h-12 rounded-lg object-cover mr-3">303                        <div>304                            <h4 class="font-medium">${station.name}</h4>305                            <p class="text-xs text-gray-400">${station.genre}</p>306                        </div>307                    </div>308                `;309                stationElement.addEventListener('click', () => selectStation(index));310                stationList.appendChild(stationElement);311            });312        }313 314        // Select a station315        function selectStation(index) {316            // Update UI317            const stationCards = document.querySelectorAll('.station-card');318            stationCards.forEach(card => card.classList.remove('active'));319            stationCards[index].classList.add('active');320            321            // Update current station322            currentStationIndex = index;323            const station = stations[index];324            325            // Update now playing info326            stationName.textContent = station.name;327            stationGenre.textContent = station.genre;328            currentSong.textContent = station.currentSong;329            stationArtwork.src = station.image;330            331            // Load and play the station332            audio.src = station.url;333            playStation();334        }335 336        // Play the selected station337        function playStation() {338            audio.play()339                .then(() => {340                    isPlaying = true;341                    btnPlay.innerHTML = '<i class="fas fa-pause"></i>';342                    document.querySelector('.now-playing-artwork').classList.add('playing');343                    equalizer.classList.remove('hidden');344                    345                    // Start progress bar and time updates346                    startProgressUpdate();347                    startTimeUpdate();348                })349                .catch(error => {350                    console.error('Error playing audio:', error);351                    alert('Erro ao reproduzir a estação. Verifique sua conexão ou tente outra estação.');352                });353        }354 355        // Pause the current station356        function pauseStation() {357            audio.pause();358            isPlaying = false;359            btnPlay.innerHTML = '<i class="fas fa-play"></i>';360            document.querySelector('.now-playing-artwork').classList.remove('playing');361            equalizer.classList.add('hidden');362            363            // Stop progress updates364            stopProgressUpdate();365            stopTimeUpdate();366        }367 368        // Toggle play/pause369        function togglePlayPause() {370            if (isPlaying) {371                pauseStation();372            } else {373                if (audio.src) {374                    playStation();375                } else {376                    // If no station is selected, select the first one377                    selectStation(0);378                }379            }380        }381 382        // Play next station383        function playNext() {384            const nextIndex = (currentStationIndex + 1) % stations.length;385            selectStation(nextIndex);386        }387 388        // Play previous station389        function playPrev() {390            const prevIndex = (currentStationIndex - 1 + stations.length) % stations.length;391            selectStation(prevIndex);392        }393 394        // Update progress bar395        function startProgressUpdate() {396            // For live streams, we'll simulate progress397            let progress = 0;398            progressInterval = setInterval(() => {399                progress = (progress + 0.5) % 100;400                progressBar.style.width = `${progress}%`;401            }, 1000);402        }403 404        function stopProgressUpdate() {405            clearInterval(progressInterval);406        }407 408        // Update current time409        function startTimeUpdate() {410            let seconds = 0;411            updateTimeInterval = setInterval(() => {412                seconds++;413                const mins = Math.floor(seconds / 60);414                const secs = seconds % 60;415                currentTime.textContent = `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;416            }, 1000);417        }418 419        function stopTimeUpdate() {420            clearInterval(updateTimeInterval);421        }422 423        // Setup event listeners424        function setupEventListeners() {425            btnPlay.addEventListener('click', togglePlayPause);426            btnNext.addEventListener('click', playNext);427            btnPrev.addEventListener('click', playPrev);428            429            // Volume control430            volumeControl.addEventListener('input', () => {431                audio.volume = volumeControl.value / 100;432            });433            434            // Shuffle and repeat buttons435            btnShuffle.addEventListener('click', () => {436                btnShuffle.classList.toggle('text-blue-400');437            });438            439            btnRepeat.addEventListener('click', () => {440                btnRepeat.classList.toggle('text-blue-400');441            });442            443            // Select first station by default444            selectStation(0);445        }446 447        // Initialize the app when DOM is loaded448        document.addEventListener('DOMContentLoaded', init);449    </script>450</body>451</html>