w

Exemples de Code

Exemples d'implémentation et code d'échantillon pour le Lecteur M3U8 en Ligne.

Exemple HTML/JavaScript de Base

Lecteur Simple

<!DOCTYPE html>
<html lang="fr">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Lecteur M3U8 - Exemple de Base</title>
    <link href="https://vjs.zencdn.net/8.6.1/video-js.css" rel="stylesheet" />
  </head>
  <body>
    <div class="container">
      <h1>Lecteur de Stream M3U8</h1>

      <!-- Conteneur du Lecteur -->
      <video-js
        id="m3u8-player"
        class="vjs-default-skin"
        controls
        preload="auto"
        width="800"
        height="450"
        data-setup="{}"
      >
        <p class="vjs-no-js">
          Pour lire cette vidéo, activez JavaScript.
          <a href="https://videojs.com/html5-video-support/" target="_blank">
            Navigateurs compatibles avec Video.js </a
          >.
        </p>
      </video-js>

      <!-- Panneau de Contrôle -->
      <div class="controls">
        <input type="url" id="stream-url" placeholder="Entrez l'URL M3U8" />
        <button id="load-btn">Charger</button>
        <button id="play-btn">Lire</button>
        <button id="pause-btn">Pause</button>
      </div>

      <!-- Informations -->
      <div class="info">
        <p>Temps actuel: <span id="current-time">0:00</span></p>
        <p>Durée: <span id="duration">0:00</span></p>
        <p>Qualité: <span id="quality">Automatique</span></p>
      </div>
    </div>

    <script src="https://vjs.zencdn.net/8.6.1/video.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@videojs/http-streaming@3.0.2/dist/videojs-http-streaming.min.js"></script>
    <script>
      // Initialiser le lecteur
      const player = videojs('m3u8-player', {
        html5: {
          vhs: {
            overrideNative: true,
          },
        },
      });

      // Obtenir les éléments DOM
      const streamUrlInput = document.getElementById('stream-url');
      const loadBtn = document.getElementById('load-btn');
      const playBtn = document.getElementById('play-btn');
      const pauseBtn = document.getElementById('pause-btn');
      const currentTimeSpan = document.getElementById('current-time');
      const durationSpan = document.getElementById('duration');
      const qualitySpan = document.getElementById('quality');

      // Configurer les écouteurs d'événements
      loadBtn.addEventListener('click', loadStream);
      playBtn.addEventListener('click', () => player.play());
      pauseBtn.addEventListener('click', () => player.pause());

      // Fonction pour charger le stream
      function loadStream() {
        const url = streamUrlInput.value.trim();
        if (!url) {
          alert('Veuillez entrer une URL');
          return;
        }

        try {
          player.src({
            src: url,
            type: 'application/x-mpegURL',
          });
          console.log('Stream chargé:', url);
        } catch (error) {
          console.error('Erreur lors du chargement du stream:', error);
          alert('Erreur lors du chargement du stream');
        }
      }

      // Fonction pour formater le temps
      function formatTime(seconds) {
        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor((seconds % 3600) / 60);
        const secs = Math.floor(seconds % 60);

        if (hours > 0) {
          return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
        } else {
          return `${minutes}:${secs.toString().padStart(2, '0')}`;
        }
      }

      // Surveiller les événements du lecteur
      player.on('loadedmetadata', () => {
        durationSpan.textContent = formatTime(player.duration());
      });

      player.on('timeupdate', () => {
        currentTimeSpan.textContent = formatTime(player.currentTime());
      });

      player.on('error', (error) => {
        console.error('Erreur du lecteur:', error);
        alert('Erreur de lecture');
      });

      // Configurer l'URL d'exemple
      streamUrlInput.value =
        'https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8';
    </script>
  </body>
</html>

Exemple de Fonctionnalités Avancées

Sélection de Qualité et Gestion d'Erreurs

