W3docs

L'API Web Audio en JavaScript

Apprenez l'API Web Audio JavaScript : créez un graphe audio avec AudioContext et AudioNodes, chargez des sons, contrôlez le volume, générez des tonalités et gérez la politique d'autoplay du navigateur.

La Web Audio API vous permet de générer, charger, traiter et lire du son directement dans le navigateur — sans aucun plugin. Ce guide vous présente ses éléments fondamentaux : comment créer un contexte audio, charger et lire des fichiers sonores, contrôler le volume, générer des tonalités avec un oscillateur, et contourner la politique d'autoplay du navigateur. Chaque exemple est court et autonome, prêt à être intégré dans une page pour entendre le résultat immédiatement.

Introduction à la Web Audio API

La Web Audio API est une API JavaScript destinée au traitement et à la synthèse audio dans les applications web. Contrairement à un simple élément <audio> — qui ne fait que lire un fichier du début à la fin — la Web Audio API vous offre un graphe de nœuds connectés qui acheminent, mélangent et transforment le son en temps réel. C'est l'outil idéal pour les jeux, les applications musicales, les synthétiseurs et les visualiseurs audio.

Penser en termes de graphes audio

Dans la Web Audio API, chaque son transite par une chaîne de nœuds, d'une source vers une destination :

source  →  (effets)  →  destination
 (fichier,  (gain,       (vos
 oscillateur)  filtre)    haut-parleurs)

Les trois concepts que vous rencontrerez en premier :

  • AudioContext — le conteneur qui gère l'ensemble du graphe et l'horloge audio. Vous en créez un par page et le réutilisez.
  • AudioNode — une unité de traitement modulaire. Les nœuds sources produisent du son (un buffer ou un oscillateur), les nœuds d'effet le transforment (gain, filtre, panoramique), et le nœud destination l'envoie vers les haut-parleurs.
  • AudioBuffer — des données audio décodées en mémoire, idéales pour les sons courts (effets, échantillons) que vous déclenchez répétitivement avec une synchronisation précise.

Vous construisez un graphe en appelant node.connect(otherNode). L'audio se termine toujours à audioContext.destination.

Premiers pas avec la Web Audio API

Pour travailler avec l'audio, vous commencez par créer un AudioContext, qui sert de conteneur à votre graphe audio.

Créer un AudioContext

const audioContext = new (window.AudioContext || window.webkitAudioContext)();

Ceci initialise un nouvel AudioContext. Le fallback webkit couvre les anciennes versions de Safari ; les navigateurs modernes prennent en charge AudioContext directement, sans préfixe.

Attention à la politique d'autoplay. Les navigateurs créent le contexte dans un état "suspended" et refusent de jouer du son tant que l'utilisateur n'a pas interagi avec la page (un clic ou une pression de touche). Reprenez toujours le contexte dans un gestionnaire d'événements avant de lancer la lecture :

button.addEventListener("click", async () => {
  if (audioContext.state === "suspended") {
    await audioContext.resume();
  }
  // ...la lecture peut maintenant commencer en toute sécurité
});

Si l'audio est muet sans erreur dans la console, un contexte non repris est la cause la plus fréquente.

Chargement et lecture audio

Pour lire un fichier sonore, vous le chargez dans un AudioBuffer, puis vous connectez un nœud source au contexte pour la lecture.

Chargement de fichiers audio

Cette fonction utilise la Fetch API et async/await pour télécharger le fichier et le décoder :

async function loadAudioFile(url, audioContext) {
  const response = await fetch(url);
  const arrayBuffer = await response.arrayBuffer();
  const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
  return audioBuffer;
}

La fonction récupère le fichier, le lit comme un ArrayBuffer brut, puis le transmet à decodeAudioData, qui décompresse des formats comme MP3, WAV ou OGG en un AudioBuffer prêt à l'emploi. Le décodage s'effectue en dehors du thread principal et retourne une promesse, donc utilisez await.

Lecture de l'audio chargé

function playAudio(audioBuffer, audioContext) {
  const sourceNode = audioContext.createBufferSource();
  sourceNode.buffer = audioBuffer;
  sourceNode.connect(audioContext.destination);
  sourceNode.start();
}

Cette fonction crée un BufferSourceNode, le pointe vers le buffer décodé, le connecte aux haut-parleurs (audioContext.destination), et démarre la lecture.

Un nœud source est à usage unique. Un AudioBufferSourceNode ne peut être démarré qu'une seule fois — une fois arrêté, vous devez en créer un nouveau pour rejouer le même buffer. L'AudioBuffer lui-même est réutilisable, alors conservez le buffer et recréez le nœud source (peu coûteux) à chaque lecture :

// ❌ Lève une exception après la première lecture : "cannot call start more than once"
// sourceNode.start();
// sourceNode.start();

// ✅ Un nouveau nœud source à chaque lecture
function playOnce(buffer, ctx) {
  const src = ctx.createBufferSource();
  src.buffer = buffer;
  src.connect(ctx.destination);
  src.start();
}

Manipulation de l'audio

La Web Audio API révèle tout son potentiel lorsque vous insérez des nœuds d'effet entre la source et la destination. Le plus courant est le nœud de gain pour le contrôle du volume.

Créer un nœud de gain

function createGainNode(audioContext, volume) {
  const gainNode = audioContext.createGain();
  gainNode.gain.value = volume; // 1 = volume maximal, 0 = silence, 0.5 = moitié
  return gainNode;
}

