Edita código
Copiar al portapapeles
Ejecutar »
<html><head><base href="https://radiospain.app/"> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sintonizador de Radio Español</title> <style> :root { --primary-color: #ff6b6b; --secondary-color: #4ecdc4; --background-color: #1a1a2e; --text-color: #f0f0f0; } body { font-family: 'Roboto', sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: var(--background-color); color: var(--text-color); overflow-x: hidden; } .sintonizador { background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); padding: 10px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); text-align: center; max-width: 450px; width: 95%; position: relative; overflow: hidden; } .sintonizador::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 70%); animation: rotate 20s linear infinite; z-index: -1; } @keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } h1 { font-size: 36px; margin-bottom: 15px; color: var(--primary-color); text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); } .station-selector { margin-bottom: 20px; position: relative; } select { appearance: none; -webkit-appearance: none; width: 100%; padding: 15px 20px; font-size: 18px; background-color: rgba(0, 0, 0, 0.7); color: var(--text-color); border: 2px solid var(--secondary-color); border-radius: 50px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); outline: none; transition: all 0.3s ease; cursor: pointer; } select:hover, select:focus { background-color: rgba(0, 0, 0, 0.8); transform: translateY(-2px); } .station-selector::after { content: '\25BC'; position: absolute; top: 50%; right: 20px; transform: translateY(-50%); color: var(--secondary-color); pointer-events: none; } .station-info { font-size: 22px; margin-bottom: 30px; background: rgba(255, 255, 255, 0.1); padding: 20px; border-radius: 15px; box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.2); transition: all 0.3s ease; } .controls { display: flex; justify-content: space-around; margin-bottom: 30px; } .controls button { padding: 20px; font-size: 36px; /* Increased icon size */ border: none; border-radius: 50%; width: 100px; /* Increased button size */ height: 100px; /* Increased button size */ background-color: var(--primary-color); color: var(--text-color); box-shadow: 0 6px 15px rgba(0, 0, 0, 0.3); transition: all 0.3s ease; cursor: pointer; outline: none; display: flex; justify-content: center; align-items: center; } .controls button:hover { background-color: var(--secondary-color); transform: scale(1.1) rotate(5deg); } .volume-control { margin-bottom: 30px; display: flex; align-items: center; justify-content: space-between; padding: 15px; background: rgba(255, 255, 255, 0.1); border-radius: 15px; box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.2); } .volume-control input[type="range"] { width: 80%; -webkit-appearance: none; appearance: none; height: 8px; background: var(--secondary-color); border-radius: 5px; outline: none; opacity: 0.7; transition: opacity 0.3s ease; } .volume-control input[type="range"]:hover { opacity: 1; } .volume-control input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 25px; height: 25px; background: var(--primary-color); border-radius: 50%; cursor: pointer; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); transition: all 0.3s ease; } .volume-control input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.2); } .volume-control input[type="range"]::-moz-range-thumb { width: 25px; height: 25px; background: var(--primary-color); border-radius: 50%; cursor: pointer; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); transition: all 0.3s ease; } .volume-control input[type="range"]::-moz-range-thumb:hover { transform: scale(1.2); } .volume-control span { font-size: 18px; margin-right: 15px; color: var(--text-color); } .visualizer { display: flex; justify-content: center; align-items: flex-end; height: 120px; width: 100%; background: rgba(255, 255, 255, 0.1); border-radius: 15px; overflow: hidden; box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.2); } .visualizer .bar { width: 4px; margin: 0 2px; background-color: var(--secondary-color); transition: height 0.1s ease; } @keyframes pulso { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } } #play-btn.pulsing { animation: pulso 1s infinite; } .station-info.error { background-color: #e74c3c; color: #fff; } @media (max-width: 480px) { .sintonizador { padding: 20px; } h1 { font-size: 28px; } .controls button { width: 80px; height: 80px; font-size: 28px; } .station-info { font-size: 18px; } } </style> </head> <body style="overflow: hidden"> <div class="sintonizador"> <h1>Sintonizador de Radio Español</h1> <div class="station-selector"> <select id="station-select"> <option value="0">Radio Nacional de España</option> <option value="1">Cadena SER</option> <option value="2">COPE</option> <option value="3">Cadena Dial</option> <option value="4">LOS40</option> <option value="5">Radio 3</option> <option value="6">Europa radio</option> <option value="7">Radiole de la Frontera</option> <option value="8">Rà dio 5</option> <option value="9">Radio Clásica</option> </select> </div> <div class="station-info" id="station-info">No hay estación seleccionada</div> <div class="controls"> <button id="prev-btn">â®ï¸</button> <button id="play-btn">â–¶ï¸</button> <button id="next-btn">âï¸</button> </div> <div class="volume-control"> <span>Volumen</span> <input type="range" id="volume-slider" min="0" max="100" value="50"> </div> <div class="visualizer" id="visualizer"></div> </div> <script> const stationInfo = document.getElementById('station-info'); const prevBtn = document.getElementById('prev-btn'); const playBtn = document.getElementById('play-btn'); const nextBtn = document.getElementById('next-btn'); const volumeSlider = document.getElementById('volume-slider'); const visualizer = document.getElementById('visualizer'); const stationSelect = document.getElementById('station-select'); const stations = [ { name: "Radio Nacional de España", url: "https://dispatcher.rndfnk.com/crtve/rne1/main/mp3/high" }, { name: "Cadena SER", url: "https://playerservices.streamtheworld.com/api/livestream-redirect/CADENASER.mp3" }, { name: "COPE", url: "https://flucast-b02-04.flumotion.com/cope/net3.mp3" }, { name: "Cadena Dial", url: "https://playerservices.streamtheworld.com/api/livestream-redirect/CADENADIAL.mp3" }, { name: "LOS40", url: "https://playerservices.streamtheworld.com/api/livestream-redirect/LOS40.mp3" }, { name: "Radio 3", url: "https://dispatcher.rndfnk.com/crtve/rner3/main/mp3/high" }, { name: "Europa radio", url: "https://rs9.stream24.net:80/europa-park-radio.mp3" }, { name: "Radiole de la Frontera", url: "https://playerservices.streamtheworld.com/api/livestream-redirect/RADIOLE_ASO_JEREZ.mp3" }, { name: "Rà dio 5", url: "https://dispatcher.rndfnk.com/crtve/rne5/main/mp3/high" }, { name: "Radio Clásica", url: "https://dispatcher.rndfnk.com/crtve/rnerc/main/mp3/high" } ]; let currentStationIndex = 0; let isPlaying = false; let audio = new Audio(); const loadStation = (index) => { const station = stations[index]; stationInfo.textContent = station.name; audio.src = station.url; stationSelect.value = index; }; const playStation = () => { audio.play().then(() => { isPlaying = true; playBtn.textContent = 'â¸ï¸'; playBtn.classList.add('pulsing'); startVisualizer(); }).catch(error => { console.error('Error al reproducir la estación:', error); stationInfo.textContent = "Error al cargar la estación"; stationInfo.classList.add('error'); }); }; const pauseStation = () => { audio.pause(); isPlaying = false; playBtn.textContent = 'â–¶ï¸'; playBtn.classList.remove('pulsing'); stopVisualizer(); }; playBtn.addEventListener('click', () => { if (isPlaying) { pauseStation(); } else { playStation(); } }); prevBtn.addEventListener('click', () => { currentStationIndex = (currentStationIndex === 0) ? stations.length - 1 : currentStationIndex - 1; loadStation(currentStationIndex); if (isPlaying) playStation(); }); nextBtn.addEventListener('click', () => { currentStationIndex = (currentStationIndex === stations.length - 1) ? 0 : currentStationIndex + 1; loadStation(currentStationIndex); if (isPlaying) playStation(); }); volumeSlider.addEventListener('input', () => { audio.volume = volumeSlider.value / 100; }); stationSelect.addEventListener('change', () => { currentStationIndex = parseInt(stationSelect.value); loadStation(currentStationIndex); if (isPlaying) playStation(); }); // Improved Visualizer const createVisualizer = () => { for (let i = 0; i < 60; i++) { const bar = document.createElement('div'); bar.classList.add('bar'); visualizer.appendChild(bar); } }; const startVisualizer = () => { const bars = visualizer.querySelectorAll('.bar'); const animateBars = () => { bars.forEach((bar, index) => { const height = Math.sin((Date.now() + index * 50) / 500) * 50 + 50; bar.style.height = `${height}%`; bar.style.opacity = height / 100; }); if (isPlaying) { requestAnimationFrame(animateBars); } }; animateBars(); }; const stopVisualizer = () => { const bars = visualizer.querySelectorAll('.bar'); bars.forEach(bar => { bar.style.height = '0%'; bar.style.opacity = 0; }); }; createVisualizer(); loadStation(currentStationIndex); // Hover effect on buttons const buttons = document.querySelectorAll('.controls button'); buttons.forEach(button => { button.addEventListener('mouseover', () => { button.style.transform = 'scale(1.1) rotate(5deg)'; }); button.addEventListener('mouseout', () => { button.style.transform = 'scale(1) rotate(0deg)'; }); }); // Smooth transition for station info const updateStationInfo = (name) => { stationInfo.style.opacity = '0'; setTimeout(() => { stationInfo.textContent = name; stationInfo.style.opacity = '1'; }, 300); }; // Update loadStation function to use smooth transition const loadStationWithTransition = (index) => { const station = stations[index]; updateStationInfo(station.name); audio.src = station.url; stationSelect.value = index; }; // Replace all calls to loadStation with loadStationWithTransition prevBtn.addEventListener('click', () => { currentStationIndex = (currentStationIndex === 0) ? stations.length - 1 : currentStationIndex - 1; loadStationWithTransition(currentStationIndex); if (isPlaying) playStation(); }); nextBtn.addEventListener('click', () => { currentStationIndex = (currentStationIndex === stations.length - 1) ? 0 : currentStationIndex + 1; loadStationWithTransition(currentStationIndex); if (isPlaying) playStation(); }); stationSelect.addEventListener('change', () => { currentStationIndex = parseInt(stationSelect.value); loadStationWithTransition(currentStationIndex); if (isPlaying) playStation(); }); loadStationWithTransition(currentStationIndex); </script> </body> </html>
Resultado