rotican.ai
Back to Explore

HD Video Player With Playlist

+Open App
HD Video Player With Playlist

Prompt

build this :- <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Fragrant Flowers Blossom - HD Player</title> <script src="https://cdn.tailwindcss.com"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> <style> @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap'); body { font-family: 'Inter', sans-serif; background: radial-gradient(circle at top left, #1e3a8a, #0f172a, #000000); color: #e2e8f0; min-height: 100vh; overflow-x: hidden; } /* Custom Scrollbar */ ::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { background: #0f172a; } ::-webkit-scrollbar-thumb { background: #3b82f6; border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: #2563eb; } /* Glassmorphism */ .glass-panel { background: rgba(30, 41, 59, 0.7); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.1); } /* Video Container & Controls Overlay */ .video-wrapper { position: relative; width: 100%; padding-bottom: 56.25%; /* 16:9 Aspect Ratio */ background: #000; border-radius: 0.75rem; overflow: hidden; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 8px 10px -6px rgba(0, 0, 0, 0.5); } video { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: contain; } /* Custom Controls Overlay */ .controls-overlay { position: absolute; bottom: 0; left: 0; width: 100%; background: linear-gradient(to top, rgba(0,0,0,0.9), transparent); padding: 20px; opacity: 0; transition: opacity 0.3s ease; display: flex; flex-direction: column; gap: 10px; } .video-wrapper:hover .controls-overlay, .video-wrapper.paused .controls-overlay { opacity: 1; } /* Progress Bar */ .progress-container { width: 100%; height: 5px; background: rgba(255,255,255,0.2); border-radius: 5px; cursor: pointer; position: relative; } .progress-bar { height: 100%; background: #3b82f6; width: 0%; border-radius: 5px; position: relative; } .progress-bar::after { content: ''; position: absolute; right: -6px; top: -4px; width: 12px; height: 12px; background: #fff; border-radius: 50%; opacity: 0; transition: opacity 0.2s; } .progress-container:hover .progress-bar::after { opacity: 1; } /* Playlist Drawer */ .playlist-drawer { position: fixed; top: 0; right: -400px; width: 350px; height: 100%; background: rgba(15, 23, 42, 0.95); backdrop-filter: blur(10px); border-left: 1px solid rgba(255,255,255,0.1); transition: right 0.4s cubic-bezier(0.16, 1, 0.3, 1); z-index: 50; padding: 20px; display: flex; flex-direction: column; } .playlist-drawer.open { right: 0; } /* Notification Toast */ .notification { position: fixed; top: 20px; left: 50%; transform: translateX(-50%) translateY(-100px); background: rgba(59, 130, 246, 0.9); color: white; padding: 12px 24px; border-radius: 50px; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3); transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); z-index: 100; display: flex; align-items: center; gap: 10px; font-weight: 600; } .notification.show { transform: translateX(-50%) translateY(0); } /* Loader */ .loader { border: 4px solid rgba(255, 255, 255, 0.1); border-left-color: #3b82f6; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; position: absolute; top: 50%; left: 50%; margin-top: -20px; margin-left: -20px; display: none; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .quality-badge { background: rgba(255,255,255,0.2); padding: 2px 6px; border-radius: 4px; font-size: 0.75rem; font-weight: bold; margin-left: 10px; } </style> </head> <body class="flex flex-col items-center"> <!-- Notification Toast --> <div id="notification" class="notification"> <i class="fas fa-info-circle"></i> <span id="notification-text">Operation Successful</span> </div> <!-- Main Container --> <div class="w-full max-w-6xl px-4 py-8 flex flex-col gap-6"> <!-- Header / Video Info --> <div class="flex flex-col md:flex-row justify-between items-start md:items-end gap-4 border-b border-white/10 pb-6"> <div> <div class="flex items-center gap-3 mb-2"> <span class="bg-blue-600 text-xs font-bold px-2 py-1 rounded text-white">HD</span> <span class="text-blue-400 text-sm font-semibold tracking-wide uppercase">Now Playing</span> </div> <h1 id="video-title" class="text-3xl md:text-4xl font-bold text-white leading-tight">Episode 1 - Rintaro and Kaori</h1> <p class="text-slate-400 mt-2 text-sm md:text-base">Season 1 • Romance • Drama</p> </div> <div class="flex gap-3"> <button onclick="togglePlaylist()" class="glass-panel hover:bg-white/10 text-white px-4 py-2 rounded-lg transition flex items-center gap-2"> <i class="fas fa-list-ul"></i> Playlist </button> <button class="bg-blue-600 hover:bg-blue-500 text-white px-4 py-2 rounded-lg transition flex items-center gap-2 shadow-lg shadow-blue-600/30"> <i class="fas fa-share-alt"></i> Share </button> </div> </div> <!-- Player Section --> <div class="video-wrapper group" id="video-container"> <div class="loader" id="loader"></div> <!-- Using a high quality stock video for demo purposes --> <video id="main-video" poster="https://images.unsplash.com/photo-1490750967868-58cb75069ed6?q=80&w=2070&auto=format&fit=crop" playsinline> <source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4" type="video/mp4"> Your browser does not support the video tag. </video> <!-- Big Play Button (Center) --> <div id="center-play" class="absolute inset-0 flex items-center justify-center cursor-pointer bg-black/20 group-hover:bg-black/10 transition"> <div class="w-16 h-16 md:w-20 md:h-20 bg-white/20 backdrop-blur-sm rounded-full flex items-center justify-center hover:scale-110 transition duration-300 border border-white/30"> <i class="fas fa-play text-2xl md:text-3xl text-white ml-1"></i> </div> </div> <!-- Controls Overlay --> <div class="controls-overlay"> <!-- Progress --> <div class="progress-container" id="progress-container"> <div class="progress-bar" id="progress-bar"></div> </div> <!-- Buttons Row --> <div class="flex justify-between items-center text-white"> <div class="flex items-center gap-4"> <button id="play-pause-btn" class="hover:text-blue-400 transition text-xl w-8"> <i class="fas fa-play"></i> </button> <button id="mute-btn" class="hover:text-blue-400 transition text-lg w-8"> <i class="fas fa-volume-up"></i> </button> <span class="text-xs font-mono text-slate-300" id="time-display">00:00 / 00:00</span> </div> <div class="flex items-center gap-4"> <div class="hidden md:flex items-center text-xs text-slate-300 bg-black/40 px-2 py-1 rounded"> <i class="fas fa-bolt text-yellow-400 mr-1"></i> Auto <span class="quality-badge">1080p</span> </div> <button id="fullscreen-btn" class="hover:text-blue-400 transition text-lg" title="Fullscreen"> <i class="fas fa-expand"></i> </button> </div> </div> </div> </div> <!-- Description / Meta --> <div class="glass-panel rounded-xl p-6 mt-2"> <h3 class="text-lg font-semibold text-white mb-2">About this episode</h3> <p class="text-slate-300 leading-relaxed text-sm md:text-base"> The journey begins. Rintaro, a reserved botanist, meets Kaori, a spirited writer, in a small town famous for its cherry blossoms. As they navigate their differences, a delicate bond forms amidst the falling petals. Experience the stunning visuals and emotional depth in Full HD. </p> <div class="flex gap-4 mt-4 text-xs text-slate-400 font-mono"> <span><i class="fas fa-eye mr-1"></i> 1.2M Views</span> <span><i class="fas fa-thumbs-up mr-1"></i> 45K Likes</span> <span><i class="fas fa-calendar mr-1"></i> Released: Oct 24, 2023</span> </div> </div> </div> <!-- Playlist Drawer --> <div id="playlist-drawer" class="playlist-drawer"> <div class="flex justify-between items-center mb-6"> <h2 class="text-xl font-bold text-white">Episodes</h2> <button onclick="togglePlaylist()" class="text-slate-400 hover:text-white transition"> <i class="fas fa-times text-xl"></i> </button> </div> <div class="flex-1 overflow-y-auto space-y-3 pr-2" id="playlist-items"> <!-- Items injected via JS --> </div> </div> <script> // Data Structure const episodes = [ { id: 1, title: "Episode 1 - Rintaro and Kaori", desc: "The fateful meeting under the cherry blossoms.", src: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/TearsOfSteel.mp4", thumb: "https://images.unsplash.com/photo-1490750967868-58cb75069ed6?q=80&w=300&auto=format&fit=crop", duration: "12:34" }, { id: 2, title: "Episode 2 - The Garden's Secret", desc: "Kaori discovers Rintaro's hidden greenhouse.", src: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4", thumb: "https://images.unsplash.com/photo-1462275646964-a0e338679cde?q=80&w=300&auto=format&fit=crop", duration: "14:20" }, { id: 3, title: "Episode 3 - Rainy Days", desc: "A storm forces them to spend the day indoors.", src: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4", thumb: "https://images.unsplash.com/photo-1515694346937-94d85e41e6f0?q=80&w=300&auto=format&fit=crop", duration: "11:15" }, { id: 4, title: "Episode 4 - The Letter", desc: "Rintaro finds a letter from the past.", src: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4", thumb: "https://images.unsplash.com/photo-1516205651411-a416745265dd?q=80&w=300&auto=format&fit=crop", duration: "15:45" }, { id: 5, title: "Episode 5 - Full Bloom", desc: "The festival arrives, and confessions are made.", src: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4", thumb: "https://images.unsplash.com/photo-1522383225653-ed111181a951?q=80&w=300&auto=format&fit=crop", duration: "13:50" } ]; // State let currentEpisodeIndex = 0; let isPlaying = false; let isMuted = false; // Elements const video = document.getElementById('main-video'); const playPauseBtn = document.getElementById('play-pause-btn'); const centerPlay = document.getElementById('center-play'); const muteBtn = document.getElementById('mute-btn'); const fullscreenBtn = document.getElementById('fullscreen-btn'); const progressContainer = document.getElementById('progress-container'); const progressBar = document.getElementById('progress-bar'); const timeDisplay = document.getElementById('time-display'); const videoTitle = document.getElementById('video-title'); const playlistDrawer = document.getElementById('playlist-drawer'); const playlistItemsContainer = document.getElementById('playlist-items'); const notification = document.getElementById('notification'); const notificationText = document.getElementById('notification-text'); const loader = document.getElementById('loader'); // Initialization function init() { renderPlaylist(); loadEpisode(0); // Event Listeners playPauseBtn.addEventListener('click', togglePlay); centerPlay.addEventListener('click', togglePlay); video.addEventListener('click', togglePlay); muteBtn.addEventListener('click', toggleMute); fullscreenBtn.addEventListener('click', toggleFullscreen); video.addEventListener('timeupdate', updateProgress); video.addEventListener('ended', () => { showNotification("Episode Finished. Next up..."); setTimeout(() => nextEpisode(), 2000); }); progressContainer.addEventListener('click', scrub); video.addEventListener('waiting', () => loader.style.display = 'block'); video.addEventListener('playing', () => loader.style.display = 'none'); video.addEventListener('canplay', () => loader.style.display = 'none'); } // Core Functions function togglePlay() { if (video.paused) { video.play(); isPlaying = true; playPauseBtn.innerHTML = '<i class="fas fa-pause"></i>'; centerPlay.style.opacity = '0'; centerPlay.style.pointerEvents = 'none'; document.querySelector('.video-wrapper').classList.remove('paused'); } else { video.pause(); isPlaying = false; playPauseBtn.innerHTML = '<i class="fas fa-play"></i>'; centerPlay.style.opacity = '1'; centerPlay.style.pointerEvents = 'auto'; document.querySelector('.video-wrapper').classList.add('paused'); } } function toggleMute() { if (video.muted) { video.muted = false; muteBtn.innerHTML = '<i class="fas fa-volume-up"></i>'; showNotification("Sound On"); } else { video.muted = true; muteBtn.innerHTML = '<i class="fas fa-volume-mute"></i>'; showNotification("Muted"); } } function toggleFullscreen() { const container = document.getElementById('video-container'); if (!document.fullscreenElement) { if (container.requestFullscreen) { container.requestFullscreen(); } else if (video.requestFullscreen) { video.requestFullscreen(); } fullscreenBtn.innerHTML = '<i class="fas fa-compress"></i>'; } else { if (document.exitFullscreen) { document.exitFullscreen(); } fullscreenBtn.innerHTML = '<i class="fas fa-expand"></i>'; } } function updateProgress() { const percent = (video.currentTime / video.duration) * 100; progressBar.style.width = `${percent}%`; let currentMins = Math.floor(video.currentTime / 60); let currentSecs = Math.floor(video.currentTime % 60); let durationMins = Math.floor(video.duration / 60) || 0; let durationSecs = Math.floor(video.duration % 60) || 0; if(currentSecs < 10) currentSecs = '0' + currentSecs; if(durationSecs < 10) durationSecs = '0' + durationSecs; timeDisplay.innerText = `${currentMins}:${currentSecs} / ${durationMins}:${durationSecs}`; } function scrub(e) { const scrubTime = (e.offsetX / progressContainer.offsetWidth) * video.duration; video.currentTime = scrubTime; } function loadEpisode(index) { currentEpisodeIndex = index; const ep = episodes[index]; // Update UI videoTitle.innerText = ep.title; video.src = ep.src; video.poster = ep.thumb; // Optional: keep poster or let video load // Reset State video.load(); progressBar.style.width = '0%'; // Auto Play video.play().then(() => { isPlaying = true; playPauseBtn.innerHTML = '<i class="fas fa-pause"></i>'; centerPlay.style.opacity = '0'; document.querySelector('.video-wrapper').classList.remove('paused'); }).catch(e => console.log("Autoplay prevented")); // Update Playlist Active State renderPlaylist(); // Close drawer on mobile after selection if(window.innerWidth < 768) { playlistDrawer.classList.remove('open'); } } function nextEpisode() { let nextIndex = currentEpisodeIndex + 1; if (nextIndex >= episodes.length) nextIndex = 0; loadEpisode(nextIndex); showNotification(`Playing: ${episodes[nextIndex].title}`); } function renderPlaylist() { playlistItemsContainer.innerHTML = ''; episodes.forEach((ep, index) => { const isActive = index === currentEpisodeIndex; const item = document.createElement('div'); item.className = `flex gap-3 p-3 rounded-lg cursor-pointer transition ${isActive ? 'bg-blue-600/40 border border-blue-500/50' : 'hover:bg-white/5 border border-transparent'}`; item.onclick = () => { if(!isActive) { loadEpisode(index); showNotification(`Switched to ${ep.title}`); } }; item.innerHTML = ` <div class="relative w-24 h-14 flex-shrink-0 rounded overflow-hidden"> <img src="${ep.thumb}" class="w-full h-full object-cover" alt="thumb"> <div class="absolute bottom-1 right-1 bg-black/80 text-[10px] px-1 rounded text-white">${ep.duration}</div> ${isActive ? '<div class="absolute inset-0 flex items-center justify-center bg-black/40"><i class="fas fa-play text-white text-xs"></i></div>' : ''} </div> <div class="flex flex-col justify-center"> <h4 class="text-sm font-bold text-white line-clamp-1 ${isActive ? 'text-blue-300' : ''}">${ep.title}</h4> <p class="text-xs text-slate-400 line-clamp-2 mt-1">${ep.desc}</p> </div> `; playlistItemsContainer.appendChild(item); }); } function togglePlaylist() { playlistDrawer.classList.toggle('open'); } // Notification System let notificationTimeout; function showNotification(msg) { notificationText.innerText = msg; notification.classList.add('show'); clearTimeout(notificationTimeout); notificationTimeout = setTimeout(() => { notification.classList.remove('show'); }, 3000); } // Keyboard Shortcuts document.addEventListener('keydown', (e) => { if (e.code === 'Space') { e.preventDefault(); togglePlay(); } if (e.code === 'KeyF') { toggleFullscreen(); } }); // Start init(); </script> </body> </html>

Share

Last Updated February 18, 2026