Un GainNode multiplie le signal par sa valeur gain. La propriété gain est un AudioParam, ce qui signifie que vous pouvez aussi planifier des changements progressifs dans le temps (pour les fondus) plutôt que de définir une valeur brusquement :

// Fade from silent to full volume over 2 seconds, avoiding clicks/pops
gainNode.gain.setValueAtTime(0, audioContext.currentTime);
gainNode.gain.linearRampToValueAtTime(1, audioContext.currentTime + 2);

Connexion de nœuds pour les effets audio

function applyEffects(audioBuffer, volume, audioContext) {
  const sourceNode = audioContext.createBufferSource();
  sourceNode.buffer = audioBuffer;

  const gainNode = createGainNode(audioContext, volume);

  // source → gain → destination
  sourceNode.connect(gainNode);
  gainNode.connect(audioContext.destination);

  sourceNode.start();
}

Ce code construit un graphe à trois nœuds : la source alimente le nœud de gain, et ce dernier alimente la destination. Insérez d'autres nœuds d'effet de la même manière — par exemple un BiquadFilterNode pour la mise en forme du timbre :

const filter = audioContext.createBiquadFilter();
filter.type = "lowpass";      // let low frequencies through, cut highs
filter.frequency.value = 800; // cutoff in Hz

sourceNode.connect(filter);
filter.connect(gainNode);
gainNode.connect(audioContext.destination);

L'ordre est important : le signal circule dans le sens de vos appels connect.

Un exemple fonctionnel : un générateur de tonalités

Pour une démo autonome ne nécessitant aucun fichier audio, voici un générateur de tonalités construit à partir d'un oscillateur. Il gère également la politique d'autoplay en reprenant le contexte au premier clic.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Simple Tone Generator</title>
  </head>
  <body>
    <h1>Simple Tone Generator</h1>
    <button onclick="playTone()">Play Tone</button>
    <button onclick="stopTone()">Stop Tone</button>

    <script>
      let audioContext;
      let oscillator;

      async function playTone() {
        if (!audioContext) {
          audioContext = new (window.AudioContext ||
            window.webkitAudioContext)();
        }
        // Satisfy the autoplay policy: resume on user gesture
        if (audioContext.state === "suspended") {
          await audioContext.resume();
        }
        if (!oscillator) {
          oscillator = audioContext.createOscillator();
          oscillator.type = "sine"; // Sine wave — other values are 'square', 'sawtooth', 'triangle'
          oscillator.frequency.setValueAtTime(440, audioContext.currentTime); // A4 note, 440 Hz
          oscillator.connect(audioContext.destination);
          oscillator.start();
        }
      }

      function stopTone() {
        if (oscillator) {
          oscillator.stop();
          oscillator.disconnect();
          oscillator = null; // Reset the oscillator to allow a new one to be created next time
        }
      }
    </script>
  </body>
</html>

Fonctionnement :

  • Nœud oscillateur — génère une onde sinusoïdale pure à 440 Hz (la note La4 utilisée pour l'accordage). Les autres valeurs de type sont "square", "sawtooth" et "triangle", chacune avec un timbre différent.
  • Fonctions de contrôleplayTone reprend le contexte et démarre l'oscillateur ; stopTone l'arrête, le déconnecte et réinitialise la variable afin qu'un nouvel oscillateur puisse être créé lors de la prochaine utilisation.
  • Pourquoi réinitialiser oscillator = null ? Comme un nœud source de buffer, un oscillateur est à usage unique — une fois arrêté, il ne peut pas être redémarré, donc vous en créez un nouveau pour la prochaine tonalité.

Quand utiliser la Web Audio API

Cas d'usageÀ privilégier…
Lire une piste de fond ou un podcastUn élément <audio> simple — plus facile, moins de code
Effets sonores dans un jeu avec synchronisation préciseWeb Audio API + AudioBuffer
Contrôle du volume, fondus, filtres, panoramiqueNœuds gain/filtre/panoramique de la Web Audio API
Synthétiseurs et tonalités généréesOscillatorNode de la Web Audio API
Visualiseurs de forme d'onde/fréquence en temps réelAnalyserNode de la Web Audio API

Si vous avez seulement besoin de démarrer/arrêter la lecture, l'élément <audio> suffit. Choisissez la Web Audio API dès que vous avez besoin de traitement, de synchronisation ou de synthèse.

Conclusion

La Web Audio API transforme le navigateur en une table de mixage programmable : vous câblez un graphe de nœuds depuis une source, à travers des effets, jusqu'aux haut-parleurs, et contrôlez chaque étape en temps réel. Retenez ces points essentiels :

  • Créez un seul AudioContext et reprenez-le lors d'un geste utilisateur avant de lancer la lecture.
  • Réutilisez les AudioBuffers, mais créez un nouveau nœud source/oscillateur pour chaque lecture.
  • Construisez des effets en chaînant les nœuds avec connect(), en terminant toujours à audioContext.destination.

Pour aller plus loin, explorez des fonctionnalités du navigateur comme la Web MIDI API pour connecter des instruments de musique, ou la Web Animations API pour synchroniser les visuels avec votre audio.

Pratique

Pratique
Quelles affirmations sont vraies concernant les capacités de la Web Audio API ?
Quelles affirmations sont vraies concernant les capacités de la Web Audio API ?
Was this page helpful?