Файловый менеджер - Редактировать - /home/gqdcvggs/formore.tv/watch.php
Назад
<?php require_once 'includes/config.php'; require_once 'includes/auth.php'; $content_id = (int)($_GET['id'] ?? 0); if (!$content_id) { header('Location: home.php'); exit; } $stmt = $pdo->prepare("SELECT * FROM content WHERE id = ? AND status = 'approved'"); $stmt->execute([$content_id]); $content = $stmt->fetch(PDO::FETCH_ASSOC); if (!$content) { header('Location: home.php'); exit; } $selected_profile_id = $_SESSION['selected_profile'] ?? null; $selected_profile = null; if ($selected_profile_id) { $stmt = $pdo->prepare("SELECT * FROM profiles WHERE id = ? AND user_id = ?"); $stmt->execute([$selected_profile_id, $current_user['id']]); $selected_profile = $stmt->fetch(PDO::FETCH_ASSOC); } if (!$selected_profile || $content['age_rating'] > $selected_profile['age_limit']) { header('Location: home.php'); exit; } $stmt = $pdo->prepare("SELECT * FROM ads WHERE status = 'active' ORDER BY RAND() LIMIT 1"); $stmt->execute(); $ad = $stmt->fetch(PDO::FETCH_ASSOC); $stmt = $pdo->prepare("SELECT * FROM content WHERE status = 'approved' AND id != ? ORDER BY RAND() LIMIT 6"); $stmt->execute([$content_id]); $related_content = $stmt->fetchAll(PDO::FETCH_ASSOC); ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><?php echo htmlspecialchars($content['title']); ?> - Formore</title> <meta property="og:title" content="<?php echo htmlspecialchars($content['title']); ?> - Formore"> <meta property="og:description" content="<?php echo htmlspecialchars(substr($content['description'], 0, 160)); ?>"> <meta property="og:image" content="<?php echo htmlspecialchars($content['thumbnail']); ?>"> <meta property="og:type" content="video.movie"> <meta property="og:url" content="<?php echo htmlspecialchars('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); ?>"> <meta property="og:site_name" content="Formore"> <meta name="twitter:card" content="summary_large_image"> <meta name="twitter:title" content="<?php echo htmlspecialchars($content['title']); ?> - Formore"> <meta name="twitter:description" content="<?php echo htmlspecialchars(substr($content['description'], 0, 160)); ?>"> <meta name="twitter:image" content="<?php echo htmlspecialchars($content['thumbnail']); ?>"> <script src="https://cdn.tailwindcss.com"></script> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <link rel="icon" href="https://cdn.imators.com/logo.png" type="image/png"> <style> body { font-family: 'Poppins', sans-serif; } .hero-bg { background: url('<?php echo htmlspecialchars($content['thumbnail']); ?>'); } .video-controls { transition: opacity 0.3s ease; } .video-controls:hover { opacity: 1 !important; } video { background: #000; } input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 16px; height: 16px; background: white; border-radius: 50%; cursor: pointer; } input[type="range"]::-moz-range-thumb { width: 16px; height: 16px; background: white; border-radius: 50%; cursor: pointer; border: none; } </style> </head> <body class="bg-white text-gray-900"> <header class="fixed top-0 w-full px-4 md:px-8 py-4 bg-white/95 backdrop-blur-xl border-b border-gray-200 z-50"> <div class="flex justify-between items-center max-w-6xl mx-auto"> <a href="home.php" class="text-xl font-semibold text-black">formore</a> <a href="home.php" class="px-6 py-3 bg-gray-100 hover:bg-gray-200 text-gray-800 rounded-full transition-colors flex items-center gap-2"> <i class="fas fa-arrow-left"></i> Back </a> </div> </header> <div class="mt-20 max-w-6xl mx-auto px-4 md:px-8 py-6"> <section class="mb-8"> <div class="hero-bg bg-cover bg-center rounded-xl aspect-video mb-6"></div> <div class="space-y-4"> <div class="flex flex-col sm:flex-row sm:items-center gap-4"> <h1 class="text-2xl md:text-4xl font-semibold"><?php echo htmlspecialchars($content['title']); ?></h1> <span class="inline-flex items-center bg-gray-100 px-3 py-1 rounded-full text-sm font-medium w-fit"> <?php echo $content['age_rating']; ?>+ </span> </div> <div class="text-gray-600 text-sm md:text-base"> <span class="flex items-center gap-2 mb-2"> <i class="fas fa-user"></i> By <?php echo htmlspecialchars($content['author']); ?> </span> <?php if(!empty($content['director'])): ?> <span class="flex items-center gap-2"> <i class="fas fa-video"></i> Directed by <?php echo htmlspecialchars($content['director']); ?> </span> <?php endif; ?> </div> <p class="text-gray-700 text-sm md:text-base leading-relaxed max-w-4xl"> <?php echo nl2br(htmlspecialchars($content['description'])); ?> </p> <button onclick="launchVideo()" class="bg-black text-white px-8 py-4 rounded-lg font-medium hover:bg-gray-800 transition-colors flex items-center gap-3 w-fit"> <i class="fas fa-play"></i> Watch Now </button> </div> </section> <section class="bg-gray-50 rounded-xl p-6 mb-8"> <h3 class="text-lg font-semibold mb-4">Details</h3> <div class="grid grid-cols-2 md:grid-cols-4 gap-6"> <div> <div class="text-xs md:text-sm text-gray-500 mb-1 uppercase tracking-wide">Author</div> <div class="text-sm md:text-base font-medium"><?php echo htmlspecialchars($content['author']); ?></div> </div> <div> <div class="text-xs md:text-sm text-gray-500 mb-1 uppercase tracking-wide">Director</div> <div class="text-sm md:text-base font-medium"><?php echo htmlspecialchars($content['director']); ?></div> </div> <div> <div class="text-xs md:text-sm text-gray-500 mb-1 uppercase tracking-wide">Rating</div> <div class="text-sm md:text-base font-medium"><?php echo $content['age_rating']; ?>+</div> </div> <?php if(!empty($content['category'])): ?> <div> <div class="text-xs md:text-sm text-gray-500 mb-1 uppercase tracking-wide">Category</div> <div class="text-sm md:text-base font-medium"><?php echo htmlspecialchars($content['category']); ?></div> </div> <?php endif; ?> </div> </section> <?php if(!empty($related_content)): ?> <section> <h2 class="text-xl md:text-2xl font-semibold mb-6">Similar Content</h2> <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4"> <?php foreach($related_content as $related): ?> <div onclick="window.location.href='watch.php?id=<?php echo $related['id']; ?>'" class="relative bg-gray-100 rounded-lg overflow-hidden cursor-pointer hover:scale-105 transition-transform aspect-video group"> <img src="<?php echo htmlspecialchars($related['thumbnail']); ?>" alt="<?php echo htmlspecialchars($related['title']); ?>" class="w-full h-full object-cover"> <div class="absolute top-2 right-2 bg-black/80 text-white px-2 py-1 rounded text-xs font-medium"><?php echo $related['age_rating']; ?>+</div> <div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/80 to-transparent text-white p-3 opacity-0 group-hover:opacity-100 transition-opacity"> <div class="font-medium text-sm mb-1"><?php echo htmlspecialchars($related['title']); ?></div> <div class="text-xs opacity-90">By <?php echo htmlspecialchars($related['author']); ?></div> </div> </div> <?php endforeach; ?> </div> </section> <?php endif; ?> </div> <div id="videoModal" class="fixed inset-0 bg-black z-50 hidden"> <div id="videoContainer" class="relative w-full h-full group"> <?php if($ad): ?> <video id="adVideo" class="w-full h-full object-contain" preload="auto" muted controls> <source src="<?php echo htmlspecialchars($ad['video_url']); ?>" type="video/mp4"> </video> <div id="adOverlay" class="absolute top-4 right-16 bg-red-600/90 text-white px-3 py-2 rounded text-sm font-medium">ADVERTISEMENT</div> <button id="skipAdBtn" class="absolute bottom-6 right-6 bg-black/80 hover:bg-black text-white px-4 py-2 rounded-full hidden transition-all">Skip Ad</button> <?php endif; ?> <video id="mainVideo" class="w-full h-full object-contain hidden" preload="auto" muted controls> <source src="<?php echo htmlspecialchars($content['video_url']); ?>" type="video/mp4"> </video> <button onclick="closeVideo()" class="absolute top-4 right-4 bg-black/80 hover:bg-black text-white w-12 h-12 rounded-full transition-all z-10"> <i class="fas fa-times"></i> </button> <div id="customControls" class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/90 to-transparent p-4 opacity-0 group-hover:opacity-100 transition-opacity hidden"> <div id="progressWrapper" class="relative h-2 bg-white/20 rounded-full mb-4 cursor-pointer"> <div id="progressBar" class="h-full bg-white rounded-full w-0 transition-all"></div> <div id="timeTooltip" class="absolute bottom-6 bg-black/90 text-white px-2 py-1 rounded text-sm opacity-0 pointer-events-none whitespace-nowrap">0:00</div> <img id="videoPreview" class="absolute bottom-8 w-32 h-18 bg-black rounded opacity-0 pointer-events-none object-cover border-2 border-white/40" alt="Preview"> </div> <div class="flex items-center gap-4"> <button onclick="skipTime(-10)" class="bg-white/20 hover:bg-white/30 text-white px-3 py-2 rounded transition-all text-sm"> <i class="fas fa-backward"></i> </button> <button id="playButton" onclick="togglePlayPause()" class="bg-white/20 hover:bg-white/30 text-white w-10 h-10 rounded-full flex items-center justify-center transition-all"> <i class="fas fa-play"></i> </button> <button onclick="skipTime(10)" class="bg-white/20 hover:bg-white/30 text-white px-3 py-2 rounded transition-all text-sm"> <i class="fas fa-forward"></i> </button> <div class="text-white text-sm min-w-max"> <span id="currentTime">0:00</span> / <span id="totalDuration">0:00</span> </div> <div class="flex items-center gap-3 ml-auto"> <button id="muteButton" onclick="toggleMute()" class="bg-white/20 hover:bg-white/30 text-white px-2 py-2 rounded transition-all text-sm"> <i class="fas fa-volume-up"></i> </button> <input type="range" id="volumeSlider" min="0" max="100" value="100" class="w-16 h-1 bg-white/20 rounded-full outline-none cursor-pointer"> <button onclick="toggleFullscreen()" class="bg-white/20 hover:bg-white/30 text-white px-2 py-2 rounded transition-all text-sm"> <i class="fas fa-expand"></i> </button> </div> </div> </div> </div> </div> <canvas id="previewCanvas" class="hidden"></canvas> <script> const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent); const isAndroid = /Android/.test(navigator.userAgent); let activeVideo = null; let hasAd = <?php echo $ad ? 'true' : 'false'; ?>; let adSkipTimer = null; let previewData = {}; let controlsTimer = null; const videoModal = document.getElementById('videoModal'); const videoContainer = document.getElementById('videoContainer'); const adVideo = document.getElementById('adVideo'); const mainVideo = document.getElementById('mainVideo'); const adOverlay = document.getElementById('adOverlay'); const skipAdBtn = document.getElementById('skipAdBtn'); const customControls = document.getElementById('customControls'); const progressWrapper = document.getElementById('progressWrapper'); const progressBar = document.getElementById('progressBar'); const playButton = document.getElementById('playButton'); const muteButton = document.getElementById('muteButton'); const volumeSlider = document.getElementById('volumeSlider'); const currentTimeSpan = document.getElementById('currentTime'); const totalDurationSpan = document.getElementById('totalDuration'); const timeTooltip = document.getElementById('timeTooltip'); const videoPreview = document.getElementById('videoPreview'); const previewCanvas = document.getElementById('previewCanvas'); function launchVideo() { videoModal.classList.remove('hidden'); document.body.style.overflow = 'hidden'; if (isMobile) { if (hasAd && adVideo) { adVideo.setAttribute('controls', 'true'); playMobileAd(); } else { prepareMobileMainVideo(); } } else { if (hasAd && adVideo) { adVideo.removeAttribute('controls'); playAdvertisement(); } else { prepareMainVideo(); } } } function playMobileAd() { adVideo.classList.remove('hidden'); mainVideo.classList.add('hidden'); customControls.classList.add('hidden'); activeVideo = adVideo; adVideo.muted = false; adVideo.play().catch(e => console.log('Mobile ad play error:', e)); adSkipTimer = setTimeout(() => { skipAdBtn.classList.remove('hidden'); }, 20000); adVideo.addEventListener('ended', endMobileAdvertisement); } function prepareMobileMainVideo() { if (adVideo) { adVideo.classList.add('hidden'); adOverlay.classList.add('hidden'); skipAdBtn.classList.add('hidden'); } mainVideo.classList.remove('hidden'); mainVideo.setAttribute('controls', 'true'); customControls.classList.add('hidden'); activeVideo = mainVideo; mainVideo.muted = false; } function endMobileAdvertisement() { if (adSkipTimer) clearTimeout(adSkipTimer); adVideo.classList.add('hidden'); adOverlay.classList.add('hidden'); skipAdBtn.classList.add('hidden'); adVideo.muted = true; adVideo.pause(); prepareMobileMainVideo(); } function playAdvertisement() { adVideo.classList.remove('hidden'); mainVideo.classList.add('hidden'); customControls.classList.add('hidden'); activeVideo = adVideo; adVideo.muted = false; adVideo.play().catch(e => console.log('Desktop ad play error:', e)); adSkipTimer = setTimeout(() => { skipAdBtn.classList.remove('hidden'); }, 20000); adVideo.addEventListener('ended', endAdvertisement); } function endAdvertisement() { if (adSkipTimer) clearTimeout(adSkipTimer); adVideo.classList.add('hidden'); adOverlay.classList.add('hidden'); skipAdBtn.classList.add('hidden'); adVideo.muted = true; adVideo.pause(); prepareMainVideo(); } function prepareMainVideo() { if (adVideo) { adVideo.classList.add('hidden'); adOverlay.classList.add('hidden'); skipAdBtn.classList.add('hidden'); } mainVideo.classList.remove('hidden'); mainVideo.removeAttribute('controls'); customControls.classList.remove('hidden'); activeVideo = mainVideo; mainVideo.muted = false; generatePreviews(); } function closeVideo() { videoModal.classList.add('hidden'); document.body.style.overflow = 'auto'; if (activeVideo) { activeVideo.pause(); activeVideo.currentTime = 0; } if (adVideo) { adVideo.classList.remove('hidden'); adOverlay.classList.remove('hidden'); skipAdBtn.classList.add('hidden'); } mainVideo.classList.add('hidden'); customControls.classList.add('hidden'); if (adSkipTimer) clearTimeout(adSkipTimer); if (controlsTimer) clearTimeout(controlsTimer); if (playButton) playButton.innerHTML = '<i class="fas fa-play"></i>'; activeVideo = null; } function togglePlayPause() { if (!activeVideo || isMobile) return; if (activeVideo.paused) { activeVideo.play().catch(e => console.log('Play error:', e)); playButton.innerHTML = '<i class="fas fa-pause"></i>'; } else { activeVideo.pause(); playButton.innerHTML = '<i class="fas fa-play"></i>'; } } function skipTime(seconds) { if (activeVideo === mainVideo && activeVideo.duration && !isMobile) { const newTime = Math.max(0, Math.min(activeVideo.duration, activeVideo.currentTime + seconds)); activeVideo.currentTime = newTime; } } function toggleMute() { if (!activeVideo || isMobile) return; activeVideo.muted = !activeVideo.muted; muteButton.innerHTML = activeVideo.muted ? '<i class="fas fa-volume-mute"></i>' : '<i class="fas fa-volume-up"></i>'; volumeSlider.value = activeVideo.muted ? 0 : activeVideo.volume * 100; } function toggleFullscreen() { if (!document.fullscreenElement) { videoModal.requestFullscreen().catch(e => console.log('Fullscreen error:', e)); } else { document.exitFullscreen(); } } function generatePreviews() { if (isMobile || !mainVideo.duration) { if (!isMobile) setTimeout(generatePreviews, 100); return; } const canvas = previewCanvas; const ctx = canvas.getContext('2d'); const totalPreviews = 50; const interval = mainVideo.duration / totalPreviews; let currentTime = 0; function generateNext() { if (currentTime >= mainVideo.duration) return; const tempTime = currentTime; mainVideo.currentTime = tempTime; const handleSeek = () => { mainVideo.removeEventListener('seeked', handleSeek); canvas.width = 128; canvas.height = 72; ctx.drawImage(mainVideo, 0, 0, 128, 72); previewData[tempTime] = canvas.toDataURL(); currentTime += interval; setTimeout(generateNext, 50); }; mainVideo.addEventListener('seeked', handleSeek); } generateNext(); } function findClosestPreview(time) { const times = Object.keys(previewData).map(Number); if (times.length === 0) return null; let closest = times[0]; for (let t of times) { if (Math.abs(t - time) < Math.abs(closest - time)) { closest = t; } } return previewData[closest]; } function formatTime(seconds) { if (isNaN(seconds) || !isFinite(seconds)) return '0:00'; const mins = Math.floor(seconds / 60); const secs = Math.floor(seconds % 60); return `${mins}:${secs.toString().padStart(2, '0')}`; } function showControls() { if (isMobile) return; customControls.style.opacity = '1'; if (controlsTimer) clearTimeout(controlsTimer); controlsTimer = setTimeout(() => { if (activeVideo && !activeVideo.paused) { customControls.style.opacity = '0'; } }, 3000); } if (skipAdBtn) { skipAdBtn.onclick = isMobile ? endMobileAdvertisement : endAdvertisement; } if (mainVideo && !isMobile) { mainVideo.addEventListener('play', () => { if (playButton) playButton.innerHTML = '<i class="fas fa-pause"></i>'; }); mainVideo.addEventListener('pause', () => { if (playButton) playButton.innerHTML = '<i class="fas fa-play"></i>'; }); mainVideo.addEventListener('timeupdate', () => { if (mainVideo.duration && isFinite(mainVideo.duration)) { const progress = (mainVideo.currentTime / mainVideo.duration) * 100; if (progressBar) progressBar.style.width = progress + '%'; if (currentTimeSpan) currentTimeSpan.textContent = formatTime(mainVideo.currentTime); } }); mainVideo.addEventListener('loadedmetadata', () => { if (totalDurationSpan) totalDurationSpan.textContent = formatTime(mainVideo.duration); }); mainVideo.addEventListener('volumechange', () => { if (volumeSlider) volumeSlider.value = mainVideo.volume * 100; if (muteButton) muteButton.innerHTML = mainVideo.muted ? '<i class="fas fa-volume-mute"></i>' : '<i class="fas fa-volume-up"></i>'; }); mainVideo.addEventListener('error', (e) => { console.log('Video error:', e); }); } if (volumeSlider && !isMobile) { volumeSlider.addEventListener('input', (e) => { if (activeVideo) { const volume = e.target.value / 100; activeVideo.volume = volume; activeVideo.muted = volume === 0; } }); } if (progressWrapper && !isMobile) { progressWrapper.addEventListener('click', (e) => { if (mainVideo.duration && activeVideo === mainVideo && isFinite(mainVideo.duration)) { const rect = progressWrapper.getBoundingClientRect(); const progress = (e.clientX - rect.left) / rect.width; mainVideo.currentTime = progress * mainVideo.duration; } }); progressWrapper.addEventListener('mousemove', (e) => { if (!mainVideo.duration || activeVideo !== mainVideo || !isFinite(mainVideo.duration)) return; const rect = progressWrapper.getBoundingClientRect(); const progress = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width)); const time = progress * mainVideo.duration; timeTooltip.textContent = formatTime(time); timeTooltip.style.left = Math.max(0, Math.min(rect.width - 60, e.clientX - rect.left - 30)) + 'px'; timeTooltip.classList.remove('opacity-0'); const preview = findClosestPreview(time); if (preview) { videoPreview.src = preview; videoPreview.style.left = Math.max(0, Math.min(rect.width - 128, e.clientX - rect.left - 64)) + 'px'; videoPreview.classList.remove('opacity-0'); } }); progressWrapper.addEventListener('mouseleave', () => { timeTooltip.classList.add('opacity-0'); videoPreview.classList.add('opacity-0'); }); } if (videoContainer && !isMobile) { videoContainer.addEventListener('mouseenter', showControls); videoContainer.addEventListener('mousemove', showControls); videoContainer.addEventListener('mouseleave', () => { if (controlsTimer) clearTimeout(controlsTimer); controlsTimer = setTimeout(() => { if (customControls) customControls.style.opacity = '0'; }, 1000); }); } videoModal.addEventListener('click', (e) => { if (e.target === videoModal) { closeVideo(); } }); document.addEventListener('keydown', (e) => { if (!videoModal.classList.contains('hidden') && !isMobile) { switch(e.code) { case 'Space': e.preventDefault(); togglePlayPause(); break; case 'Escape': e.preventDefault(); closeVideo(); break; case 'ArrowLeft': e.preventDefault(); skipTime(-10); break; case 'ArrowRight': e.preventDefault(); skipTime(10); break; case 'KeyF': e.preventDefault(); toggleFullscreen(); break; case 'KeyM': e.preventDefault(); toggleMute(); break; case 'ArrowUp': e.preventDefault(); if (activeVideo) { activeVideo.volume = Math.min(1, activeVideo.volume + 0.1); } break; case 'ArrowDown': e.preventDefault(); if (activeVideo) { activeVideo.volume = Math.max(0, activeVideo.volume - 0.1); } break; } } }); </script> </body> </html>
| ver. 1.6 |
Github
|
.
| PHP 8.1.33 | Генерация страницы: 0.01 |
proxy
|
phpinfo
|
Настройка