File size: 28,961 Bytes
8fd4798
 
 
1
2
3
<!DOCTYPE html> <html lang="fr"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <title>Live Vidéo - Système de Partage</title>     <style>         body {             font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;             margin: 0;             padding: 0;             background-color: #f5f5f5;         }         .container {             max-width: 1200px;             margin: 0 auto;             padding: 20px;         }         .header {             text-align: center;             margin-bottom: 30px;         }         .main-content {             display: flex;             flex-direction: column;             gap: 20px;         }         .login-section, .video-section, .control-section {             background-color: white;             border-radius: 8px;             padding: 20px;             box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);         }         .video-container {             display: grid;             grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));             gap: 15px;             margin-top: 20px;         }         .video-box {             position: relative;             border-radius: 8px;             overflow: hidden;             aspect-ratio: 16/9;         }         video {             width: 100%;             height: 100%;             object-fit: cover;             background-color: #222;         }         .username {             position: absolute;             bottom: 10px;             left: 10px;             background-color: rgba(0, 0, 0, 0.5);             color: white;             padding: 5px 10px;             border-radius: 4px;             font-size: 14px;         }         .input-group {             display: flex;             margin-bottom: 15px;         }         input {             flex-grow: 1;             padding: 10px;             border: 1px solid #ddd;             border-radius: 4px;             font-size: 16px;         }         button {             padding: 10px 20px;             background-color: #4285f4;             color: white;             border: none;             border-radius: 4px;             cursor: pointer;             font-size: 16px;             transition: background-color 0.3s;         }         button:hover {             background-color: #3367d6;         }         .controls {             display: flex;             gap: 10px;             margin-top: 15px;         }         .btn-danger {             background-color: #ea4335;         }         .btn-danger:hover {             background-color: #d33426;         }         .copy-link {             display: flex;             margin-top: 15px;             background-color: #f8f9fa;             padding: 10px;             border-radius: 4px;             align-items: center;         }         .copy-link input {             margin-right: 10px;         }         .participants {             margin-top: 15px;         }         .participant-list {             max-height: 200px;             overflow-y: auto;         }         .status-indicator {             display: inline-block;             width: 10px;             height: 10px;             border-radius: 50%;             margin-right: 5px;         }         .status-online {             background-color: #34a853;         }         .status-offline {             background-color: #ea4335;         }         .hidden {             display: none;         }         .modal {             position: fixed;             top: 0;             left: 0;             width: 100%;             height: 100%;             background-color: rgba(0, 0, 0, 0.5);             display: flex;             justify-content: center;             align-items: center;             z-index: 1000;         }         .modal-content {             background-color: white;             padding: 30px;             border-radius: 8px;             max-width: 500px;             width: 100%;         }         .modal-header {             display: flex;             justify-content: space-between;             align-items: center;             margin-bottom: 20px;         }         .close {             cursor: pointer;             font-size: 24px;         }         .text-center {             text-align: center;         }         .text-success {             color: #34a853;         }     </style> </head> <body>     <div class="container">         <div class="header">             <h1>Plateforme de Live Vidéo</h1>         </div>                  <div class="main-content">             <!-- Section de connexion -->             <div class="login-section" id="login-section">                 <h2>Rejoindre ou créer un live</h2>                 <div class="input-group">                     <input type="text" id="username" placeholder="Votre nom" required>                 </div>                 <div class="input-group">                     <input type="text" id="room-code" placeholder="Code de la salle">                     <button id="join-btn" style="margin-left: 10px;">Rejoindre</button>                 </div>                 <div>                     <button id="create-btn">Créer un nouveau live</button>                 </div>             </div>                          <!-- Section vidéo - cachée au départ -->             <div class="video-section hidden" id="video-section">                 <h2>Live en cours: <span id="room-display"></span></h2>                 <div class="video-container" id="videos">                     <div class="video-box">                         <video id="local-video" autoplay muted playsinline></video>                         <div class="username">Vous</div>                     </div>                 </div>                                  <div class="controls">                     <button id="toggle-video">Désactiver vidéo</button>                     <button id="toggle-audio">Désactiver audio</button>                     <button id="share-screen">Partager écran</button>                     <button class="btn-danger" id="leave-btn">Quitter</button>                 </div>             </div>                          <!-- Section contrôle (uniquement pour le créateur) -->             <div class="control-section hidden" id="host-controls">                 <h2>Contrôles du live</h2>                 <div class="copy-link">                     <input type="text" id="invite-link" readonly>                     <button id="copy-btn">Copier le lien</button>                 </div>                 <div class="participants">                     <h3>Participants (<span id="participant-count">1</span>)</h3>                     <div class="participant-list" id="participant-list">                         <!-- Les participants seront ajoutés ici dynamiquement -->                     </div>                 </div>             </div>         </div>     </div>          <!-- Modales -->     <div id="create-room-modal" class="modal hidden">         <div class="modal-content">             <div class="modal-header">                 <h2>Créer un nouveau live</h2>                 <span class="close">&times;</span>             </div>             <p>Choisissez un code pour votre salle (ou laissez vide pour un code généré automatiquement)</p>             <div class="input-group">                 <input type="text" id="new-room-code" placeholder="Code de la salle (optionnel)">             </div>             <button id="confirm-create">Créer et rejoindre</button>         </div>     </div>      <div id="notification-modal" class="modal hidden">         <div class="modal-content">             <div class="modal-header">                 <h2 id="notification-title">Notification</h2>                 <span class="close">&times;</span>             </div>             <p id="notification-message"></p>             <div class="text-center">                 <button id="notification-confirm">OK</button>             </div>         </div>     </div>      <!-- Inclusion de Firebase et PeerJS -->     <script src="https://cdnjs.cloudflare.com/ajax/libs/firebase/9.17.1/firebase-app-compat.min.js"></script>     <script src="https://cdnjs.cloudflare.com/ajax/libs/firebase/9.17.1/firebase-database-compat.min.js"></script>     <script src="https://cdnjs.cloudflare.com/ajax/libs/peerjs/1.4.7/peerjs.min.js"></script>          <script>         // Configuration de Firebase - À REMPLACER PAR VOS PROPRES IDENTIFIANTS         const firebaseConfig = {             apiKey: "VOTRE_API_KEY",             authDomain: "VOTRE_AUTH_DOMAIN",             databaseURL: "VOTRE_DATABASE_URL",             projectId: "VOTRE_PROJECT_ID",             storageBucket: "VOTRE_STORAGE_BUCKET",             messagingSenderId: "VOTRE_MESSAGING_SENDER_ID",             appId: "VOTRE_APP_ID"         };                  // Initialisation de Firebase         firebase.initializeApp(firebaseConfig);         const database = firebase.database();                  // Variables globales         let localStream = null;         let peers = {};         let isHost = false;         let roomCode = "";         let username = "";         let myPeer = null;         let videoEnabled = true;         let audioEnabled = true;         let screenShareStream = null;                  // Éléments DOM         const loginSection = document.getElementById('login-section');         const videoSection = document.getElementById('video-section');         const hostControls = document.getElementById('host-controls');         const usernameInput = document.getElementById('username');         const roomCodeInput = document.getElementById('room-code');         const joinBtn = document.getElementById('join-btn');         const createBtn = document.getElementById('create-btn');         const roomDisplay = document.getElementById('room-display');         const toggleVideoBtn = document.getElementById('toggle-video');         const toggleAudioBtn = document.getElementById('toggle-audio');         const shareScreenBtn = document.getElementById('share-screen');         const leaveBtn = document.getElementById('leave-btn');         const inviteLink = document.getElementById('invite-link');         const copyBtn = document.getElementById('copy-btn');         const participantCount = document.getElementById('participant-count');         const participantList = document.getElementById('participant-list');         const createRoomModal = document.getElementById('create-room-modal');         const newRoomCodeInput = document.getElementById('new-room-code');         const confirmCreateBtn = document.getElementById('confirm-create');         const notificationModal = document.getElementById('notification-modal');         const notificationTitle = document.getElementById('notification-title');         const notificationMessage = document.getElementById('notification-message');         const notificationConfirm = document.getElementById('notification-confirm');         const localVideo = document.getElementById('local-video');         const videosContainer = document.getElementById('videos');                  // Fonction pour générer un code de salle aléatoire         function generateRoomCode() {             return Math.random().toString(36).substring(2, 8).toUpperCase();         }                  // Afficher une notification         function showNotification(title, message) {             notificationTitle.textContent = title;             notificationMessage.textContent = message;             notificationModal.classList.remove('hidden');         }                  // Rejoindre une salle         async function joinRoom(code) {             if (!username) {                 showNotification("Erreur", "Veuillez entrer votre nom pour rejoindre.");                 return;             }                          if (!code) {                 showNotification("Erreur", "Veuillez entrer un code de salle.");                 return;             }                          roomCode = code.toUpperCase();                          // Vérifier si la salle existe             const roomRef = database.ref(`rooms/${roomCode}`);             const snapshot = await roomRef.once('value');                          if (!snapshot.exists() && !isHost) {                 showNotification("Erreur", "Cette salle n'existe pas. Veuillez vérifier le code.");                 return;             }                          // Initialiser le flux vidéo local             try {                 localStream = await navigator.mediaDevices.getUserMedia({                     video: true,                     audio: true                 });                                  // Afficher la vidéo locale                 localVideo.srcObject = localStream;                                  // Masquer la section de connexion et afficher la section vidéo                 loginSection.classList.add('hidden');                 videoSection.classList.remove('hidden');                                  if (isHost) {                     hostControls.classList.remove('hidden');                                          // Créer la salle dans Firebase                     await roomRef.set({                         host: username,                         created: firebase.database.ServerValue.TIMESTAMP                     });                                          // Générer le lien d'invitation                     const currentUrl = window.location.href.split('?')[0];                     inviteLink.value = `${currentUrl}?room=${roomCode}`;                 }                                  // Mettre à jour l'affichage du code de salle                 roomDisplay.textContent = roomCode;                                  // Initialiser PeerJS                 initializePeerConnection();                                  // S'inscrire comme participant                 const participantRef = database.ref(`rooms/${roomCode}/participants/${myPeer.id}`);                 participantRef.set({                     username: username,                     joined: firebase.database.ServerValue.TIMESTAMP                 });                                  // Supprimer le participant lorsqu'il se déconnecte                 participantRef.onDisconnect().remove();                                  // Si c'est l'hôte, supprimer la salle lorsqu'il se déconnecte                 if (isHost) {                     roomRef.onDisconnect().remove();                 }                                  // Écouter les participants                 listenForParticipants();             } catch (error) {                 console.error("Erreur lors de l'accès à la caméra et au micro:", error);                 showNotification("Erreur", "Impossible d'accéder à la caméra ou au microphone. Veuillez vérifier vos autorisations.");             }         }                  // Initialiser la connexion PeerJS         function initializePeerConnection() {             // Générer un ID unique pour ce peer             const peerId = `${roomCode}-${Date.now()}-${Math.random().toString(36).substring(2, 10)}`;                          myPeer = new Peer(peerId, {                 debug: 3             });                          myPeer.on('open', (id) => {                 console.log('Mon ID PeerJS:', id);             });                          // Gérer les appels entrants             myPeer.on('call', (call) => {                 // Répondre avec notre flux vidéo                 call.answer(localStream);                                  // Ajouter la vidéo distante à notre interface                 call.on('stream', (remoteStream) => {                     addVideoStream(call.peer, remoteStream);                 });                                  // Gérer la déconnexion                 call.on('close', () => {                     removeVideoStream(call.peer);                 });                                  // Stocker l'appel                 peers[call.peer] = call;             });                          myPeer.on('error', (err) => {                 console.error('Erreur PeerJS:', err);                 showNotification("Erreur de connexion", `Une erreur s'est produite: ${err.message}`);             });         }                  // Appeler un nouveau participant         function connectToNewUser(userId, stream) {             const call = myPeer.call(userId, stream);                          call.on('stream', (remoteStream) => {                 addVideoStream(userId, remoteStream);             });                          call.on('close', () => {                 removeVideoStream(userId);             });                          peers[userId] = call;         }                  // Ajouter un flux vidéo à l'interface         function addVideoStream(userId, stream) {             // Vérifier si ce flux existe déjà             if (document.getElementById(`video-${userId}`)) {                 return;             }                          // Créer les éléments pour la vidéo             const videoBox = document.createElement('div');             videoBox.className = 'video-box';             videoBox.id = `video-container-${userId}`;                          const video = document.createElement('video');             video.id = `video-${userId}`;             video.srcObject = stream;             video.autoplay = true;             video.playsinline = true;                          // Obtenir le nom du participant             database.ref(`rooms/${roomCode}/participants/${userId}`).once('value', (snapshot) => {                 const participant = snapshot.val();                 if (participant) {                     const usernameDiv = document.createElement('div');                     usernameDiv.className = 'username';                     usernameDiv.textContent = participant.username;                     videoBox.appendChild(usernameDiv);                 }             });                          videoBox.appendChild(video);             videosContainer.appendChild(videoBox);         }                  // Supprimer un flux vidéo de l'interface         function removeVideoStream(userId) {             const videoContainer = document.getElementById(`video-container-${userId}`);             if (videoContainer) {                 videoContainer.remove();             }                          // Supprimer l'appel             if (peers[userId]) {                 peers[userId].close();                 delete peers[userId];             }         }                  // Écouter les participants         function listenForParticipants() {             const participantsRef = database.ref(`rooms/${roomCode}/participants`);                          participantsRef.on('child_added', (snapshot) => {                 const participant = snapshot.val();                 const participantId = snapshot.key;                                  // Mettre à jour la liste des participants                 updateParticipantList();                                  // Si c'est un nouveau participant et que je suis déjà connecté                 if (participantId !== myPeer.id && localStream) {                     // L'appeler pour établir la connexion                     connectToNewUser(participantId, localStream);                 }             });                          participantsRef.on('child_removed', (snapshot) => {                 const participantId = snapshot.key;                                  // Mettre à jour la liste des participants                 updateParticipantList();                                  // Supprimer la vidéo                 removeVideoStream(participantId);             });         }                  // Mettre à jour la liste des participants         function updateParticipantList() {             const participantsRef = database.ref(`rooms/${roomCode}/participants`);                          participantsRef.once('value', (snapshot) => {                 // Vider la liste                 participantList.innerHTML = '';                                  const participants = snapshot.val() || {};                 const count = Object.keys(participants).length;                                  // Mettre à jour le compteur                 participantCount.textContent = count;                                  // Ajouter chaque participant à la liste                 Object.entries(participants).forEach(([id, data]) => {                     const participantItem = document.createElement('div');                     participantItem.innerHTML = `                         <span class="status-indicator status-online"></span>                         ${data.username} ${id === myPeer.id ? '(vous)' : ''}                     `;                     participantList.appendChild(participantItem);                 });             });         }                  // Quitter la salle         function leaveRoom() {             // Arrêter tous les flux             if (localStream) {                 localStream.getTracks().forEach(track => track.stop());             }                          if (screenShareStream) {                 screenShareStream.getTracks().forEach(track => track.stop());             }                          // Fermer toutes les connexions             Object.values(peers).forEach(call => call.close());             peers = {};                          // Supprimer le participant             if (myPeer && roomCode) {                 database.ref(`rooms/${roomCode}/participants/${myPeer.id}`).remove();             }                          // Fermer la connexion PeerJS             if (myPeer) {                 myPeer.destroy();             }                          // Réinitialiser les variables             myPeer = null;             localStream = null;             screenShareStream = null;             isHost = false;             roomCode = "";                          // Réafficher la section de connexion             videoSection.classList.add('hidden');             hostControls.classList.add('hidden');             loginSection.classList.remove('hidden');                          // Vider le conteneur de vidéos (sauf la vidéo locale)             const videos = document.querySelectorAll('.video-box:not(:first-child)');             videos.forEach(video => video.remove());                          // Réinitialiser la vidéo locale             localVideo.srcObject = null;         }                  // Événements         joinBtn.addEventListener('click', () => {             username = usernameInput.value.trim();             const code = roomCodeInput.value.trim().toUpperCase();                          if (username && code) {                 isHost = false;                 joinRoom(code);             } else {                 showNotification("Informations manquantes", "Veuillez entrer votre nom et le code de la salle.");             }         });                  createBtn.addEventListener('click', () => {             username = usernameInput.value.trim();                          if (username) {                 isHost = true;                 createRoomModal.classList.remove('hidden');             } else {                 showNotification("Nom manquant", "Veuillez entrer votre nom pour créer une salle.");             }         });                  confirmCreateBtn.addEventListener('click', () => {             const customCode = newRoomCodeInput.value.trim().toUpperCase();             const code = customCode || generateRoomCode();                          createRoomModal.classList.add('hidden');             joinRoom(code);         });                  toggleVideoBtn.addEventListener('click', () => {             if (localStream) {                 const videoTracks = localStream.getVideoTracks();                 videoTracks.forEach(track => {                     track.enabled = !track.enabled;                 });                                  videoEnabled = videoTracks[0]?.enabled || false;                 toggleVideoBtn.textContent = videoEnabled ? "Désactiver vidéo" : "Activer vidéo";             }         });                  toggleAudioBtn.addEventListener('click', () => {             if (localStream) {                 const audioTracks = localStream.getAudioTracks();                 audioTracks.forEach(track => {                     track.enabled = !track.enabled;                 });                                  audioEnabled = audioTracks[0]?.enabled || false;                 toggleAudioBtn.textContent = audioEnabled ? "Désactiver audio" : "Activer audio";             }         });                  shareScreenBtn.addEventListener('click', async () => {             try {                 if (!screenShareStream) {                     // Commencer le partage d'écran                     screenShareStream = await navigator.mediaDevices.getDisplayMedia({                         video: true                     });                                          // Remplacer le flux vidéo local par le partage d'écran                     const videoTrack = screenShareStream.getVideoTracks()[0];                     const sender = Object.values(peers).forEach(peer => {                         const senders = peer._pc.getSenders();                         const videoSender = senders.find(s => s.track && s.track.kind === 'video');                         if (videoSender) {                             videoSender.replaceTrack(videoTrack);                         }                     });                                          // Mettre à jour l'affichage local                     localVideo.srcObject = screenShareStream;                                          // Arrêter le partage d'écran lorsque l'utilisateur arrête                     videoTrack.onended = () => {                         stopScreenSharing();                     };                                          shareScreenBtn.textContent = "Arrêter le partage";                 } else {                     stopScreenSharing();                 }             } catch (error) {                 console.error("Erreur lors du partage d'écran:", error);                 showNotification("Erreur", "Impossible de partager l'écran. Veuillez réessayer.");             }         });                  function stopScreenSharing() {             if (screenShareStream) {                 screenShareStream.getTracks().forEach(track => track.stop());                                  // Rétablir la vidéo de la caméra                 const videoTrack = localStream.getVideoTracks()[0];                 if (videoTrack) {                     Object.values(peers).forEach(peer => {                         const senders = peer._pc.getSenders();                         const videoSender = senders.find(s => s.track && s.track.kind === 'video');                         if (videoSender) {                             videoSender.replaceTrack(videoTrack);                         }                     });                                          // Rétablir l'affichage local                     localVideo.srcObject = localStream;                 }                                  screenShareStream = null;                 shareScreenBtn.textContent = "Partager écran";             }         }                  leaveBtn.addEventListener('click', () => {             leaveRoom();         });                  copyBtn.addEventListener('click', () => {             inviteLink.select();             document.execCommand('copy');                          // Afficher une confirmation             copyBtn.textContent = "Copié !";             setTimeout(() => {                 copyBtn.textContent = "Copier le lien";             }, 2000);         });                  // Fermer les modales         document.querySelectorAll('.close').forEach(closeBtn => {             closeBtn.addEventListener('click', () => {                 createRoomModal.classList.add('hidden');                 notificationModal.classList.add('hidden');             });         });                  notificationConfirm.addEventListener('click', () => {             notificationModal.classList.add('hidden');         });                  // Vérifier s'il y a un code de salle dans l'URL         window.addEventListener('load', () => {             const urlParams = new URLSearchParams(window.location.search);             const roomParam = urlParams.get('room');                          if (roomParam) {                 roomCodeInput.value = roomParam;                 // Focus sur le champ nom                 usernameInput.focus();             }         });                  // Gérer la déconnexion à la fermeture de la page         window.addEventListener('beforeunload', () => {             leaveRoom();         });     </script> </body> </html> ...Le code pour intégrer le live est 1234
Corrigé les erreurs et fait en sorte que tout les boutons fonctionnent code a234
Les boutons ne sont pas aligné et partage d'écran ne fonctionne pas