Spaces:
Running
Running
<html lang="es"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Reproductor Video/Audio</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
.switch { | |
position: relative; | |
display: inline-block; | |
width: 60px; | |
height: 34px; | |
} | |
.switch input { | |
opacity: 0; | |
width: 0; | |
height: 0; | |
} | |
.slider { | |
position: absolute; | |
cursor: pointer; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
background-color: #4f46e5; | |
transition: .4s; | |
border-radius: 34px; | |
} | |
.slider:before { | |
position: absolute; | |
content: ""; | |
height: 26px; | |
width: 26px; | |
left: 4px; | |
bottom: 4px; | |
background-color: white; | |
transition: .4s; | |
border-radius: 50%; | |
} | |
input:checked + .slider { | |
background-color: #10b981; | |
} | |
input:checked + .slider:before { | |
transform: translateX(26px); | |
} | |
.slider-icon { | |
position: absolute; | |
top: 50%; | |
transform: translateY(-50%); | |
color: white; | |
font-size: 14px; | |
} | |
.video-icon { | |
left: 8px; | |
} | |
.audio-icon { | |
right: 8px; | |
} | |
#videoContainer { | |
transition: all 0.3s ease; | |
} | |
#audioContainer { | |
transition: all 0.3s ease; | |
background: linear-gradient(135deg, #4f46e5 0%, #10b981 100%); | |
} | |
.progress-container { | |
height: 6px; | |
background-color: #e5e7eb; | |
border-radius: 3px; | |
cursor: pointer; | |
} | |
.progress-bar { | |
height: 100%; | |
background-color: #4f46e5; | |
border-radius: 3px; | |
width: 0%; | |
} | |
.thumbnail { | |
width: 100%; | |
height: 100%; | |
object-fit: cover; | |
border-radius: 8px; | |
} | |
.audio-visualizer { | |
display: flex; | |
align-items: flex-end; | |
height: 50px; | |
gap: 2px; | |
} | |
.audio-bar { | |
background-color: rgba(255, 255, 255, 0.7); | |
width: 4px; | |
border-radius: 2px; | |
animation: equalize 1s infinite alternate; | |
animation-delay: calc(var(--order) * 100ms); | |
} | |
@keyframes equalize { | |
0% { | |
height: 10%; | |
} | |
100% { | |
height: calc(var(--height) * 1%); | |
} | |
} | |
</style> | |
</head> | |
<body class="bg-gray-100 min-h-screen flex items-center justify-center p-4"> | |
<div class="w-full max-w-2xl bg-white rounded-xl shadow-xl overflow-hidden"> | |
<!-- Header --> | |
<div class="bg-indigo-600 p-4 text-white"> | |
<h1 class="text-xl font-bold text-center">Reproductor Flexible</h1> | |
<p class="text-center text-indigo-100 text-sm">Cambia entre video y audio sin perder la reproducción</p> | |
</div> | |
<!-- Main Content --> | |
<div class="p-6"> | |
<!-- Video Container (Visible by default) --> | |
<div id="videoContainer" class="mb-6 rounded-lg overflow-hidden relative"> | |
<video id="mediaPlayer" class="w-full aspect-video bg-black" poster="https://i.imgur.com/3ZQZQ9m.jpg" controls> | |
<source id="mediaSource" src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4"> | |
Tu navegador no soporta el elemento de video. | |
</video> | |
<div id="videoOverlay" class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-30 hidden"> | |
<button id="playBtn" class="w-16 h-16 rounded-full bg-indigo-600 text-white flex items-center justify-center hover:bg-indigo-700 transition"> | |
<i class="fas fa-play text-2xl"></i> | |
</button> | |
</div> | |
</div> | |
<!-- Audio Container (Hidden by default) --> | |
<div id="audioContainer" class="hidden mb-6 rounded-lg p-6"> | |
<div class="flex items-center"> | |
<div class="mr-4"> | |
<div class="w-16 h-16 rounded-lg overflow-hidden shadow-md"> | |
<img src="https://i.imgur.com/3ZQZQ9m.jpg" alt="Thumbnail" class="thumbnail"> | |
</div> | |
</div> | |
<div class="flex-1"> | |
<h3 class="text-white font-medium">Big Buck Bunny</h3> | |
<p class="text-white text-opacity-80 text-sm">Reproduciendo en modo audio</p> | |
<!-- Audio Visualizer --> | |
<div class="audio-visualizer mt-2"> | |
<div class="audio-bar" style="--height: 30; --order: 1;"></div> | |
<div class="audio-bar" style="--height: 60; --order: 2;"></div> | |
<div class="audio-bar" style="--height: 40; --order: 3;"></div> | |
<div class="audio-bar" style="--height: 80; --order: 4;"></div> | |
<div class="audio-bar" style="--height: 50; --order: 5;"></div> | |
<div class="audio-bar" style="--height: 70; --order: 6;"></div> | |
<div class="audio-bar" style="--height: 30; --order: 7;"></div> | |
<div class="audio-bar" style="--height: 90; --order: 8;"></div> | |
<div class="audio-bar" style="--height: 60; --order: 9;"></div> | |
<div class="audio-bar" style="--height: 40; --order: 10;"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Custom Controls --> | |
<div class="space-y-4"> | |
<!-- Progress Bar --> | |
<div class="progress-container" id="progressContainer"> | |
<div class="progress-bar" id="progressBar"></div> | |
</div> | |
<!-- Time Display --> | |
<div class="flex justify-between text-sm text-gray-600"> | |
<span id="currentTime">0:00</span> | |
<span id="duration">1:00</span> | |
</div> | |
<!-- Main Controls --> | |
<div class="flex items-center justify-between"> | |
<!-- Play/Pause Button --> | |
<button id="playPauseBtn" class="w-12 h-12 rounded-full bg-indigo-100 text-indigo-600 flex items-center justify-center hover:bg-indigo-200 transition"> | |
<i class="fas fa-play"></i> | |
</button> | |
<!-- Volume Control --> | |
<div class="flex items-center space-x-2"> | |
<i class="fas fa-volume-down text-gray-600"></i> | |
<input type="range" id="volumeControl" min="0" max="1" step="0.01" value="1" class="w-24"> | |
</div> | |
<!-- Mode Switch --> | |
<div class="flex items-center space-x-3"> | |
<span class="text-sm font-medium text-gray-700">Modo:</span> | |
<label class="switch"> | |
<input type="checkbox" id="modeSwitch"> | |
<span class="slider"></span> | |
<span class="slider-icon video-icon"><i class="fas fa-video"></i></span> | |
<span class="slider-icon audio-icon"><i class="fas fa-music"></i></span> | |
</label> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
document.addEventListener('DOMContentLoaded', function() { | |
// Elements | |
const mediaPlayer = document.getElementById('mediaPlayer'); | |
const videoContainer = document.getElementById('videoContainer'); | |
const audioContainer = document.getElementById('audioContainer'); | |
const playPauseBtn = document.getElementById('playPauseBtn'); | |
const playBtn = document.getElementById('playBtn'); | |
const progressBar = document.getElementById('progressBar'); | |
const progressContainer = document.getElementById('progressContainer'); | |
const currentTimeDisplay = document.getElementById('currentTime'); | |
const durationDisplay = document.getElementById('duration'); | |
const volumeControl = document.getElementById('volumeControl'); | |
const modeSwitch = document.getElementById('modeSwitch'); | |
const videoOverlay = document.getElementById('videoOverlay'); | |
// Initial state | |
let isVideoMode = true; | |
// Play/Pause functionality | |
function togglePlayPause() { | |
if (mediaPlayer.paused) { | |
mediaPlayer.play(); | |
playPauseBtn.innerHTML = '<i class="fas fa-pause"></i>'; | |
videoOverlay.classList.add('hidden'); | |
} else { | |
mediaPlayer.pause(); | |
playPauseBtn.innerHTML = '<i class="fas fa-play"></i>'; | |
if (isVideoMode) videoOverlay.classList.remove('hidden'); | |
} | |
} | |
playPauseBtn.addEventListener('click', togglePlayPause); | |
playBtn.addEventListener('click', togglePlayPause); | |
// Update progress bar | |
mediaPlayer.addEventListener('timeupdate', function() { | |
const progress = (mediaPlayer.currentTime / mediaPlayer.duration) * 100; | |
progressBar.style.width = `${progress}%`; | |
// Update time displays | |
currentTimeDisplay.textContent = formatTime(mediaPlayer.currentTime); | |
if (!isNaN(mediaPlayer.duration)) { | |
durationDisplay.textContent = formatTime(mediaPlayer.duration); | |
} | |
}); | |
// Click on progress bar to seek | |
progressContainer.addEventListener('click', function(e) { | |
const rect = progressContainer.getBoundingClientRect(); | |
const pos = (e.clientX - rect.left) / rect.width; | |
mediaPlayer.currentTime = pos * mediaPlayer.duration; | |
}); | |
// Volume control | |
volumeControl.addEventListener('input', function() { | |
mediaPlayer.volume = this.value; | |
}); | |
// Mode switch | |
modeSwitch.addEventListener('change', function() { | |
isVideoMode = !isVideoMode; | |
if (isVideoMode) { | |
videoContainer.classList.remove('hidden'); | |
audioContainer.classList.add('hidden'); | |
if (mediaPlayer.paused) { | |
videoOverlay.classList.remove('hidden'); | |
} | |
} else { | |
videoContainer.classList.add('hidden'); | |
audioContainer.classList.remove('hidden'); | |
videoOverlay.classList.add('hidden'); | |
} | |
}); | |
// Format time (seconds to MM:SS) | |
function formatTime(seconds) { | |
const minutes = Math.floor(seconds / 60); | |
const secs = Math.floor(seconds % 60); | |
return `${minutes}:${secs < 10 ? '0' : ''}${secs}`; | |
} | |
// Update duration when metadata is loaded | |
mediaPlayer.addEventListener('loadedmetadata', function() { | |
durationDisplay.textContent = formatTime(mediaPlayer.duration); | |
}); | |
// Show overlay when video ends | |
mediaPlayer.addEventListener('ended', function() { | |
playPauseBtn.innerHTML = '<i class="fas fa-play"></i>'; | |
if (isVideoMode) videoOverlay.classList.remove('hidden'); | |
}); | |
// Initialize | |
mediaPlayer.volume = volumeControl.value; | |
// Animate audio bars when playing | |
mediaPlayer.addEventListener('play', function() { | |
const audioBars = document.querySelectorAll('.audio-bar'); | |
audioBars.forEach(bar => { | |
bar.style.animationPlayState = 'running'; | |
}); | |
}); | |
mediaPlayer.addEventListener('pause', function() { | |
const audioBars = document.querySelectorAll('.audio-bar'); | |
audioBars.forEach(bar => { | |
bar.style.animationPlayState = 'paused'; | |
}); | |
}); | |
// Optional: Replace with your video URL | |
function setMediaSource(url, posterUrl) { | |
document.getElementById('mediaSource').src = url; | |
mediaPlayer.poster = posterUrl || ''; | |
mediaPlayer.load(); | |
// Update thumbnail in audio mode | |
if (posterUrl) { | |
const audioThumbnail = document.querySelector('#audioContainer img'); | |
if (audioThumbnail) { | |
audioThumbnail.src = posterUrl; | |
} | |
} | |
} | |
// Example of how to set a new video URL (you can call this function when needed) | |
// setMediaSource('YOUR_NEW_VIDEO_URL.mp4', 'YOUR_THUMBNAIL_URL.jpg'); | |
}); | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=josejuan314/audiovideoswitch" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |