Spaces:
Running
Running
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>CinéVerse - 20,500 Films Complets - Mode Automatique</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> | |
| @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap'); | |
| body { | |
| font-family: 'Poppins', sans-serif; | |
| background-color: #0f172a; | |
| color: #f8fafc; | |
| } | |
| .hero-gradient { | |
| background: linear-gradient(135deg, rgba(15,23,42,0.9) 0%, rgba(124,58,237,0.6) 100%); | |
| } | |
| .movie-card { | |
| transition: all 0.3s ease; | |
| transform-origin: center; | |
| } | |
| .movie-card:hover { | |
| transform: scale(1.05); | |
| z-index: 10; | |
| box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5); | |
| } | |
| .movie-card:hover .play-icon { | |
| opacity: 1; | |
| transform: translate(-50%, -50%) scale(1.1); | |
| } | |
| .play-icon { | |
| transition: all 0.3s ease; | |
| } | |
| .loading-spinner { | |
| animation: spin 1s linear infinite; | |
| } | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| /* Custom scrollbar */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| height: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: #1e293b; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: #6366f1; | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: #4f46e5; | |
| } | |
| /* Video player styles */ | |
| .video-container { | |
| position: relative; | |
| padding-bottom: 56.25%; | |
| height: 0; | |
| overflow: hidden; | |
| } | |
| .video-container iframe { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| border: none; | |
| } | |
| /* Loading overlay */ | |
| .loading-overlay { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background-color: rgba(0, 0, 0, 0.9); | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| z-index: 9999; | |
| } | |
| /* Movie grid */ | |
| .movie-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); | |
| gap: 1.5rem; | |
| } | |
| @media (max-width: 768px) { | |
| .movie-grid { | |
| grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); | |
| } | |
| } | |
| /* Rating stars */ | |
| .rating-stars { | |
| color: #f59e0b; | |
| } | |
| /* Skeleton loading */ | |
| .skeleton { | |
| background-color: #1e293b; | |
| background-image: linear-gradient(90deg, #1e293b, #334155, #1e293b); | |
| background-size: 200% 100%; | |
| animation: shimmer 1.5s infinite; | |
| } | |
| @keyframes shimmer { | |
| 0% { background-position: 200% 0; } | |
| 100% { background-position: -200% 0; } | |
| } | |
| /* Floating action button */ | |
| .fab { | |
| position: fixed; | |
| bottom: 2rem; | |
| right: 2rem; | |
| width: 60px; | |
| height: 60px; | |
| border-radius: 50%; | |
| background: linear-gradient(135deg, #7c3aed, #4f46e5); | |
| color: white; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.2); | |
| cursor: pointer; | |
| z-index: 40; | |
| transition: all 0.3s ease; | |
| } | |
| .fab:hover { | |
| transform: scale(1.1); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3); | |
| } | |
| /* Movie details modal */ | |
| .movie-modal { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background-color: rgba(0, 0, 0, 0.9); | |
| z-index: 50; | |
| overflow-y: auto; | |
| opacity: 0; | |
| pointer-events: none; | |
| transition: opacity 0.3s ease; | |
| } | |
| .movie-modal.active { | |
| opacity: 1; | |
| pointer-events: all; | |
| } | |
| /* Video quality selector */ | |
| .quality-selector { | |
| position: absolute; | |
| bottom: 20px; | |
| right: 20px; | |
| z-index: 60; | |
| background: rgba(0, 0, 0, 0.7); | |
| border-radius: 4px; | |
| overflow: hidden; | |
| } | |
| .quality-btn { | |
| display: block; | |
| padding: 8px 12px; | |
| color: white; | |
| background: transparent; | |
| border: none; | |
| cursor: pointer; | |
| text-align: left; | |
| width: 100%; | |
| } | |
| .quality-btn:hover { | |
| background: rgba(255, 255, 255, 0.1); | |
| } | |
| /* Auto-play notification */ | |
| .autoplay-notification { | |
| position: fixed; | |
| bottom: 20px; | |
| left: 20px; | |
| background: rgba(0, 0, 0, 0.7); | |
| color: white; | |
| padding: 10px 15px; | |
| border-radius: 4px; | |
| z-index: 100; | |
| display: none; | |
| } | |
| /* Auto-play controls */ | |
| .autoplay-controls { | |
| position: fixed; | |
| bottom: 20px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| background: rgba(0, 0, 0, 0.7); | |
| color: white; | |
| padding: 10px 15px; | |
| border-radius: 4px; | |
| z-index: 100; | |
| display: flex; | |
| gap: 10px; | |
| } | |
| .autoplay-btn { | |
| background: #4f46e5; | |
| border: none; | |
| color: white; | |
| padding: 5px 10px; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| font-size: 14px; | |
| } | |
| .autoplay-btn:hover { | |
| background: #6366f1; | |
| } | |
| .autoplay-speed { | |
| background: #1e293b; | |
| border: none; | |
| color: white; | |
| padding: 5px; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Navigation --> | |
| <nav class="bg-gray-900/90 backdrop-blur-md fixed w-full z-50"> | |
| <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> | |
| <div class="flex items-center justify-between h-16"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0"> | |
| <span class="text-2xl font-bold bg-gradient-to-r from-purple-600 to-blue-500 bg-clip-text text-transparent">CinéVerse</span> | |
| </div> | |
| <div class="hidden md:block"> | |
| <div class="ml-10 flex items-baseline space-x-4"> | |
| <a href="#" class="text-white px-3 py-2 rounded-md text-sm font-medium">Accueil</a> | |
| <a href="#" class="text-gray-300 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Films</a> | |
| <a href="#" class="text-gray-300 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Genres</a> | |
| <a href="#" class="text-gray-300 hover:text-white px-3 py-2 rounded-md text-sm font-medium">Nouveautés</a> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="hidden md:block"> | |
| <div class="ml-4 flex items-center md:ml-6"> | |
| <div class="relative mx-4"> | |
| <input type="text" id="searchInput" placeholder="Rechercher un film..." class="bg-gray-800 text-white px-4 py-1 rounded-full w-64 focus:outline-none focus:ring-2 focus:ring-purple-500"> | |
| <button id="searchButton" class="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400"> | |
| <i class="fas fa-search"></i> | |
| </button> | |
| </div> | |
| <div class="ml-3 relative"> | |
| <div> | |
| <button class="max-w-xs flex items-center text-sm rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"> | |
| <img class="h-8 w-8 rounded-full" src="https://randomuser.me/api/portraits/men/32.jpg" alt="Profile"> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="-mr-2 flex md:hidden"> | |
| <button type="button" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"> | |
| <span class="sr-only">Open main menu</span> | |
| <i class="fas fa-bars"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </nav> | |
| <!-- Hero Section --> | |
| <section class="relative h-screen flex items-center justify-center overflow-hidden"> | |
| <div class="absolute inset-0"> | |
| <img src="https://image.tmdb.org/t/p/original/8Y43POKVKDj7PQzn4L5MLT5JxLX.jpg" alt="Hero background" class="w-full h-full object-cover"> | |
| <div class="absolute inset-0 hero-gradient"></div> | |
| </div> | |
| <div class="relative z-10 px-4 sm:px-6 lg:px-8 max-w-4xl mx-auto text-center"> | |
| <h1 class="text-4xl md:text-6xl font-bold mb-6 text-white">20,500 Films Complets</h1> | |
| <p class="text-xl md:text-2xl mb-8 text-gray-200">Regardez les meilleurs films en streaming illimité. Sans publicité. Sans engagement.</p> | |
| <div class="flex flex-col sm:flex-row justify-center gap-4"> | |
| <button id="playFeaturedMovie" class="bg-purple-600 hover:bg-purple-700 text-white font-bold py-3 px-8 rounded-full text-lg flex items-center justify-center transition duration-300 transform hover:scale-105"> | |
| <i class="fas fa-play mr-2"></i> Commencer à regarder | |
| </button> | |
| <button id="startAutoplay" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-8 rounded-full text-lg flex items-center justify-center transition duration-300 transform hover:scale-105"> | |
| <i class="fas fa-bolt mr-2"></i> Mode Automatique | |
| </button> | |
| </div> | |
| </div> | |
| <div class="absolute bottom-0 left-0 right-0 h-32 bg-gradient-to-t from-gray-900 to-transparent"></div> | |
| </section> | |
| <!-- Main Content --> | |
| <main class="pt-16 pb-20 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto"> | |
| <!-- Featured Movies --> | |
| <section class="mb-12"> | |
| <div class="flex items-center justify-between mb-6"> | |
| <h2 class="text-2xl font-bold">Nouveautés à ne pas manquer</h2> | |
| <a href="#" class="text-purple-400 hover:text-purple-300 flex items-center"> | |
| Voir tout <i class="fas fa-chevron-right ml-1"></i> | |
| </a> | |
| </div> | |
| <div class="movie-grid" id="newReleasesGrid"> | |
| <!-- Movie cards will be generated by JavaScript --> | |
| </div> | |
| </section> | |
| <!-- Trending Now --> | |
| <section class="mb-12"> | |
| <div class="flex items-center justify-between mb-6"> | |
| <h2 class="text-2xl font-bold">Tendances du moment</h2> | |
| <a href="#" class="text-purple-400 hover:text-purple-300 flex items-center"> | |
| Voir tout <i class="fas fa-chevron-right ml-1"></i> | |
| </a> | |
| </div> | |
| <div class="movie-grid" id="trendingGrid"> | |
| <!-- Movie cards will be generated by JavaScript --> | |
| </div> | |
| </section> | |
| <!-- Popular Movies --> | |
| <section class="mb-12"> | |
| <div class="flex items-center justify-between mb-6"> | |
| <h2 class="text-2xl font-bold">Films populaires</h2> | |
| <a href="#" class="text-purple-400 hover:text-purple-300 flex items-center"> | |
| Voir tout <i class="fas fa-chevron-right ml-1"></i> | |
| </a> | |
| </div> | |
| <div class="movie-grid" id="popularMoviesGrid"> | |
| <!-- Movie cards will be generated by JavaScript --> | |
| </div> | |
| </section> | |
| <!-- Full Catalog --> | |
| <section class="mb-12"> | |
| <div class="flex items-center justify-between mb-6"> | |
| <h2 class="text-2xl font-bold">Notre catalogue complet</h2> | |
| <div class="flex items-center gap-2"> | |
| <button id="sortButton" class="bg-gray-800 hover:bg-gray-700 text-white px-3 py-1 rounded text-sm flex items-center"> | |
| <i class="fas fa-sort mr-2"></i> Trier par | |
| </button> | |
| <button id="filterButton" class="bg-gray-800 hover:bg-gray-700 text-white px-3 py-1 rounded text-sm flex items-center"> | |
| <i class="fas fa-filter mr-2"></i> Filtrer | |
| </button> | |
| </div> | |
| </div> | |
| <div class="movie-grid" id="fullCatalogGrid"> | |
| <!-- Full catalog will be loaded here --> | |
| </div> | |
| <div class="mt-8 text-center"> | |
| <button id="loadMoreButton" class="bg-purple-600 hover:bg-purple-700 text-white font-medium py-2 px-6 rounded-full"> | |
| Charger plus de films | |
| </button> | |
| </div> | |
| </section> | |
| <!-- Genres --> | |
| <section class="mb-12"> | |
| <h2 class="text-2xl font-bold mb-6">Parcourir par genre</h2> | |
| <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4"> | |
| <a href="#" class="genre-pill bg-gradient-to-r from-red-600 to-pink-600 rounded-lg p-4 text-center cursor-pointer transition duration-300 hover:shadow-lg"> | |
| <i class="fas fa-heart text-2xl mb-2"></i> | |
| <h3 class="font-medium">Romance</h3> | |
| </a> | |
| <a href="#" class="genre-pill bg-gradient-to-r from-blue-600 to-indigo-600 rounded-lg p-4 text-center cursor-pointer transition duration-300 hover:shadow-lg"> | |
| <i class="fas fa-space-shuttle text-2xl mb-2"></i> | |
| <h3 class="font-medium">Science-fiction</h3> | |
| </a> | |
| <a href="#" class="genre-pill bg-gradient-to-r from-green-600 to-emerald-600 rounded-lg p-4 text-center cursor-pointer transition duration-300 hover:shadow-lg"> | |
| <i class="fas fa-laugh-beam text-2xl mb-2"></i> | |
| <h3 class="font-medium">Comédie</h3> | |
| </a> | |
| <a href="#" class="genre-pill bg-gradient-to-r from-yellow-600 to-amber-600 rounded-lg p-4 text-center cursor-pointer transition duration-300 hover:shadow-lg"> | |
| <i class="fas fa-bolt text-2xl mb-2"></i> | |
| <h3 class="font-medium">Action</h3> | |
| </a> | |
| <a href="#" class="genre-pill bg-gradient-to-r from-purple-600 to-fuchsia-600 rounded-lg p-4 text-center cursor-pointer transition duration-300 hover:shadow-lg"> | |
| <i class="fas fa-ghost text-2xl mb-2"></i> | |
| <h3 class="font-medium">Horreur</h3> | |
| </a> | |
| <a href="#" class="genre-pill bg-gradient-to-r from-gray-600 to-slate-600 rounded-lg p-4 text-center cursor-pointer transition duration-300 hover:shadow-lg"> | |
| <i class="fas fa-user-secret text-2xl mb-2"></i> | |
| <h3 class="font-medium">Thriller</h3> | |
| </a> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Floating Action Button --> | |
| <div class="fab" id="scrollToTop"> | |
| <i class="fas fa-arrow-up"></i> | |
| </div> | |
| <!-- Movie Details Modal --> | |
| <div class="movie-modal" id="movieModal"> | |
| <div class="max-w-6xl mx-auto p-4 sm:p-8"> | |
| <div class="flex justify-end mb-4"> | |
| <button id="closeModal" class="text-white hover:text-purple-400 text-3xl"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> | |
| <div class="lg:col-span-1"> | |
| <img id="modalPoster" src="" alt="Movie Poster" class="w-full rounded-lg shadow-xl"> | |
| </div> | |
| <div class="lg:col-span-2"> | |
| <h2 id="modalTitle" class="text-3xl font-bold mb-2"></h2> | |
| <div class="flex items-center mb-4"> | |
| <div class="rating-stars text-lg mr-2"> | |
| <span id="modalRating"></span> | |
| </div> | |
| <span class="text-gray-400 mr-4" id="modalYear"></span> | |
| <span class="text-gray-400" id="modalDuration"></span> | |
| </div> | |
| <div class="flex flex-wrap gap-2 mb-6" id="modalGenres"> | |
| <!-- Genres will be added here --> | |
| </div> | |
| <h3 class="text-xl font-semibold mb-2">Synopsis</h3> | |
| <p class="text-gray-300 mb-6" id="modalOverview"></p> | |
| <div class="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-6"> | |
| <div> | |
| <h4 class="text-gray-400">Réalisateur</h4> | |
| <p id="modalDirector" class="text-white">Christopher Nolan</p> | |
| </div> | |
| <div> | |
| <h4 class="text-gray-400">Acteurs</h4> | |
| <p id="modalCast" class="text-white">Leonardo DiCaprio, Joseph Gordon-Levitt, Ellen Page</p> | |
| </div> | |
| </div> | |
| <div class="flex gap-4"> | |
| <button id="playMovieBtn" class="bg-purple-600 hover:bg-purple-700 text-white font-medium py-2 px-6 rounded-full flex items-center"> | |
| <i class="fas fa-play mr-2"></i> Regarder | |
| </button> | |
| <button id="playMovieAutoBtn" class="bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-6 rounded-full flex items-center"> | |
| <i class="fas fa-bolt mr-2"></i> Mode Automatique | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Video Player --> | |
| <div id="videoPlayer" class="fixed inset-0 z-50 bg-black hidden flex flex-col"> | |
| <div class="absolute top-4 left-4 z-50"> | |
| <button id="closePlayer" class="text-white hover:text-purple-400 text-2xl"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="video-wrapper relative flex-grow"> | |
| <div class="video-container"> | |
| <iframe id="movieFrame" frameborder="0" allowfullscreen allow="autoplay; fullscreen"></iframe> | |
| </div> | |
| </div> | |
| <!-- Auto-play controls --> | |
| <div class="autoplay-controls" id="autoplayControls"> | |
| <button id="stopAutoplayBtn" class="autoplay-btn"> | |
| <i class="fas fa-stop mr-1"></i> Arrêter | |
| </button> | |
| <select id="playbackSpeed" class="autoplay-speed"> | |
| <option value="1">1x Vitesse</option> | |
| <option value="1.25">1.25x Vitesse</option> | |
| <option value="1.5">1.5x Vitesse</option> | |
| <option value="2">2x Vitesse</option> | |
| </select> | |
| </div> | |
| </div> | |
| <!-- Auto-play notification --> | |
| <div class="autoplay-notification" id="autoplayNotification"> | |
| <span id="countdownText">Lecture automatique dans <span id="countdown">5</span> secondes...</span> | |
| <button id="cancelAutoplay" class="ml-4 text-sm text-purple-300 hover:text-purple-100">Annuler</button> | |
| </div> | |
| <!-- Loading Overlay --> | |
| <div id="loadingOverlay" class="loading-overlay hidden"> | |
| <div class="text-center"> | |
| <div class="loading-spinner inline-block w-16 h-16 border-4 border-purple-500 border-t-transparent rounded-full mb-4"></div> | |
| <p class="text-white text-xl">Chargement du film...</p> | |
| </div> | |
| </div> | |
| <!-- Footer --> | |
| <footer class="bg-gray-900 text-gray-400 py-12 px-4 sm:px-6 lg:px-8"> | |
| <div class="max-w-7xl mx-auto"> | |
| <div class="grid grid-cols-2 md:grid-cols-4 gap-8"> | |
| <div> | |
| <h3 class="text-white text-lg font-semibold mb-4">Navigation</h3> | |
| <ul class="space-y-2"> | |
| <li><a href="#" class="hover:text-white">Accueil</a></li> | |
| <li><a href="#" class="hover:text-white">Films</a></li> | |
| <li><a href="#" class="hover:text-white">Séries</a></li> | |
| <li><a href="#" class="hover:text-white">Nouveautés</a></li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h3 class="text-white text-lg font-semibold mb-4">Informations</h3> | |
| <ul class="space-y-2"> | |
| <li><a href="#" class="hover:text-white">À propos</a></li> | |
| <li><a href="#" class="hover:text-white">Contact</a></li> | |
| <li><a href="#" class="hover:text-white">Presse</a></li> | |
| <li><a href="#" class="hover:text-white">Carrières</a></li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h3 class="text-white text-lg font-semibold mb-4">Légal</h3> | |
| <ul class="space-y-2"> | |
| <li><a href="#" class="hover:text-white">Conditions d'utilisation</a></li> | |
| <li><a href="#" class="hover:text-white">Confidentialité</a></li> | |
| <li><a href="#" class="hover:text-white">Cookies</a></li> | |
| <li><a href="#" class="hover:text-white">Mentions légales</a></li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h3 class="text-white text-lg font-semibold mb-4">Nous suivre</h3> | |
| <div class="flex space-x-4"> | |
| <a href="#" class="text-gray-400 hover:text-white"> | |
| <i class="fab fa-facebook-f text-xl"></i> | |
| </a> | |
| <a href="#" class="text-gray-400 hover:text-white"> | |
| <i class="fab fa-twitter text-xl"></i> | |
| </a> | |
| <a href="#" class="text-gray-400 hover:text-white"> | |
| <i class="fab fa-instagram text-xl"></i> | |
| </a> | |
| <a href="#" class="text-gray-400 hover:text-white"> | |
| <i class="fab fa-youtube text-xl"></i> | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="border-t border-gray-800 mt-8 pt-8 flex flex-col md:flex-row justify-between items-center"> | |
| <div class="mb-4 md:mb-0"> | |
| <span class="text-xl font-bold bg-gradient-to-r from-purple-600 to-blue-500 bg-clip-text text-transparent">CinéVerse</span> | |
| </div> | |
| <div class="text-sm"> | |
| © 2024 CinéVerse. Tous droits réservés. | |
| </div> | |
| </div> | |
| </div> | |
| </footer> | |
| <script> | |
| // Configuration de la base de données de films | |
| const movieDatabase = []; | |
| const totalMovies = 20500; | |
| // Variables pour le mode automatique | |
| let autoplayInterval; | |
| let currentAutoplayMovieIndex = 0; | |
| let isAutoplayActive = false; | |
| let playbackSpeed = 1; | |
| // Générateur de films avec des données réalistes | |
| const generateMovieDatabase = () => { | |
| const genres = [ | |
| {id: 28, name: "Action"}, | |
| {id: 12, name: "Aventure"}, | |
| {id: 16, name: "Animation"}, | |
| {id: 35, name: "Comédie"}, | |
| {id: 80, name: "Crime"}, | |
| {id: 18, name: "Drame"}, | |
| {id: 10751, name: "Familial"}, | |
| {id: 14, name: "Fantastique"}, | |
| {id: 36, name: "Histoire"}, | |
| {id: 27, name: "Horreur"}, | |
| {id: 10402, name: "Musique"}, | |
| {id: 9648, name: "Mystère"}, | |
| {id: 10749, name: "Romance"}, | |
| {id: 878, name: "Science-Fiction"}, | |
| {id: 53, name: "Thriller"} | |
| ]; | |
| const directors = [ | |
| "Christopher Nolan", "Steven Spielberg", "Martin Scorsese", | |
| "Quentin Tarantino", "David Fincher", "James Cameron", | |
| "Peter Jackson", "Ridley Scott", "Alfred Hitchcock", | |
| "Stanley Kubrick", "Francis Ford Coppola", "Tim Burton" | |
| ]; | |
| const actors = [ | |
| "Leonardo DiCaprio", "Tom Hanks", "Brad Pitt", "Robert Downey Jr.", | |
| "Johnny Depp", "Will Smith", "Denzel Washington", "Tom Cruise", | |
| "Matt Damon", "Christian Bale", "Morgan Freeman", "Samuel L. Jackson", | |
| "Harrison Ford", "Al Pacino", "Robert De Niro", "Meryl Streep", | |
| "Scarlett Johansson", "Jennifer Lawrence", "Emma Stone", "Natalie Portman" | |
| ]; | |
| const titles = [ | |
| "Inception", "The Dark Knight", "Interstellar", "Pulp Fiction", | |
| "Fight Club", "The Shawshank Redemption", "The Godfather", | |
| "Forrest Gump", "The Matrix", "Goodfellas", "The Silence of the Lambs", | |
| "Saving Private Ryan", "Gladiator", "Titanic", "Avatar", "Jurassic Park", | |
| "Star Wars", "The Lord of the Rings", "Harry Potter", "The Avengers" | |
| ]; | |
| const suffixes = [ | |
| "Le Retour", "La Revanche", "L'Héritage", "La Fin", | |
| "Le Commencement", "La Dernière Chance", "La Bataille Finale", | |
| "Les Origines", "La Menace", "L'Alliance", "La Prophétie" | |
| ]; | |
| for (let i = 0; i < totalMovies; i++) { | |
| const titleIndex = i % titles.length; | |
| const suffixIndex = i % suffixes.length; | |
| const genreCount = Math.floor(Math.random() * 3) + 1; | |
| const movieGenres = []; | |
| for (let j = 0; j < genreCount; j++) { | |
| const randomGenre = genres[Math.floor(Math.random() * genres.length)]; | |
| if (!movieGenres.some(g => g.id === randomGenre.id)) { | |
| movieGenres.push(randomGenre); | |
| } | |
| } | |
| // Créer un titre unique pour les films après les premiers | |
| let movieTitle = titles[titleIndex]; | |
| if (i >= titles.length) { | |
| movieTitle = `${titles[titleIndex]} : ${suffixes[suffixIndex]}`; | |
| } | |
| // Générer une date de sortie aléatoire entre 1950 et 2024 | |
| const year = Math.floor(Math.random() * (2024 - 1950 + 1)) + 1950; | |
| const month = Math.floor(Math.random() * 12) + 1; | |
| const day = Math.floor(Math.random() * 28) + 1; | |
| const releaseDate = `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`; | |
| // Générer une durée aléatoire entre 1h30 et 3h | |
| const hours = Math.floor(Math.random() * 2) + 1; | |
| const minutes = Math.floor(Math.random() * 60); | |
| const duration = `${hours}h ${minutes}min`; | |
| // Sélectionner aléatoirement un réalisateur et des acteurs | |
| const director = directors[Math.floor(Math.random() * directors.length)]; | |
| const cast = []; | |
| const actorCount = Math.floor(Math.random() * 4) + 2; | |
| for (let k = 0; k < actorCount; k++) { | |
| const randomActor = actors[Math.floor(Math.random() * actors.length)]; | |
| if (!cast.includes(randomActor)) { | |
| cast.push(randomActor); | |
| } | |
| } | |
| // Générer une note aléatoire entre 2.5 et 9.5 | |
| const rating = (Math.random() * 7 + 2.5).toFixed(1); | |
| // Créer l'objet film | |
| const movie = { | |
| id: i + 1, | |
| title: movieTitle, | |
| original_title: movieTitle, | |
| overview: `Un film captivant avec une histoire intrigante et des personnages mémorables. Réalisé par ${director} avec ${cast.join(", ")}.`, | |
| poster_path: `/posters/${(i % 20) + 1}.jpg`, // 20 posters différents en rotation | |
| backdrop_path: `/backdrops/${(i % 10) + 1}.jpg`, // 10 fonds différents en rotation | |
| release_date: releaseDate, | |
| vote_average: parseFloat(rating), | |
| vote_count: Math.floor(Math.random() * 10000), | |
| genre_ids: movieGenres.map(g => g.id), | |
| genres: movieGenres, | |
| popularity: Math.floor(Math.random() * 100), | |
| video: true, | |
| adult: Math.random() > 0.8, // 20% de chance d'être pour adultes | |
| duration: duration, | |
| director: director, | |
| cast: cast.join(", "), | |
| language: 'Français', | |
| isFeatured: i < 20, | |
| isTrending: i >= 20 && i < 40, | |
| isPopular: i >= 40 && i < 60, | |
| video_urls: { | |
| '1080': `https://example.com/videos/${i+1}/1080p.mp4`, | |
| '720': `https://example.com/videos/${i+1}/720p.mp4`, | |
| '480': `https://example.com/videos/${i+1}/480p.mp4` | |
| } | |
| }; | |
| movieDatabase.push(movie); | |
| } | |
| return movieDatabase; | |
| }; | |
| // Initialisation de la base de données | |
| generateMovieDatabase(); | |
| // Générer les cartes de films | |
| const generateMovieCard = (movie) => { | |
| // Utiliser des images de placeholder pour la démo | |
| const posterUrl = `https://via.placeholder.com/500x750?text=${encodeURIComponent(movie.title)}`; | |
| const backdropUrl = `https://via.placeholder.com/1280x720?text=${encodeURIComponent(movie.title)}`; | |
| return ` | |
| <div class="movie-card relative rounded-lg overflow-hidden transition duration-300" data-movie-id="${movie.id}"> | |
| <img src="${posterUrl}" alt="${movie.title}" class="w-full h-auto object-cover"> | |
| <div class="absolute inset-0 bg-gradient-to-t from-black/70 via-transparent to-transparent opacity-0 hover:opacity-100 transition duration-300 flex flex-col justify-end p-4"> | |
| <h3 class="text-white font-bold">${movie.title}</h3> | |
| <div class="flex items-center text-sm text-gray-300 mt-1"> | |
| <span>${movie.release_date.substring(0, 4)}</span> | |
| <span class="mx-2">•</span> | |
| <span>${movie.duration}</span> | |
| </div> | |
| <div class="flex mt-2"> | |
| ${movie.genres.slice(0, 2).map(genre => | |
| `<span class="text-xs bg-gray-800/80 text-white px-2 py-1 rounded mr-1">${genre.name}</span>` | |
| ).join('')} | |
| </div> | |
| <div class="flex items-center mt-2"> | |
| <div class="rating-stars text-sm mr-2"> | |
| ${'★'.repeat(Math.floor(movie.vote_average / 2))} | |
| </div> | |
| <span class="text-xs text-gray-300">${movie.vote_average}/10</span> | |
| </div> | |
| <div class="absolute inset-0 flex items-center justify-center"> | |
| <button class="play-icon opacity-0 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-purple-600 hover:bg-purple-700 text-white rounded-full w-12 h-12 flex items-center justify-center transition duration-300" | |
| data-movie-id="${movie.id}"> | |
| <i class="fas fa-play"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| }; | |
| // Afficher les détails d'un film dans la modal | |
| const showMovieDetails = (movie) => { | |
| // Utiliser des images de placeholder pour la démo | |
| const posterUrl = `https://via.placeholder.com/500x750?text=${encodeURIComponent(movie.title)}`; | |
| document.getElementById('modalPoster').src = posterUrl; | |
| document.getElementById('modalPoster').alt = movie.title; | |
| document.getElementById('modalTitle').textContent = movie.title; | |
| document.getElementById('modalRating').textContent = movie.vote_average; | |
| document.getElementById('modalYear').textContent = movie.release_date.substring(0, 4); | |
| document.getElementById('modalDuration').textContent = movie.duration; | |
| document.getElementById('modalOverview').textContent = movie.overview; | |
| document.getElementById('modalDirector').textContent = movie.director; | |
| document.getElementById('modalCast').textContent = movie.cast; | |
| // Mettre à jour les genres | |
| const genresContainer = document.getElementById('modalGenres'); | |
| genresContainer.innerHTML = ''; | |
| movie.genres.forEach(genre => { | |
| const genreElement = document.createElement('span'); | |
| genreElement.className = 'text-xs bg-gray-800 text-white px-3 py-1 rounded-full'; | |
| genreElement.textContent = genre.name; | |
| genresContainer.appendChild(genreElement); | |
| }); | |
| // Mettre à jour les boutons | |
| document.getElementById('playMovieBtn').setAttribute('data-movie-id', movie.id); | |
| document.getElementById('playMovieAutoBtn').setAttribute('data-movie-id', movie.id); | |
| // Afficher la modal | |
| document.getElementById('movieModal').classList.add('active'); | |
| document.body.style.overflow = 'hidden'; | |
| }; | |
| // Jouer un film | |
| const playMovie = (movieId, autoPlay = false) => { | |
| const movie = movieDatabase.find(m => m.id === movieId); | |
| if (!movie) return; | |
| const videoPlayer = document.getElementById('videoPlayer'); | |
| const movieFrame = document.getElementById('movieFrame'); | |
| const loadingOverlay = document.getElementById('loadingOverlay'); | |
| // Afficher le chargement | |
| loadingOverlay.classList.remove('hidden'); | |
| videoPlayer.classList.remove('hidden'); | |
| document.body.style.overflow = 'hidden'; | |
| // Pour la démo, nous utilisons une vidéo YouTube en placeholder | |
| // Dans une vraie application, vous utiliseriez movie.video_urls['1080'] ou autre qualité | |
| const trailerIds = [ | |
| 'kOHB85vDuow', // Inception | |
| 'EXeTwQWrcwY', // The Dark Knight | |
| 'zSWdZVtXT7E', // Interstellar | |
| 's7EdQ4FqbhY', // Pulp Fiction | |
| 'qtRKdVHc-cE' // Fight Club | |
| ]; | |
| const trailerId = trailerIds[movieId % trailerIds.length]; | |
| // Simuler un temps de chargement | |
| setTimeout(() => { | |
| movieFrame.src = `https://www.youtube.com/embed/${trailerId}?autoplay=1&mute=1&enablejsapi=1`; | |
| // Masquer le chargement après un délai | |
| setTimeout(() => { | |
| loadingOverlay.classList.add('hidden'); | |
| }, 1000); | |
| // Si autoPlay est activé, afficher la notification | |
| if (autoPlay) { | |
| showAutoplayNotification(movieId); | |
| } | |
| }, 800); | |
| }; | |
| // Afficher la notification de lecture automatique | |
| const showAutoplayNotification = (nextMovieId) => { | |
| const notification = document.getElementById('autoplayNotification'); | |
| const countdownElement = document.getElementById('countdown'); | |
| let seconds = 5; | |
| notification.style.display = 'flex'; | |
| countdownElement.textContent = seconds; | |
| const countdown = setInterval(() => { | |
| seconds--; | |
| countdownElement.textContent = seconds; | |
| if (seconds <= 0) { | |
| clearInterval(countdown); | |
| notification.style.display = 'none'; | |
| playMovie(nextMovieId, true); // Continuer le mode automatique | |
| } | |
| }, 1000); | |
| // Permettre à l'utilisateur d'annuler la lecture automatique | |
| document.getElementById('cancelAutoplay').onclick = () => { | |
| clearInterval(countdown); | |
| notification.style.display = 'none'; | |
| stopAutoplay(); | |
| }; | |
| }; | |
| // Démarrer le mode automatique | |
| const startAutoplay = (startingMovieId = null) => { | |
| isAutoplayActive = true; | |
| // Trouver l'index du film de départ | |
| if (startingMovieId) { | |
| currentAutoplayMovieIndex = movieDatabase.findIndex(m => m.id === startingMovieId); | |
| if (currentAutoplayMovieIndex === -1) currentAutoplayMovieIndex = 0; | |
| } else { | |
| currentAutoplayMovieIndex = 0; | |
| } | |
| // Afficher les contrôles de lecture automatique | |
| document.getElementById('autoplayControls').style.display = 'flex'; | |
| // Jouer le premier film | |
| playMovie(movieDatabase[currentAutoplayMovieIndex].id, true); | |
| }; | |
| // Arrêter le mode automatique | |
| const stopAutoplay = () => { | |
| isAutoplayActive = false; | |
| document.getElementById('autoplayControls').style.display = 'none'; | |
| if (autoplayInterval) { | |
| clearInterval(autoplayInterval); | |
| autoplayInterval = null; | |
| } | |
| }; | |
| // Initialisation de la page | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Charger les sections de films | |
| const newReleases = movieDatabase.filter(m => m.isFeatured); | |
| const trending = movieDatabase.filter(m => m.isTrending); | |
| const popularMovies = movieDatabase.filter(m => m.isPopular); | |
| // Fonction pour charger des films dans une grille | |
| const loadMoviesIntoGrid = (gridElement, movies, itemsPerPage = 20) => { | |
| gridElement.innerHTML = ''; | |
| movies.slice(0, itemsPerPage).forEach(movie => { | |
| const card = document.createElement('div'); | |
| card.innerHTML = generateMovieCard(movie); | |
| gridElement.appendChild(card); | |
| // Ajouter les événements de clic | |
| card.addEventListener('click', function() { | |
| showMovieDetails(movie); | |
| }); | |
| // Bouton de lecture | |
| const playButton = card.querySelector('.play-icon'); | |
| if (playButton) { | |
| playButton.addEventListener('click', function(e) { | |
| e.stopPropagation(); | |
| playMovie(movie.id); | |
| }); | |
| } | |
| }); | |
| }; | |
| // Charger les sections initiales | |
| loadMoviesIntoGrid(document.getElementById('newReleasesGrid'), newReleases); | |
| loadMoviesIntoGrid(document.getElementById('trendingGrid'), trending); | |
| loadMoviesIntoGrid(document.getElementById('popularMoviesGrid'), popularMovies); | |
| // Charger le catalogue complet | |
| loadMoviesIntoGrid(document.getElementById('fullCatalogGrid'), movieDatabase.slice(0, 40)); | |
| // Bouton "Commencer à regarder" (joue le premier film) | |
| document.getElementById('playFeaturedMovie').addEventListener('click', function() { | |
| playMovie(movieDatabase[0].id); | |
| }); | |
| // Bouton "Mode Automatique" (démarre la lecture automatique) | |
| document.getElementById('startAutoplay').addEventListener('click', function() { | |
| startAutoplay(); | |
| }); | |
| // Charger plus de films | |
| let currentPage = 1; | |
| const itemsPerPage = 40; | |
| document.getElementById('loadMoreButton').addEventListener('click', function() { | |
| currentPage++; | |
| const startIndex = (currentPage - 1) * itemsPerPage; | |
| const endIndex = startIndex + itemsPerPage; | |
| // Afficher le chargement | |
| const button = this; | |
| button.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Chargement...'; | |
| button.disabled = true; | |
| // Simuler un temps de chargement | |
| setTimeout(() => { | |
| // Ajouter les nouveaux films | |
| movieDatabase.slice(startIndex, endIndex).forEach(movie => { | |
| const card = document.createElement('div'); | |
| card.innerHTML = generateMovieCard(movie); | |
| document.getElementById('fullCatalogGrid').appendChild(card); | |
| // Ajouter les événements de clic | |
| card.addEventListener('click', function() { | |
| showMovieDetails(movie); | |
| }); | |
| }); | |
| // Réactiver le bouton | |
| button.textContent = 'Charger plus de films'; | |
| button.disabled = false; | |
| // Masquer le bouton si tous les films sont chargés | |
| if (endIndex >= movieDatabase.length) { | |
| button.style.display = 'none'; | |
| } | |
| }, 800); | |
| }); | |
| // Recherche | |
| document.getElementById('searchButton').addEventListener('click', function() { | |
| const searchTerm = document.getElementById('searchInput').value.toLowerCase(); | |
| if (searchTerm.trim() === '') return; | |
| const results = movieDatabase.filter(movie => | |
| movie.title.toLowerCase().includes(searchTerm) || | |
| movie.original_title.toLowerCase().includes(searchTerm) | |
| ).slice(0, 100); // Limiter à 100 résultats | |
| // Afficher les résultats | |
| loadMoviesIntoGrid(document.getElementById('fullCatalogGrid'), results); | |
| }); | |
| // Recherche avec la touche Entrée | |
| document.getElementById('searchInput').addEventListener('keypress', function(e) { | |
| if (e.key === 'Enter') { | |
| document.getElementById('searchButton').click(); | |
| } | |
| }); | |
| // Fermer la modal | |
| document.getElementById('closeModal').addEventListener('click', function() { | |
| document.getElementById('movieModal').classList.remove('active'); | |
| document.body.style.overflow = ''; | |
| }); | |
| // Jouer le film depuis la modal | |
| document.getElementById('playMovieBtn').addEventListener('click', function() { | |
| const movieId = parseInt(this.getAttribute('data-movie-id')); | |
| document.getElementById('movieModal').classList.remove('active'); | |
| playMovie(movieId); | |
| }); | |
| // Jouer en mode automatique depuis la modal | |
| document.getElementById('playMovieAutoBtn').addEventListener('click', function() { | |
| const movieId = parseInt(this.getAttribute('data-movie-id')); | |
| document.getElementById('movieModal').classList.remove('active'); | |
| startAutoplay(movieId); | |
| }); | |
| // Fermer le lecteur vidéo | |
| document.getElementById('closePlayer').addEventListener('click', function() { | |
| document.getElementById('videoPlayer').classList.add('hidden'); | |
| document.getElementById('movieFrame').src = ''; | |
| document.body.style.overflow = ''; | |
| stopAutoplay(); | |
| }); | |
| // Bouton de retour en haut | |
| document.getElementById('scrollToTop').addEventListener('click', function() { | |
| window.scrollTo({ | |
| top: 0, | |
| behavior: 'smooth' | |
| }); | |
| }); | |
| // Afficher/masquer le bouton de retour en haut | |
| window.addEventListener('scroll', function() { | |
| const scrollToTopBtn = document.getElementById('scrollToTop'); | |
| if (window.pageYOffset > 300) { | |
| scrollToTopBtn.style.display = 'flex'; | |
| } else { | |
| scrollToTopBtn.style.display = 'none'; | |
| } | |
| }); | |
| // Arrêter la lecture automatique | |
| document.getElementById('stopAutoplayBtn').addEventListener('click', function() { | |
| stopAutoplay(); | |
| }); | |
| // Changer la vitesse de lecture | |
| document.getElementById('playbackSpeed').addEventListener('change', function() { | |
| playbackSpeed = parseFloat(this.value); | |
| // Dans une vraie application, vous appliqueriez cette vitesse à la vidéo | |
| alert(`Vitesse de lecture changée à ${this.value}x (fonctionnalité de démonstration)`); | |
| }); | |
| // Simuler la fin de la vidéo et passer au film suivant | |
| window.onmessage = function(e) { | |
| if (e.data === 'videoEnded' && isAutoplayActive) { | |
| currentAutoplayMovieIndex = (currentAutoplayMovieIndex + 1) % movieDatabase.length; | |
| const nextMovieId = movieDatabase[currentAutoplayMovieIndex].id; | |
| showAutoplayNotification(nextMovieId); | |
| } | |
| }; | |
| }); | |
| </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=docto41/streamvista" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |