cin-flix / index.html
docto41's picture
Add 2 files
40aff0a verified
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CinéFlix - Films HD en Français</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;
}
.movie-card {
transition: all 0.3s ease;
transform-origin: center;
}
.movie-card:hover {
transform: scale(1.05);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
}
.movie-card:hover .play-icon {
opacity: 1;
}
.play-icon {
opacity: 0;
transition: opacity 0.3s ease;
}
.gradient-bg {
background: linear-gradient(135deg, #1e40af 0%, #7c3aed 100%);
}
.search-input:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.3);
}
.category-btn.active {
background-color: #3b82f6;
color: white;
}
/* Animation pour le chargement */
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.animate-pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
/* Style pour le robot */
.robot-status {
position: fixed;
bottom: 20px;
right: 20px;
background: rgba(30, 41, 59, 0.9);
border-radius: 10px;
padding: 10px 15px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
z-index: 100;
display: flex;
align-items: center;
}
.robot-icon {
margin-right: 10px;
color: #3b82f6;
}
.robot-loader {
width: 20px;
height: 20px;
border: 3px solid rgba(59, 130, 246, 0.2);
border-radius: 50%;
border-top-color: #3b82f6;
animation: spin 1s linear infinite;
margin-right: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Style pour les options de streaming */
.stream-option {
transition: all 0.3s ease;
}
.stream-option:hover {
background-color: #1e293b;
}
.quality-badge {
font-size: 0.75rem;
padding: 0.15rem 0.5rem;
border-radius: 0.25rem;
}
.quality-hd {
background-color: #3b82f6;
color: white;
}
.quality-fullhd {
background-color: #10b981;
color: white;
}
.quality-4k {
background-color: #f59e0b;
color: black;
}
.quality-1080p {
background-color: #8b5cf6;
color: white;
}
/* Pagination */
.pagination-btn {
padding: 0.5rem 1rem;
border-radius: 0.25rem;
background-color: #1e293b;
transition: all 0.3s ease;
}
.pagination-btn:hover {
background-color: #3b82f6;
}
.pagination-btn.active {
background-color: #3b82f6;
}
/* Database stats */
.stats-card {
background: rgba(30, 41, 59, 0.7);
border-radius: 0.5rem;
padding: 1rem;
backdrop-filter: blur(10px);
}
/* Badge pour liens vérifiés */
.verified-badge {
background-color: #10b981;
color: white;
font-size: 0.65rem;
padding: 0.15rem 0.4rem;
border-radius: 0.25rem;
margin-left: 0.5rem;
}
/* Style pour les serveurs actifs */
.server-active {
position: relative;
}
.server-active::after {
content: '';
position: absolute;
top: 0;
right: 0;
width: 8px;
height: 8px;
background-color: #10b981;
border-radius: 50%;
}
</style>
</head>
<body class="text-gray-100">
<!-- Header -->
<header class="gradient-bg py-4 shadow-lg">
<div class="container mx-auto px-4 flex justify-between items-center">
<div class="flex items-center space-x-2">
<i class="fas fa-film text-2xl text-white"></i>
<h1 class="text-2xl font-bold">CinéFlix FR</h1>
</div>
<div class="relative w-1/3">
<input type="text" placeholder="Rechercher un film..."
class="search-input w-full py-2 px-4 rounded-full bg-gray-800 text-white focus:ring-2 focus:ring-blue-500">
<button class="absolute right-3 top-2 text-gray-400">
<i class="fas fa-search"></i>
</button>
</div>
<div class="flex items-center space-x-4">
<button class="px-4 py-2 rounded-full bg-blue-600 hover:bg-blue-700 transition">
<i class="fas fa-user mr-2"></i>Connexion
</button>
<button class="p-2 rounded-full bg-gray-800 hover:bg-gray-700 transition">
<i class="fas fa-cog"></i>
</button>
</div>
</div>
</header>
<!-- Main Content -->
<main class="container mx-auto px-4 py-8">
<!-- Database Stats -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
<div class="stats-card">
<div class="flex items-center space-x-3">
<div class="p-3 rounded-full bg-blue-500/20 text-blue-500">
<i class="fas fa-film text-xl"></i>
</div>
<div>
<p class="text-gray-400 text-sm">Films en base</p>
<p class="text-xl font-bold" id="total-movies">142,555</p>
</div>
</div>
</div>
<div class="stats-card">
<div class="flex items-center space-x-3">
<div class="p-3 rounded-full bg-green-500/20 text-green-500">
<i class="fas fa-link text-xl"></i>
</div>
<div>
<p class="text-gray-400 text-sm">Liens disponibles</p>
<p class="text-xl font-bold" id="total-links">124,556</p>
</div>
</div>
</div>
<div class="stats-card">
<div class="flex items-center space-x-3">
<div class="p-3 rounded-full bg-purple-500/20 text-purple-500">
<i class="fas fa-server text-xl"></i>
</div>
<div>
<p class="text-gray-400 text-sm">Serveurs actifs</p>
<p class="text-xl font-bold" id="active-servers">28</p>
</div>
</div>
</div>
</div>
<!-- Serveurs actifs -->
<div class="mb-6 bg-gray-800 rounded-lg p-4">
<h3 class="text-lg font-bold mb-3 flex items-center">
<i class="fas fa-server text-blue-500 mr-2"></i> Serveurs actifs
</h3>
<div class="flex flex-wrap gap-2" id="active-servers-list">
<!-- Les serveurs seront chargés ici -->
</div>
</div>
<!-- Categories -->
<div class="mb-8 overflow-x-auto">
<div class="flex space-x-2 pb-2">
<button class="category-btn active px-4 py-2 rounded-full bg-gray-800 hover:bg-gray-700 transition whitespace-nowrap">
Tous les films
</button>
<button class="category-btn px-4 py-2 rounded-full bg-gray-800 hover:bg-gray-700 transition whitespace-nowrap">
Action
</button>
<button class="category-btn px-4 py-2 rounded-full bg-gray-800 hover:bg-gray-700 transition whitespace-nowrap">
Comédie
</button>
<button class="category-btn px-4 py-2 rounded-full bg-gray-800 hover:bg-gray-700 transition whitespace-nowrap">
Science-fiction
</button>
<button class="category-btn px-4 py-2 rounded-full bg-gray-800 hover:bg-gray-700 transition whitespace-nowrap">
Horreur
</button>
<button class="category-btn px-4 py-2 rounded-full bg-gray-800 hover:bg-gray-700 transition whitespace-nowrap">
Animation
</button>
<button class="category-btn px-4 py-2 rounded-full bg-gray-800 hover:bg-gray-700 transition whitespace-nowrap">
Thriller
</button>
</div>
</div>
<!-- Featured Movie -->
<div class="relative rounded-xl overflow-hidden mb-10 h-96">
<div class="absolute inset-0 bg-gradient-to-r from-gray-900 to-transparent z-10"></div>
<img src="https://image.tmdb.org/t/p/original/8Vt6mWEReuy4Of61Lnj5Xj704m8.jpg"
alt="Film à l'affiche" class="w-full h-full object-cover">
<div class="absolute bottom-0 left-0 z-20 p-8 w-1/2">
<h2 class="text-4xl font-bold mb-2">Dune: Partie Deux</h2>
<div class="flex items-center mb-4 space-x-4">
<span class="bg-yellow-500 text-black px-2 py-1 rounded text-sm font-bold">VF</span>
<span class="bg-yellow-500 text-black px-2 py-1 rounded text-sm font-bold">HD</span>
<span class="text-gray-300">2024</span>
<span class="text-gray-300">2h46min</span>
<span class="text-gray-300">Science-fiction</span>
</div>
<p class="text-gray-300 mb-6">Paul Atreides s'unît à Chani et aux Fremen tout en préparant sa revanche contre ceux qui ont détruit sa famille. Alors qu'il doit choisir entre l'amour de sa vie et le destin de l'univers, il devra empêcher un terrible futur que lui seul peut prévoir.</p>
<div class="flex space-x-4">
<button id="watch-featured" class="px-6 py-3 bg-blue-600 hover:bg-blue-700 rounded-lg font-medium flex items-center">
<i class="fas fa-play mr-2"></i> Regarder
</button>
<button class="px-6 py-3 bg-gray-800 hover:bg-gray-700 rounded-lg font-medium flex items-center">
<i class="fas fa-info-circle mr-2"></i> Plus d'infos
</button>
</div>
</div>
</div>
<!-- Movies Grid -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6 flex items-center">
<i class="fas fa-fire mr-3 text-red-500"></i> Films populaires en VF
</h2>
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-6" id="movies-grid">
<!-- Les films seront chargés ici par JavaScript -->
</div>
<!-- Pagination -->
<div class="flex justify-center mt-8 space-x-2">
<button class="pagination-btn"><i class="fas fa-chevron-left"></i></button>
<button class="pagination-btn active">1</button>
<button class="pagination-btn">2</button>
<button class="pagination-btn">3</button>
<button class="pagination-btn">4</button>
<button class="pagination-btn">5</button>
<button class="pagination-btn"><i class="fas fa-chevron-right"></i></button>
</div>
</section>
<!-- Loading Skeleton -->
<div id="loading-skeleton" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-6">
<div class="animate-pulse">
<div class="bg-gray-800 rounded-lg h-64 mb-2"></div>
<div class="h-4 bg-gray-800 rounded w-3/4 mb-2"></div>
<div class="h-3 bg-gray-800 rounded w-1/2"></div>
</div>
<div class="animate-pulse">
<div class="bg-gray-800 rounded-lg h-64 mb-2"></div>
<div class="h-4 bg-gray-800 rounded w-3/4 mb-2"></div>
<div class="h-3 bg-gray-800 rounded w-1/2"></div>
</div>
<div class="animate-pulse">
<div class="bg-gray-800 rounded-lg h-64 mb-2"></div>
<div class="h-4 bg-gray-800 rounded w-3/4 mb-2"></div>
<div class="h-3 bg-gray-800 rounded w-1/2"></div>
</div>
<div class="animate-pulse">
<div class="bg-gray-800 rounded-lg h-64 mb-2"></div>
<div class="h-4 bg-gray-800 rounded w-3/4 mb-2"></div>
<div class="h-3 bg-gray-800 rounded w-1/2"></div>
</div>
<div class="animate-pulse">
<div class="bg-gray-800 rounded-lg h-64 mb-2"></div>
<div class="h-4 bg-gray-800 rounded w-3/4 mb-2"></div>
<div class="h-3 bg-gray-800 rounded w-1/2"></div>
</div>
<div class="animate-pulse">
<div class="bg-gray-800 rounded-lg h-64 mb-2"></div>
<div class="h-4 bg-gray-800 rounded w-3/4 mb-2"></div>
<div class="h-3 bg-gray-800 rounded w-1/2"></div>
</div>
</div>
</main>
<!-- Footer -->
<footer class="bg-gray-900 py-8">
<div class="container mx-auto px-4">
<div class="grid grid-cols-1 md:grid-cols-4 gap-8">
<div>
<h3 class="text-xl font-bold mb-4">CinéFlix FR</h3>
<p class="text-gray-400">La meilleure plateforme pour regarder des films en VF et haute qualité gratuitement.</p>
</div>
<div>
<h4 class="font-bold mb-4">Navigation</h4>
<ul class="space-y-2">
<li><a href="#" class="text-gray-400 hover:text-white">Accueil</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Films VF</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Séries VF</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Nouveautés</a></li>
</ul>
</div>
<div>
<h4 class="font-bold mb-4">Légal</h4>
<ul class="space-y-2">
<li><a href="#" class="text-gray-400 hover:text-white">Conditions d'utilisation</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">Politique de confidentialité</a></li>
<li><a href="#" class="text-gray-400 hover:text-white">DMCA</a></li>
</ul>
</div>
<div>
<h4 class="font-bold mb-4">Contact</h4>
<div class="flex space-x-4 mb-4">
<a href="#" class="text-gray-400 hover:text-white text-2xl"><i class="fab fa-facebook"></i></a>
<a href="#" class="text-gray-400 hover:text-white text-2xl"><i class="fab fa-twitter"></i></a>
<a href="#" class="text-gray-400 hover:text-white text-2xl"><i class="fab fa-instagram"></i></a>
<a href="#" class="text-gray-400 hover:text-white text-2xl"><i class="fab fa-telegram"></i></a>
</div>
<p class="text-gray-400">contact@cineflix-fr.com</p>
</div>
</div>
<div class="border-t border-gray-800 mt-8 pt-8 text-center text-gray-500">
<p>© 2023 CinéFlix FR. Tous droits réservés.</p>
</div>
</div>
</footer>
<!-- Robot Status -->
<div id="robot-status" class="robot-status hidden">
<div class="robot-loader"></div>
<span id="robot-message">Recherche de liens en cours...</span>
</div>
<!-- Movie Player Modal -->
<div id="player-modal" class="fixed inset-0 bg-black bg-opacity-90 z-50 hidden flex items-center justify-center p-4">
<div class="relative w-full max-w-6xl bg-gray-900 rounded-xl overflow-hidden">
<button id="close-modal" class="absolute -top-10 right-0 text-white text-2xl hover:text-blue-500">
<i class="fas fa-times"></i>
</button>
<div class="flex flex-col lg:flex-row">
<!-- Player Section -->
<div class="w-full lg:w-2/3">
<div class="aspect-w-16 aspect-h-9 bg-black">
<iframe id="movie-player" class="w-full h-96 lg:h-full" src="" frameborder="0" allowfullscreen allow="autoplay"></iframe>
</div>
<div class="p-4">
<h3 id="movie-title" class="text-2xl font-bold text-white"></h3>
<div class="flex items-center mt-2 space-x-4">
<span id="movie-quality" class="bg-blue-500 text-white px-2 py-1 rounded text-xs font-bold"></span>
<span id="movie-year" class="text-gray-300"></span>
<span id="movie-duration" class="text-gray-300"></span>
</div>
<p id="movie-description" class="text-gray-300 mt-4"></p>
</div>
</div>
<!-- Streaming Options Section -->
<div class="w-full lg:w-1/3 bg-gray-800 p-4 overflow-y-auto max-h-96 lg:max-h-full">
<h4 class="text-lg font-bold mb-4 flex items-center">
<i class="fas fa-link mr-2 text-blue-500"></i> Options de streaming
<span class="ml-auto text-xs text-gray-400" id="last-updated">Dernière vérification: maintenant</span>
</h4>
<div id="streaming-options" class="space-y-3">
<!-- Les options de streaming seront ajoutées ici -->
</div>
</div>
</div>
</div>
</div>
<script>
// Simulateur de base de données massive avec mise à jour automatique
class MovieDatabase {
constructor() {
this.totalMovies = 142555;
this.totalLinks = 124556;
this.activeServers = 28;
this.cachedMovies = [];
this.cachedLinks = {};
this.genres = [
"Action", "Aventure", "Animation", "Comédie", "Crime",
"Documentaire", "Drama", "Familial", "Fantastique",
"Histoire", "Horreur", "Musique", "Mystère", "Romance",
"Science-fiction", "Téléfilm", "Thriller", "Guerre", "Western"
];
this.qualities = ["HD", "FullHD", "4K", "1080p"];
this.languages = ["VF", "VOSTFR", "VO"];
// Serveurs de streaming populaires
this.streamingServers = [
{ name: "VidCloud", url: "https://vidcloud.com", active: true, lastChecked: new Date() },
{ name: "UpStream", url: "https://upstream.to", active: true, lastChecked: new Date() },
{ name: "DoodStream", url: "https://doodstream.com", active: true, lastChecked: new Date() },
{ name: "StreamTape", url: "https://streamtape.com", active: true, lastChecked: new Date() },
{ name: "MixDrop", url: "https://mixdrop.co", active: true, lastChecked: new Date() },
{ name: "FileMoon", url: "https://filemoon.sx", active: true, lastChecked: new Date() },
{ name: "VidSrc", url: "https://vidsrc.me", active: true, lastChecked: new Date() },
{ name: "SuperEmbed", url: "https://multiembed.mov", active: true, lastChecked: new Date() }
];
// Initialiser avec quelques films populaires
this.popularMovies = this.generatePopularMovies(50);
// Vérifier l'état des serveurs périodiquement
this.checkServersStatus();
setInterval(() => this.checkServersStatus(), 3600000); // Toutes les heures
}
// Vérifier l'état des serveurs
async checkServersStatus() {
const robotStatus = document.getElementById('robot-status');
const robotMessage = document.getElementById('robot-message');
if (robotStatus) {
robotStatus.classList.remove('hidden');
robotMessage.textContent = "Vérification des serveurs en cours...";
}
// Simuler la vérification des serveurs
await new Promise(resolve => setTimeout(resolve, 2000));
// Mettre à jour aléatoirement l'état des serveurs (simulation)
this.streamingServers.forEach(server => {
// 10% de chance qu'un serveur devienne inactif
if (Math.random() < 0.1) {
server.active = false;
} else {
server.active = true;
}
server.lastChecked = new Date();
});
// Compter les serveurs actifs
this.activeServers = this.streamingServers.filter(s => s.active).length;
// Mettre à jour l'affichage
this.updateServerStatusUI();
if (robotStatus) {
robotMessage.textContent = `Mise à jour terminée - ${this.activeServers} serveurs actifs`;
setTimeout(() => robotStatus.classList.add('hidden'), 2000);
}
}
// Mettre à jour l'interface des serveurs
updateServerStatusUI() {
const activeServersElement = document.getElementById('active-servers');
const activeServersList = document.getElementById('active-servers-list');
if (activeServersElement) {
activeServersElement.textContent = this.activeServers;
}
if (activeServersList) {
activeServersList.innerHTML = '';
this.streamingServers.forEach(server => {
const serverElement = document.createElement('div');
serverElement.className = `px-3 py-2 rounded-full ${server.active ? 'bg-green-900/50 text-green-400 server-active' : 'bg-red-900/50 text-red-400'}`;
serverElement.innerHTML = `
<i class="fas fa-server mr-1"></i>
${server.name}
${server.active ? '<span class="verified-badge">Actif</span>' : '<span class="bg-red-500 text-white text-xs px-1 rounded ml-1">Inactif</span>'}
`;
activeServersList.appendChild(serverElement);
});
}
}
// Générer des films populaires pour l'affichage initial
generatePopularMovies(count) {
const movies = [];
const baseYear = new Date().getFullYear();
for (let i = 0; i < count; i++) {
const year = baseYear - Math.floor(Math.random() * 5);
const durationHours = Math.floor(Math.random() * 2) + 1;
const durationMinutes = Math.floor(Math.random() * 60);
const genre = this.genres[Math.floor(Math.random() * this.genres.length)];
const quality = this.qualities[Math.floor(Math.random() * this.qualities.length)];
const language = this.languages[Math.floor(Math.random() * this.languages.length)];
movies.push({
id: i + 1,
title: `Film Populaire ${i + 1}`,
year: year,
duration: `${durationHours}h${durationMinutes.toString().padStart(2, '0')}min`,
genre: genre,
quality: quality,
language: language,
image: `https://image.tmdb.org/t/p/w500/${this.getRandomImageId()}.jpg`,
description: `Description du film populaire ${i + 1}. Un film ${genre.toLowerCase()} sorti en ${year}.`,
streamingLinks: this.generateRandomLinks(1 + Math.floor(Math.random() * 4))
});
}
return movies;
}
// Générer des ID d'image aléatoires pour TMDB
getRandomImageId() {
const prefixes = ["8Vt6mWEReuy4Of61Lnj5Xj704m8", "8Gxv8gSFCU0XGDykEGv7zR1n2ua",
"seyWFgGInaLqW7nOZvu0ZC95rtx", "jRXYjXNq0Cs2TcJjLkki24MLp7u",
"vZloFAK7NmvMGKE7VkF5UHaz0I", "NNxYkU70HPurnNCSiCjYAmacwm",
"4HodYYKEIsGOdinkGi2Ucz6X9i0", "iuFNMS8U5cb6xfzi51Dbkovj7vM",
"dB6Krk806zeqd0YNp2ngQ9zXteH", "kCGlIMHnOm8JPXq3rXM6c5wMxcT",
"qNBAXBIQlnOThrVvA6mA2HG5S2m", "r2J02Z2OpNTctfOSN1Ydgii51I3",
"fiVW06jE7z9YnO4trhaMEdclSiC", "rktDFPbfHfUbArZ6OOOKsXcv0Bm",
"6oH378KUfCEitzJkm7r0gBWn7GC"];
return prefixes[Math.floor(Math.random() * prefixes.length)];
}
// Générer des liens de streaming aléatoires avec vérification
generateRandomLinks(count) {
const links = [];
const activeServers = this.streamingServers.filter(s => s.active);
if (activeServers.length === 0) return links;
for (let i = 0; i < count; i++) {
const quality = this.qualities[Math.floor(Math.random() * this.qualities.length)];
const server = activeServers[Math.floor(Math.random() * activeServers.length)];
const isVerified = Math.random() > 0.3; // 70% de chance d'être vérifié
links.push({
url: `${server.url}/embed/movie-${Math.floor(Math.random() * 100000)}?autoplay=1`,
quality: quality,
source: server.name,
type: "iframe",
verified: isVerified,
lastChecked: new Date()
});
}
return links;
}
// Recherche de films (simulation)
async searchMovies(query, page = 1, limit = 24) {
// Simuler un délai de requête
await new Promise(resolve => setTimeout(resolve, 300 + Math.random() * 700));
// Si pas de requête, retourner les films populaires paginés
if (!query) {
const start = (page - 1) * limit;
const end = start + limit;
return {
movies: this.popularMovies.slice(start, end),
total: this.popularMovies.length
};
}
// Sinon, simuler une recherche
const filtered = this.popularMovies.filter(movie =>
movie.title.toLowerCase().includes(query.toLowerCase()) ||
movie.genre.toLowerCase().includes(query.toLowerCase())
);
const start = (page - 1) * limit;
const end = start + limit;
return {
movies: filtered.slice(start, end),
total: filtered.length
};
}
// Obtenir les liens pour un film avec vérification automatique
async getStreamingLinks(movieId) {
// Simuler un délai de recherche
await new Promise(resolve => setTimeout(resolve, 500 + Math.random() * 1500));
// Si le film existe dans le cache, retourner ses liens
const cachedMovie = this.popularMovies.find(m => m.id === movieId);
if (cachedMovie) {
// Vérifier et mettre à jour les liens
const updatedLinks = cachedMovie.streamingLinks.map(link => {
// 10% de chance qu'un lien devienne invalide
const isStillValid = Math.random() > 0.1;
return {
...link,
verified: isStillValid ? link.verified : false,
lastChecked: new Date()
};
});
// Filtrer les liens invalides
return updatedLinks.filter(link => link.verified);
}
// Sinon, générer des liens aléatoires avec vérification
return this.generateRandomLinks(2 + Math.floor(Math.random() * 3));
}
// Obtenir les statistiques de la base de données
getStats() {
return {
totalMovies: this.totalMovies,
totalLinks: this.totalLinks,
activeServers: this.activeServers
};
}
}
// Initialiser la base de données
const movieDB = new MovieDatabase();
const linkFinder = movieDB; // Utiliser la même instance pour la recherche de liens
// Afficher les statistiques
function displayStats() {
const stats = movieDB.getStats();
document.getElementById('total-movies').textContent = stats.totalMovies.toLocaleString();
document.getElementById('total-links').textContent = stats.totalLinks.toLocaleString();
document.getElementById('active-servers').textContent = stats.activeServers;
// Mettre à jour l'état des serveurs
movieDB.updateServerStatusUI();
}
// Fonction pour afficher les films
async function displayMovies(page = 1) {
const moviesGrid = document.getElementById('movies-grid');
const loadingSkeleton = document.getElementById('loading-skeleton');
// Afficher le squelette de chargement
moviesGrid.innerHTML = '';
loadingSkeleton.style.display = 'grid';
// Récupérer les films
const { movies, total } = await movieDB.searchMovies('', page);
// Cacher le squelette et afficher les films
loadingSkeleton.style.display = 'none';
movies.forEach(movie => {
const movieCard = document.createElement('div');
movieCard.className = 'movie-card';
movieCard.innerHTML = `
<div class="block relative group" data-movie-id="${movie.id}">
<img src="${movie.image}" alt="${movie.title}"
class="w-full h-64 object-cover rounded-lg mb-2">
<div class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center opacity-0 group-hover:opacity-100 transition">
<div class="play-icon bg-blue-600 rounded-full p-4">
<i class="fas fa-play text-white text-xl"></i>
</div>
</div>
<div class="absolute top-2 left-2 bg-yellow-500 text-black px-2 py-1 rounded text-xs font-bold">
${movie.quality}
</div>
<div class="absolute top-2 right-2 bg-blue-500 text-white px-2 py-1 rounded text-xs font-bold">
${movie.language}
</div>
</div>
<h3 class="font-semibold truncate">${movie.title}</h3>
<div class="flex justify-between text-sm text-gray-400">
<span>${movie.year}</span>
<span>${movie.duration}</span>
</div>
`;
moviesGrid.appendChild(movieCard);
// Ajouter l'événement de clic pour trouver et afficher les liens
movieCard.querySelector('.group').addEventListener('click', async () => {
await showMovieLinks(movie.id);
});
});
// Mettre à jour la pagination
updatePagination(page, Math.ceil(total / 24));
}
// Afficher les liens de streaming pour un film
async function showMovieLinks(movieId) {
// Trouver le film dans la base
const movie = movieDB.popularMovies.find(m => m.id === movieId);
if (!movie) return;
// Afficher le modal avec les options de streaming
const modal = document.getElementById('player-modal');
const player = document.getElementById('movie-player');
const title = document.getElementById('movie-title');
const quality = document.getElementById('movie-quality');
const year = document.getElementById('movie-year');
const duration = document.getElementById('movie-duration');
const description = document.getElementById('movie-description');
const streamingOptions = document.getElementById('streaming-options');
const lastUpdated = document.getElementById('last-updated');
title.textContent = movie.title;
quality.textContent = movie.quality;
year.textContent = movie.year;
duration.textContent = movie.duration;
description.textContent = movie.description;
// Vider les options précédentes
streamingOptions.innerHTML = '';
// Afficher un message de chargement
streamingOptions.innerHTML = '<div class="text-center py-4"><div class="robot-loader mx-auto"></div><p class="mt-2">Chargement des options...</p></div>';
// Obtenir les liens de streaming
const links = await linkFinder.getStreamingLinks(movieId);
// Mettre à jour la date de dernière vérification
const now = new Date();
lastUpdated.textContent = `Dernière vérification: ${now.toLocaleTimeString()}`;
// Vider à nouveau après le chargement
streamingOptions.innerHTML = '';
if (links.length === 0) {
streamingOptions.innerHTML = `
<div class="text-center py-4 text-red-400">
<i class="fas fa-exclamation-triangle text-2xl mb-2"></i>
<p>Aucun lien valide trouvé pour ce film.</p>
<button class="mt-4 px-4 py-2 bg-blue-600 rounded hover:bg-blue-700" onclick="retryFindLinks(${movieId})">
<i class="fas fa-sync-alt mr-2"></i> Réessayer
</button>
</div>
`;
return;
}
// Ajouter toutes les options de streaming disponibles
links.forEach((link, index) => {
const option = document.createElement('div');
option.className = `stream-option p-3 rounded-lg ${index === 0 ? 'border-blue-500 border-2' : 'bg-gray-700'} cursor-pointer flex justify-between items-center`;
option.innerHTML = `
<div>
<div class="font-medium flex items-center">
${link.source}
${link.verified ? '<span class="verified-badge">Vérifié</span>' : ''}
</div>
<div class="text-xs text-gray-400">${link.type === 'iframe' ? 'Lecture directe' : 'Lien externe'}</div>
</div>
<span class="quality-badge ${getQualityClass(link.quality)}">${link.quality}</span>
`;
option.addEventListener('click', () => {
// Mettre à jour le lecteur avec le nouveau lien
player.src = link.url;
quality.textContent = link.quality;
// Mettre en surbrillance l'option sélectionnée
document.querySelectorAll('.stream-option').forEach(opt => {
opt.classList.remove('border-blue-500', 'border-2');
opt.classList.add('bg-gray-700');
});
option.classList.add('border-blue-500', 'border-2');
option.classList.remove('bg-gray-700');
});
streamingOptions.appendChild(option);
});
// Utiliser le premier lien disponible par défaut et démarrer automatiquement
if (links.length > 0) {
player.src = links[0].url;
quality.textContent = links[0].quality;
// Forcer le démarrage automatique
setTimeout(() => {
player.src = links[0].url + "&autoplay=1";
}, 100);
}
modal.classList.remove('hidden');
document.body.style.overflow = 'hidden';
}
// Réessayer de trouver des liens
async function retryFindLinks(movieId) {
await showMovieLinks(movieId);
}
// Obtenir la classe CSS pour la qualité
function getQualityClass(quality) {
switch(quality.toLowerCase()) {
case 'hd': return 'quality-hd';
case 'fullhd': return 'quality-fullhd';
case '4k': return 'quality-4k';
case '1080p': return 'quality-1080p';
default: return 'quality-hd';
}
}
// Mettre à jour la pagination
function updatePagination(currentPage, totalPages) {
const paginationContainer = document.querySelector('.flex.justify-center.mt-8.space-x-2');
if (!paginationContainer) return;
// Limiter à 5 pages affichées autour de la page courante
let startPage = Math.max(1, currentPage - 2);
let endPage = Math.min(totalPages, currentPage + 2);
// Ajuster si nous sommes près du début ou de la fin
if (currentPage <= 3) {
endPage = Math.min(5, totalPages);
} else if (currentPage >= totalPages - 2) {
startPage = Math.max(totalPages - 4, 1);
}
// Générer les boutons de pagination
let paginationHTML = `
<button class="pagination-btn" onclick="changePage(${currentPage - 1})" ${currentPage === 1 ? 'disabled' : ''}>
<i class="fas fa-chevron-left"></i>
</button>
`;
for (let i = startPage; i <= endPage; i++) {
paginationHTML += `
<button class="pagination-btn ${i === currentPage ? 'active' : ''}" onclick="changePage(${i})">
${i}
</button>
`;
}
paginationHTML += `
<button class="pagination-btn" onclick="changePage(${currentPage + 1})" ${currentPage === totalPages ? 'disabled' : ''}>
<i class="fas fa-chevron-right"></i>
</button>
`;
paginationContainer.innerHTML = paginationHTML;
}
// Changer de page
function changePage(page) {
displayMovies(page);
}
// Gestion des catégories
function setupCategoryButtons() {
const buttons = document.querySelectorAll('.category-btn');
buttons.forEach(button => {
button.addEventListener('click', () => {
buttons.forEach(btn => btn.classList.remove('active'));
button.classList.add('active');
// Filtrer les films par catégorie
const category = button.textContent.trim();
filterMoviesByCategory(category);
});
});
}
// Filtrer les films par catégorie
async function filterMoviesByCategory(category) {
const moviesGrid = document.getElementById('movies-grid');
const loadingSkeleton = document.getElementById('loading-skeleton');
moviesGrid.innerHTML = '';
loadingSkeleton.style.display = 'grid';
if (category === 'Tous les films') {
displayMovies();
return;
}
// Simuler un délai de filtrage
await new Promise(resolve => setTimeout(resolve, 800));
const { movies } = await movieDB.searchMovies(category);
loadingSkeleton.style.display = 'none';
movies.forEach(movie => {
const movieCard = document.createElement('div');
movieCard.className = 'movie-card';
movieCard.innerHTML = `
<div class="block relative group" data-movie-id="${movie.id}">
<img src="${movie.image}" alt="${movie.title}"
class="w-full h-64 object-cover rounded-lg mb-2">
<div class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center opacity-0 group-hover:opacity-100 transition">
<div class="play-icon bg-blue-600 rounded-full p-4">
<i class="fas fa-play text-white text-xl"></i>
</div>
</div>
<div class="absolute top-2 left-2 bg-yellow-500 text-black px-2 py-1 rounded text-xs font-bold">
${movie.quality}
</div>
<div class="absolute top-2 right-2 bg-blue-500 text-white px-2 py-1 rounded text-xs font-bold">
${movie.language}
</div>
</div>
<h3 class="font-semibold truncate">${movie.title}</h3>
<div class="flex justify-between text-sm text-gray-400">
<span>${movie.year}</span>
<span>${movie.duration}</span>
</div>
`;
moviesGrid.appendChild(movieCard);
// Ajouter l'événement de clic
movieCard.querySelector('.group').addEventListener('click', async () => {
await showMovieLinks(movie.id);
});
});
}
// Initialisation
document.addEventListener('DOMContentLoaded', () => {
displayStats();
displayMovies();
setupCategoryButtons();
// Gestion de la recherche
const searchInput = document.querySelector('.search-input');
let searchTimeout;
searchInput.addEventListener('input', async (e) => {
clearTimeout(searchTimeout);
const searchTerm = e.target.value.trim();
if (searchTerm.length < 2) {
displayMovies();
return;
}
searchTimeout = setTimeout(async () => {
const moviesGrid = document.getElementById('movies-grid');
const loadingSkeleton = document.getElementById('loading-skeleton');
moviesGrid.innerHTML = '';
loadingSkeleton.style.display = 'grid';
const { movies } = await movieDB.searchMovies(searchTerm);
loadingSkeleton.style.display = 'none';
movies.forEach(movie => {
const movieCard = document.createElement('div');
movieCard.className = 'movie-card';
movieCard.innerHTML = `
<div class="block relative group" data-movie-id="${movie.id}">
<img src="${movie.image}" alt="${movie.title}"
class="w-full h-64 object-cover rounded-lg mb-2">
<div class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center opacity-0 group-hover:opacity-100 transition">
<div class="play-icon bg-blue-600 rounded-full p-4">
<i class="fas fa-play text-white text-xl"></i>
</div>
</div>
<div class="absolute top-2 left-2 bg-yellow-500 text-black px-2 py-1 rounded text-xs font-bold">
${movie.quality}
</div>
<div class="absolute top-2 right-2 bg-blue-500 text-white px-2 py-1 rounded text-xs font-bold">
${movie.language}
</div>
</div>
<h3 class="font-semibold truncate">${movie.title}</h3>
<div class="flex justify-between text-sm text-gray-400">
<span>${movie.year}</span>
<span>${movie.duration}</span>
</div>
`;
moviesGrid.appendChild(movieCard);
// Ajouter l'événement de clic
movieCard.querySelector('.group').addEventListener('click', async () => {
await showMovieLinks(movie.id);
});
});
}, 500);
});
// Gestion du bouton "Regarder" du film en vedette
document.getElementById('watch-featured').addEventListener('click', async () => {
await showMovieLinks(1); // ID du film en vedette (Dune 2)
});
// Fermer le modal
document.getElementById('close-modal').addEventListener('click', () => {
const modal = document.getElementById('player-modal');
const player = document.getElementById('movie-player');
modal.classList.add('hidden');
document.body.style.overflow = 'auto';
player.src = ''; // Arrêter la vidéo
});
});
// Exposer les fonctions globalement
window.changePage = changePage;
window.retryFindLinks = retryFindLinks;
</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/cin-flix" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>