KEXEL/git
0
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>