Comment construire un lecteur audio avec Claude Code
Apprenez a construire un lecteur audio avec Claude Code. Inclut des exemples de code pratiques et un guide etape par etape.
Construire un lecteur audio avec Claude Code
Il existe de nombreuses situations ou un lecteur audio personnalise est necessaire : services de streaming musical, podcasts, contenu educatif, etc. Avec Claude Code, vous pouvez construire un lecteur complet avec visualisation de forme d’onde et fonctionnalite de liste de lecture.
Implementation du lecteur de base
> Cree un lecteur audio personnalise.
> Compatible avec lecture/pause, barre de progression, volume et changement de vitesse de lecture.
> Implemente egalement la fonctionnalite de liste de lecture et la visualisation de forme d'onde.
// src/components/AudioPlayer.tsx
'use client';
import { useRef, useState, useEffect } from 'react';
interface Track {
id: string;
title: string;
artist: string;
src: string;
duration: number;
coverArt?: string;
}
interface AudioPlayerProps {
tracks: Track[];
initialTrackIndex?: number;
}
export function AudioPlayer({ tracks, initialTrackIndex = 0 }: AudioPlayerProps) {
const audioRef = useRef<HTMLAudioElement>(null);
const [currentTrackIndex, setCurrentTrackIndex] = useState(initialTrackIndex);
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const [volume, setVolume] = useState(0.8);
const currentTrack = tracks[currentTrackIndex];
useEffect(() => {
const audio = audioRef.current;
if (!audio) return;
const onTimeUpdate = () => setCurrentTime(audio.currentTime);
const onLoadedMetadata = () => setDuration(audio.duration);
const onEnded = () => playNext();
audio.addEventListener('timeupdate', onTimeUpdate);
audio.addEventListener('loadedmetadata', onLoadedMetadata);
audio.addEventListener('ended', onEnded);
return () => {
audio.removeEventListener('timeupdate', onTimeUpdate);
audio.removeEventListener('loadedmetadata', onLoadedMetadata);
audio.removeEventListener('ended', onEnded);
};
}, [currentTrackIndex]);
const togglePlay = () => {
const audio = audioRef.current;
if (!audio) return;
if (audio.paused) {
audio.play();
setIsPlaying(true);
} else {
audio.pause();
setIsPlaying(false);
}
};
const playNext = () => {
const nextIndex = (currentTrackIndex + 1) % tracks.length;
setCurrentTrackIndex(nextIndex);
setTimeout(() => {
audioRef.current?.play();
setIsPlaying(true);
}, 100);
};
const playPrevious = () => {
if (currentTime > 3) {
// Si plus de 3 secondes se sont ecoulees, revenir au debut
audioRef.current!.currentTime = 0;
} else {
const prevIndex = (currentTrackIndex - 1 + tracks.length) % tracks.length;
setCurrentTrackIndex(prevIndex);
setTimeout(() => {
audioRef.current?.play();
setIsPlaying(true);
}, 100);
}
};
const formatTime = (sec: number) => {
const m = Math.floor(sec / 60);
const s = Math.floor(sec % 60);
return `${m}:${s.toString().padStart(2, '0')}`;
};
return (
<div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg overflow-hidden max-w-md mx-auto">
<audio ref={audioRef} src={currentTrack.src} preload="metadata" />
{/* Pochette */}
<div className="aspect-square bg-gray-200 dark:bg-gray-700 relative">
{currentTrack.coverArt ? (
<img src={currentTrack.coverArt} alt={currentTrack.title} className="w-full h-full object-cover" />
) : (
<div className="w-full h-full flex items-center justify-center text-6xl text-gray-400">♫</div>
)}
</div>
{/* Informations de la piste */}
<div className="p-6">
<h3 className="text-lg font-bold dark:text-white truncate">{currentTrack.title}</h3>
<p className="text-gray-500 dark:text-gray-400 text-sm">{currentTrack.artist}</p>
{/* Barre de progression */}
<div className="mt-4">
<input
type="range"
min={0}
max={duration || 0}
value={currentTime}
onChange={(e) => {
const time = Number(e.target.value);
audioRef.current!.currentTime = time;
setCurrentTime(time);
}}
className="w-full h-1 accent-blue-600"
/>
<div className="flex justify-between text-xs text-gray-400 mt-1">
<span>{formatTime(currentTime)}</span>
<span>{formatTime(duration)}</span>
</div>
</div>
{/* Controles */}
<div className="flex items-center justify-center gap-6 mt-4">
<button onClick={playPrevious} className="text-2xl dark:text-white hover:text-blue-600">⏮</button>
<button
onClick={togglePlay}
className="w-14 h-14 rounded-full bg-blue-600 text-white text-2xl flex items-center justify-center hover:bg-blue-700"
>
{isPlaying ? '⏸' : '▶'}
</button>
<button onClick={playNext} className="text-2xl dark:text-white hover:text-blue-600">⏭</button>
</div>
{/* Volume */}
<div className="flex items-center gap-2 mt-4">
<span className="text-sm dark:text-gray-400">🔊</span>
<input
type="range"
min={0}
max={1}
step={0.05}
value={volume}
onChange={(e) => {
const vol = Number(e.target.value);
audioRef.current!.volume = vol;
setVolume(vol);
}}
className="flex-1 h-1 accent-blue-600"
/>
</div>
</div>
{/* Liste de lecture */}
<div className="border-t dark:border-gray-700 max-h-60 overflow-y-auto">
{tracks.map((track, index) => (
<button
key={track.id}
onClick={() => {
setCurrentTrackIndex(index);
setTimeout(() => { audioRef.current?.play(); setIsPlaying(true); }, 100);
}}
className={`w-full flex items-center gap-3 p-3 text-left hover:bg-gray-50 dark:hover:bg-gray-700 ${
index === currentTrackIndex ? 'bg-blue-50 dark:bg-blue-900/30' : ''
}`}
>
<span className="text-xs text-gray-400 w-6 text-right">
{index === currentTrackIndex && isPlaying ? '♫' : index + 1}
</span>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium dark:text-white truncate">{track.title}</p>
<p className="text-xs text-gray-500 truncate">{track.artist}</p>
</div>
<span className="text-xs text-gray-400">{formatTime(track.duration)}</span>
</button>
))}
</div>
</div>
);
}
Visualisation de forme d’onde avec Web Audio API
En tant que fonctionnalite avancee, vous pouvez egalement demander a Claude Code la visualisation en temps reel de la forme d’onde en utilisant Web Audio API. En combinant AudioContext et AnalyserNode, vous pouvez dessiner la forme d’onde audio en cours de lecture sur un Canvas.
Articles connexes
Pour l’implementation d’un lecteur video, consultez le guide de construction de lecteur video ; pour le design responsive, consultez le design responsive.
Pour plus de details sur Web Audio API, consultez MDN (developer.mozilla.org/Web/API/Web_Audio_API).
Mise a niveau production 2026: une vraie interface audio
Un lecteur audio n’est pas seulement un bouton de lecture. C’est l’interface qui aide l’utilisateur a ecouter, mettre en pause, revenir en arriere, comprendre sa progression et choisir l’action suivante. Dans un cours, un podcast, une bibliotheque media ou une page de vente, le player doit aussi gerer la reprise de lecture, les erreurs reseau, l’accessibilite, les evenements analytics et le CTA.
Le composant React/TypeScript ci-dessus est une base executable: il garde le HTMLAudioElement dans un useRef, tandis que React gere la piste courante, l’etat de lecture, le temps et le volume. Pour l’utiliser dans une application, fournissez une liste tracks non vide, faites pointer src vers de vrais fichiers audio et rendez le composant cote client. Cette separation rend possible l’ajout d’une waveform, d’une mesure de progression ou d’un paywall sans tout reconstruire.
HTMLAudioElement ou Web Audio API
HTMLAudioElement est l’objet du navigateur derriere l’element audio. Il gere le chargement, le decodage, la lecture, la pause, le volume, la position, la duree et les evenements media. Pour un lecteur de cours, un episode de podcast ou une preview de produit, c’est le bon point de depart. La documentation MDN de l’element audio donne les attributs et comportements a verifier.
Web Audio API est une couche plus basse. Elle permet de creer un graphe audio avec AudioContext, MediaElementAudioSourceNode, AnalyserNode et GainNode. Utilisez-la pour une forme d’onde, un spectre, un egaliseur, un fade ou une interface qui reagit au son. Elle ne remplace pas les controles de lecture; elle les complete. Consultez la reference Web Audio API et la documentation React de useRef pour comprendre comment relier proprement DOM, audio et etat React.
| Couche | Role | Point d’attention en production |
|---|---|---|
| Donnees | Titre, auteur, URL, duree, pochette, transcription | Ne pas afficher un player avec une playlist vide |
| Lecture | HTMLAudioElement pour play, pause, seek et volume | Ecouter loadedmetadata, timeupdate, ended et les erreurs |
| Visualisation | Web Audio API pour waveform ou spectre | Verifier CORS et reprendre AudioContext apres une action utilisateur |
| Interface | Boutons, sliders, liste, temps courant | Ajouter labels, focus clavier et texte pour lecteurs d’ecran |
| Produit | Analytics, progression, CTA, regles premium | Mesurer debut, 50%, fin, relecture et clics de conversion |
Cas concrets (use case) pour les lecteurs media
Premier use case: l’apprentissage. Dans une formation, un cours de langue ou un module d’onboarding, les utilisateurs veulent changer la vitesse, revenir de 10 secondes, suivre une transcription et reprendre la ou ils se sont arretes. La valeur vient de la revision facile, pas d’une animation decorative.
Deuxieme use case: le podcast et les medias editoriaux. Un lecteur personnalise peut afficher la couverture, les chapitres, les episodes lies, une inscription newsletter et une offre membre. Quand l’audio se termine, l’action suivante doit etre visible: episode suivant, abonnement, telechargement ou page de training.
Troisieme use case: la vente de contenus audio. Musiciens, voix-off, sound designers et createurs de cours peuvent proposer une preview courte avant achat. Une waveform lisible et un lien Gumroad ou produit rendent l’offre plus concrete.
Quatrieme use case: la formation interne. Scripts commerciaux, exemples de support client, exercices de prononciation et conformite peuvent etre organises en petites files audio. Dans ce contexte, la persistance de progression et les rapports d’administration sont essentiels.
Pitfalls et echecs frequents
Le pitfall principal est de croire que l’autoplay fonctionnera. Les navigateurs refusent souvent audio.play() tant que l’utilisateur n’a pas clique ou touche l’ecran. Comme play() renvoie une Promise, le code doit gerer le rejet et afficher une consigne claire.
Autre echec: lire duration trop tot. Avant loadedmetadata, la duree peut etre NaN ou zero. La barre de progression doit utiliser une valeur protegee et le texte de duree doit rester prudent pendant le chargement.
La waveform ajoute un risque CORS. Si le fichier audio vient d’un CDN, le serveur doit envoyer les bons en-tetes pour que Web Audio API puisse analyser le signal. Un player peut fonctionner en local et echouer uniquement apres deploiement.
Enfin, React peut se desynchroniser de l’element media. Le setTimeout de demo est pratique, mais un produit devrait attendre canplay ou loadedmetadata avant de lancer la lecture apres un changement de piste.
Liens et monetization CTA
Pour la partie React, continuez avec Claude Code React development. Pour l’analyse audio, lisez Claude Code Web Audio API. Pour les controles accessibles, utilisez Claude Code accessibility.
Si votre lecteur sert un cours, un podcast premium ou une page de vente, le CTA doit etre decide avant le design final. Un chemin simple: preview gratuite, inscription email, produit payant, puis consultation pour les equipes qui veulent l’integration dans leur vrai depot. ClaudeCodeLab peut structurer les regles Claude Code, CLAUDE.md, les evenements analytics et la revue technique via la page training / consultation.
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Workflow Obsidian vers CLAUDE.md avec Claude Code
Transformer des notes Obsidian en notes CLAUDE.md concises pour reprendre les sessions sans réexpliquer.
Claude Code Revenue CTA Routing : relier articles, PDF, Gumroad et consultation
Un workflow Claude Code pour orienter les lecteurs vers PDF gratuit, Gumroad ou consultation selon l'intention.
Règles de handoff Claude Code en équipe: preuves, permissions, rollback et revenus
Un format concret pour transmettre un travail Claude Code avec preuves, permissions, rollback, PDF gratuit, Gumroad et consultation.