Pourquoi créer votre propre lecteur audio
Le lecteur audio par défaut du navigateur (<audio controls>) fonctionne, mais il est impossible à personnaliser visuellement et il a un design différent sur chaque navigateur. En créant votre propre lecteur, vous contrôlez entièrement l’apparence et les fonctionnalités. Ce tutoriel utilise uniquement HTML, CSS et JavaScript — aucune bibliothèque externe.
La structure HTML
<div class="audio-player" id="player">
<audio id="audio" src="audio-sample.mp3" preload="metadata"></audio>
<div class="player-controls">
<button id="playBtn" class="btn-play">▶</button>
<div class="progress-container" id="progressContainer">
<div class="progress-bar" id="progressBar"></div>
</div>
<span id="currentTime">0:00</span>
<span> / </span>
<span id="duration">0:00</span>
<div class="volume-container">
<button id="muteBtn">🔊</button>
<input type="range" id="volumeSlider" min="0" max="1" step="0.05" value="0.7">
</div>
</div>
</div>
Détail : l’élément <audio> est présent mais sans l’attribut controls — le navigateur ne l’affiche pas. On le pilote entièrement via JavaScript. preload="metadata" charge uniquement la durée et les infos de base, pas le fichier entier.
Le CSS du lecteur
.audio-player {
background: #1a1a2e;
border-radius: 12px;
padding: 20px;
max-width: 500px;
color: white;
}
.player-controls {
display: flex;
align-items: center;
gap: 12px;
}
.btn-play {
background: #e94560;
border: none;
color: white;
width: 44px;
height: 44px;
border-radius: 50%;
font-size: 18px;
cursor: pointer;
transition: transform 0.1s;
}
.btn-play:hover { transform: scale(1.1); }
.btn-play:activé { transform: scale(0.95); }
.progress-container {
flex: 1;
height: 6px;
background: #333;
border-radius: 3px;
cursor: pointer;
position: relative;
}
.progress-bar {
height: 100%;
background: #e94560;
border-radius: 3px;
width: 0%;
transition: width 0.1s linear;
}
.volume-container {
display: flex;
align-items: center;
gap: 6px;
}
#volumeSlider {
width: 80px;
accent-color: #e94560;
}
#muteBtn {
background: none;
border: none;
font-size: 18px;
cursor: pointer;
}
Le JavaScript : 60 lignes pour tout contrôler
const audio = document.getElementById('audio');
const playBtn = document.getElementById('playBtn');
const progressContainer = document.getElementById('progressContainer');
const progressBar = document.getElementById('progressBar');
const currentTimeEl = document.getElementById('currentTime');
const durationEl = document.getElementById('duration');
const volumeSlider = document.getElementById('volumeSlider');
const muteBtn = document.getElementById('muteBtn');
// Formater le temps en M:SS
function formatTime(seconds) {
const min = Math.floor(seconds / 60);
const sec = Math.floor(seconds % 60);
return min + ':' + sec.toString().padStart(2, '0');
}
// Play / Pause
playBtn.addEventListener('click', () => {
if (audio.paused) {
audio.play();
playBtn.textContent = '⏸';
} else {
audio.pause();
playBtn.textContent = '▶';
}
});
// Mettre à jour la barre de progression
audio.addEventListener('timeupdate', () => {
const percent = (audio.currentTime / audio.duration) * 100;
progressBar.style.width = percent + '%';
currentTimeEl.textContent = formatTime(audio.currentTime);
});
// Afficher la durée quand les métadonnées sont chargées
audio.addEventListener('loadedmetadata', () => {
durationEl.textContent = formatTime(audio.duration);
});
// Cliquer sur la barre pour sauter à un moment précis
progressContainer.addEventListener('click', (e) => {
const rect = progressContainer.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const percent = clickX / rect.width;
audio.currentTime = percent * audio.duration;
});
// Volume
volumeSlider.addEventListener('input', () => {
audio.volume = volumeSlider.value;
muteBtn.textContent = audio.volume === 0 ? '🔇' : '🔊';
});
// Mute / Unmute
muteBtn.addEventListener('click', () => {
audio.muted = !audio.muted;
muteBtn.textContent = audio.muted ? '🔇' : '🔊';
});
// Réinitialiser quand la piste se terminé
audio.addEventListener('ended', () => {
playBtn.textContent = '▶';
progressBar.style.width = '0%';
});
Explication des événements audio clés
| Événement | Quand il se déclenche | Utilisation |
|---|---|---|
timeupdate |
~4 fois par seconde pendant la lecture | Mettre à jour la barre et le timer |
loadedmetadata |
Quand la durée et les dimensions sont connues | Afficher la durée totale |
ended |
Quand la piste atteint la fin | Réinitialiser le bouton play |
play / pause |
Quand la lecture démarre/s’arrête | Synchroniser l’UI |
volumechange |
Quand le volume change | Mettre à jour l’icône |
canplay |
Quand assez de données sont chargées pour jouer | Activer le bouton play |
Ajouter une playlist
const playlist = [
{ title: 'Morceau 1', src: 'track1.mp3' },
{ title: 'Morceau 2', src: 'track2.mp3' },
{ title: 'Morceau 3', src: 'track3.mp3' }
];
let currentTrack = 0;
function loadTrack(index) {
audio.src = playlist[index].src;
document.getElementById('trackTitle').textContent = playlist[index].title;
audio.load();
}
function nextTrack() {
currentTrack = (currentTrack + 1) % playlist.length;
loadTrack(currentTrack);
audio.play();
playBtn.textContent = '⏸';
}
// Jouer le morceau suivant automatiquement
audio.addEventListener('ended', nextTrack);
Exercice
Créez un lecteur audio avec les fonctionnalités suivantes :
- Boutons play/pause, précédent, suivant
- Barre de progression cliquable
- Affichage du titre du morceau en cours
- Contrôle du volume avec un slider
- Bonus : ajoutez une visualisation audio avec l’API Web Audio et un Canvas