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.