<!DOCTYPE html>
<html lang="fr">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Lecteur M3U8 - Exemple Avancé</title>
    <link href="https://vjs.zencdn.net/8.6.1/video-js.css" rel="stylesheet" />
    <style>
      .quality-selector {
        margin: 10px 0;
      }
      .quality-selector select {
        padding: 5px;
        margin-right: 10px;
      }
      .error-message {
        color: red;
        margin: 10px 0;
      }
      .stats {
        background: #f5f5f5;
        padding: 10px;
        margin: 10px 0;
        border-radius: 5px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1>Lecteur M3U8 - Fonctionnalités Avancées</h1>

      <video-js
        id="advanced-player"
        class="vjs-default-skin"
        controls
        preload="auto"
        width="800"
        height="450"
        data-setup="{}"
      >
      </video-js>

      <!-- Sélecteur de Qualité -->
      <div class="quality-selector">
        <label for="quality-select">Sélectionner la Qualité:</label>
        <select id="quality-select">
          <option value="auto">Automatique</option>
        </select>
      </div>

      <!-- Message d'Erreur -->
      <div id="error-message" class="error-message" style="display: none;"></div>

      <!-- Informations de Statistiques -->
      <div class="stats">
        <h3>Informations de Statistiques</h3>
        <p>Débit actuel: <span id="current-bitrate">-</span></p>
        <p>Santé du buffer: <span id="buffer-health">-</span></p>
        <p>État du réseau: <span id="network-state">-</span></p>
      </div>
    </div>

    <script src="https://vjs.zencdn.net/8.6.1/video.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@videojs/http-streaming@3.0.2/dist/videojs-http-streaming.min.js"></script>
    <script>
      // Initialiser le lecteur
      const player = videojs('advanced-player', {
        html5: {
          vhs: {
            overrideNative: true,
            enableLowInitialPlaylist: true,
            smoothQualityChange: true,
          },
        },
      });

      const qualitySelect = document.getElementById('quality-select');
      const errorMessage = document.getElementById('error-message');
      const currentBitrateSpan = document.getElementById('current-bitrate');
      const bufferHealthSpan = document.getElementById('buffer-health');
      const networkStateSpan = document.getElementById('network-state');

      // Charger le stream d'exemple
      player.src({
        src: 'https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8',
        type: 'application/x-mpegURL',
      });

      // Quand les niveaux de qualité sont disponibles
      player.on('loadedmetadata', () => {
        updateQualityOptions();
      });

      // Mettre à jour les options de qualité
      function updateQualityOptions() {
        const hls = player.tech().hls;
        if (hls && hls.levels) {
          // Nettoyer les options existantes
          qualitySelect.innerHTML = '<option value="auto">Automatique</option>';

          // Ajouter les niveaux de qualité
          hls.levels.forEach((level, index) => {
            const option = document.createElement('option');
            option.value = index;
            option.textContent = `${level.height}p (${Math.round(level.bitrate / 1000)}kbps)`;
            qualitySelect.appendChild(option);
          });
        }
      }

      // Changer la qualité
      qualitySelect.addEventListener('change', (e) => {
        const hls = player.tech().hls;
        if (hls) {
          if (e.target.value === 'auto') {
            hls.currentLevel = -1; // Qualité automatique
          } else {
            hls.currentLevel = parseInt(e.target.value);
          }
        }
      });

      // Gestion des erreurs
      player.on('error', (error) => {
        console.error('Erreur du lecteur:', error);
        showError(`Erreur survenue: ${error.message || 'Erreur inconnue'}`);

        // Tenter une récupération automatique
        setTimeout(() => {
          if (player.error()) {
            player.error(null);
            player.load();
          }
        }, 3000);
      });

      // Afficher le message d'erreur
      function showError(message) {
        errorMessage.textContent = message;
        errorMessage.style.display = 'block';
        setTimeout(() => {
          errorMessage.style.display = 'none';
        }, 5000);
      }

      // Mettre à jour les informations de statistiques
      function updateStats() {
        const hls = player.tech().hls;
        if (hls) {
          const currentLevel = hls.levels[hls.currentLevel];
          if (currentLevel) {
            currentBitrateSpan.textContent = `${Math.round(currentLevel.bitrate / 1000)}kbps`;
          }

          // Calculer la santé du buffer
          const buffered = player.buffered();
          const currentTime = player.currentTime();
          const duration = player.duration();

          if (buffered.length > 0) {
            const bufferedEnd = buffered.end(buffered.length - 1);
            const bufferHealth = ((bufferedEnd - currentTime) / duration) * 100;
            bufferHealthSpan.textContent = `${bufferHealth.toFixed(1)}%`;
          }
        }

        // État du réseau
        const networkState = player.networkState();
        const states = ['État initial', 'Inactif', 'Chargement', 'Aucune source'];
        networkStateSpan.textContent = states[networkState] || 'Inconnu';
      }

      // Mettre à jour les statistiques périodiquement
      setInterval(updateStats, 1000);

      // Mettre à jour les statistiques initiales
      player.on('canplay', updateStats);
    </script>
  </body>
</html>

Exemple de Composant React

Lecteur M3U8 en React

import React, { useEffect, useRef, useState } from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css';

const M3U8Player = ({ src, options = {} }) => {
  const videoRef = useRef(null);
  const playerRef = useRef(null);
  const [error, setError] = useState(null);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    // Initialiser le lecteur
    if (videoRef.current && !playerRef.current) {
      const videoElement = videoRef.current;

      const playerOptions = {
        controls: true,
        responsive: true,
        fluid: true,
        html5: {
          vhs: {
            overrideNative: true,
            enableLowInitialPlaylist: true,
            smoothQualityChange: true,
          },
        },
        ...options,
      };

      playerRef.current = videojs(videoElement, playerOptions);

      // Gestion des erreurs
      playerRef.current.on('error', (error) => {
        console.error('Erreur du lecteur:', error);
        setError('Erreur de lecture');
      });

      // Début du chargement
      playerRef.current.on('loadstart', () => {
        setIsLoading(true);
        setError(null);
      });

      // Chargement terminé
      playerRef.current.on('canplay', () => {
        setIsLoading(false);
      });
    }

    return () => {
      if (playerRef.current) {
        playerRef.current.dispose();
        playerRef.current = null;
      }
    };
  }, []);

  // Quand la source change
  useEffect(() => {
    if (playerRef.current && src) {
      playerRef.current.src({
        src: src,
        type: 'application/x-mpegURL',
      });
    }
  }, [src]);

  return (
    <div className="m3u8-player-container">
      {isLoading && (
        <div className="loading-overlay">
          <div className="loading-spinner">Chargement...</div>
        </div>
      )}

      {error && <div className="error-message">{error}</div>}

      <div data-vjs-player>
        <video
          ref={videoRef}
          className="video-js vjs-default-skin"
          controls
          preload="auto"
          data-setup="{}"
        />
      </div>
    </div>
  );
};

// Exemple d'utilisation
const App = () => {
  const [streamUrl, setStreamUrl] = useState('');
  const [currentUrl, setCurrentUrl] = useState('');

  const handleLoadStream = () => {
    if (streamUrl.trim()) {
      setCurrentUrl(streamUrl);
    }
  };

  return (
    <div className="app">
      <h1>Lecteur M3U8 - Exemple React</h1>

      <div className="controls">
        <input
          type="url"
          value={streamUrl}
          onChange={(e) => setStreamUrl(e.target.value)}
          placeholder="Entrez l'URL M3U8"
        />
        <button onClick={handleLoadStream}>Charger</button>
      </div>

      {currentUrl && (
        <M3U8Player
          src={currentUrl}
          options={{
            width: 800,
            height: 450,
          }}
        />
      )}
    </div>
  );
};

export default App;

Exemple de Composant Vue.js

Lecteur M3U8 en Vue.js

<template>
  <div class="m3u8-player-wrapper">
    <div class="controls">
      <input
        v-model="streamUrl"
        type="url"
        placeholder="Entrez l'URL M3U8"
        @keyup.enter="loadStream"
      />
      <button @click="loadStream" :disabled="!streamUrl.trim()">Charger</button>
    </div>

    <div v-if="error" class="error-message">
      {{ error }}
    </div>

    <div v-if="isLoading" class="loading-message">Chargement...</div>

    <div ref="playerContainer" class="player-container"></div>
  </div>
</template>

<script>
import videojs from 'video.js';
import 'video.js/dist/video-js.css';

export default {
  name: 'M3U8Player',
  props: {
    initialUrl: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      streamUrl: this.initialUrl,
      player: null,
      error: null,
      isLoading: false,
    };
  },
  mounted() {
    this.initializePlayer();
    if (this.initialUrl) {
      this.loadStream();
    }
  },
  beforeUnmount() {
    if (this.player) {
      this.player.dispose();
    }
  },
  methods: {
    initializePlayer() {
      const videoElement = document.createElement('video');
      videoElement.className = 'video-js vjs-default-skin';
      videoElement.controls = true;
      videoElement.preload = 'auto';
      videoElement.width = 800;
      videoElement.height = 450;

      this.$refs.playerContainer.appendChild(videoElement);

      this.player = videojs(videoElement, {
        html5: {
          vhs: {
            overrideNative: true,
            enableLowInitialPlaylist: true,
            smoothQualityChange: true,
          },
        },
      });

      // Configurer les écouteurs d'événements
      this.player.on('error', this.handleError);
      this.player.on('loadstart', () => {
        this.isLoading = true;
        this.error = null;
      });
      this.player.on('canplay', () => {
        this.isLoading = false;
      });
    },

    loadStream() {
      if (!this.streamUrl.trim()) {
        this.error = 'Veuillez entrer une URL';
        return;
      }

      if (!this.player) {
        this.error = "Le lecteur n'est pas initialisé";
        return;
      }

      try {
        this.player.src({
          src: this.streamUrl,
          type: 'application/x-mpegURL',
        });
      } catch (err) {
        this.handleError(err);
      }
    },

    handleError(error) {
      console.error('Erreur du lecteur:', error);
      this.error = 'Erreur lors du chargement du stream';
      this.isLoading = false;
    },
  },
};
</script>

<style scoped>
.m3u8-player-wrapper {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.controls {
  margin-bottom: 20px;
}

.controls input {
  width: 70%;
  padding: 8px;
  margin-right: 10px;
}

.controls button {
  padding: 8px 16px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.controls button:disabled {
  background: #ccc;
  cursor: not-allowed;
}

.error-message {
  color: red;
  background: #ffe6e6;
  padding: 10px;
  border-radius: 4px;
  margin-bottom: 20px;
}

.loading-message {
  color: #007bff;
  text-align: center;
  padding: 20px;
}

.player-container {
  background: #000;
  border-radius: 8px;
  overflow: hidden;
}
</style>

Ces exemples de code vous permettent d'implémenter le Lecteur M3U8 en Ligne dans divers environnements et frameworks.

Cette page vous a-t-elle été utile ?