W3docs

JavaScript Web Audio API

Aprenda a Web Audio API do JavaScript: construa um grafo de áudio com AudioContext e AudioNodes, carregue e reproduza sons, controle o volume, gere tons e gerencie a política de autoplay do navegador.

A Web Audio API permite gerar, carregar, processar e reproduzir som diretamente no navegador — sem necessidade de plugins. Este guia apresenta seus principais blocos de construção: como criar um contexto de áudio, carregar e reproduzir arquivos de som, controlar o volume, gerar tons com um oscilador e contornar a política de autoplay do navegador. Cada exemplo é pequeno e independente, para que você possa adicioná-lo a uma página e ouvir o resultado.

Introdução à Web Audio API

A Web Audio API é uma JavaScript API para processar e sintetizar áudio em aplicações web. Ao contrário de um simples elemento <audio> — que apenas reproduz um arquivo do início ao fim — a Web Audio API oferece um grafo de nós conectados que roteiam, misturam e transformam o som em tempo real. Isso a torna a ferramenta ideal para jogos, aplicativos de música, sintetizadores e visualizadores de áudio.

Pensando em grafos de áudio

Todo som na Web Audio API flui por uma cadeia de nós, de uma fonte até um destino:

source  →  (effects)  →  destination
 (file,    (gain,        (your
 oscillator)  filter)     speakers)

Os três conceitos que você encontrará primeiro:

  • AudioContext — o contêiner que possui todo o grafo e o relógio de áudio. Você cria um por página e o reutiliza.
  • AudioNode — uma unidade modular de processamento. Nós de fonte produzem som (um buffer ou um oscilador), nós de efeito o transformam (gain, filtro, panner), e o nó de destino envia o som para os alto-falantes.
  • AudioBuffer — dados de áudio decodificados em memória, ideal para sons curtos (efeitos, amostras) que você aciona repetidamente com temporização precisa.

Você constrói um grafo chamando node.connect(otherNode). O áudio sempre termina em audioContext.destination.

Começando com a Web Audio API

Para fazer qualquer coisa com áudio, você primeiro cria um AudioContext, que serve como contêiner para o seu grafo de áudio.

Criando um AudioContext

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

Isso inicializa um novo AudioContext. O fallback webkit cobre versões mais antigas do Safari; navegadores modernos suportam o AudioContext sem prefixo diretamente.

Atenção à política de autoplay. Os navegadores criam o contexto em estado "suspended" e recusam reproduzir som até que o usuário interaja com a página (um clique ou pressionamento de tecla). Sempre retome-o dentro de um manipulador de eventos antes de reproduzir:

button.addEventListener("click", async () => {
  if (audioContext.state === "suspended") {
    await audioContext.resume();
  }
  // ...agora é seguro reproduzir
});

Se o áudio estiver silencioso sem erros no console, um contexto não retomado é a causa mais comum.

Carregando e Reproduzindo Áudio

Para reproduzir um arquivo de som, você o carrega em um AudioBuffer e, em seguida, conecta um nó de fonte ao contexto para reprodução.

Carregando Arquivos de Áudio

Isso usa a Fetch API e async/await para baixar o arquivo e decodificá-lo:

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

A função busca o arquivo, lê-o como um ArrayBuffer bruto e, em seguida, passa-o para decodeAudioData, que descomprime formatos como MP3, WAV ou OGG em um AudioBuffer pronto para reprodução. A decodificação ocorre fora da thread principal e retorna uma promise, então use await.

Reproduzindo o Áudio Carregado

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

Isso cria um BufferSourceNode, aponta-o para o buffer decodificado, conecta-o aos alto-falantes (audioContext.destination) e inicia a reprodução.

Um nó de fonte é de uso único. Um AudioBufferSourceNode só pode ser iniciado uma vez — após parar, você deve criar um novo para reproduzir o mesmo buffer novamente. O próprio AudioBuffer é reutilizável, então mantenha o buffer e recrie o nó de fonte barato a cada vez:

// ❌ Throws after the first play: "cannot call start more than once"
// sourceNode.start();
// sourceNode.start();

// ✅ One fresh source node per playback
function playOnce(buffer, ctx) {
  const src = ctx.createBufferSource();
  src.buffer = buffer;
  src.connect(ctx.destination);
  src.start();
}

Manipulando Áudio

A Web Audio API brilha quando você insere nós de efeito entre a fonte e o destino. O mais comum é o nó de gain para controle de volume.

Criando um Nó de Gain

function createGainNode(audioContext, volume) {
  const gainNode = audioContext.createGain();
  gainNode.gain.value = volume; // 1 = full volume, 0 = silent, 0.5 = half
  return gainNode;
}

Um GainNode multiplica o sinal pelo seu valor de gain. A propriedade gain é um AudioParam, o que significa que você também pode agendar mudanças suaves ao longo do tempo (para fades) em vez de definir um valor abruptamente:

// 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);

Conectando Nós para Efeitos de Áudio

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();
}

Isso constrói um grafo de três nós: a fonte alimenta o nó de gain, e o nó de gain alimenta o destino. Insira mais nós de efeito da mesma forma — por exemplo, um BiquadFilterNode para modelagem de 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);

A ordem importa: o sinal flui na direção das suas chamadas connect.

Um Exemplo Executável: um Gerador de Tons

Para uma demonstração independente que não precisa de arquivo de áudio, aqui está um gerador de tons construído a partir de um oscilador. Ele também lida com a política de autoplay retomando o contexto no primeiro clique.

<!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>

Como funciona:

  • Nó oscilador — gera uma onda senoidal pura a 440 Hz (a nota A4 usada para afinação). Outros valores de type são "square", "sawtooth" e "triangle", cada um com um timbre diferente.
  • Funções de controleplayTone retoma o contexto e inicia o oscilador; stopTone o para, desconecta e redefine a variável para que um novo oscilador possa ser criado na próxima vez.
  • Por que redefinir oscillator = null? Como um nó de fonte de buffer, um oscilador é de uso único — uma vez parado, não pode ser reiniciado, então você cria um novo para o próximo tom.

Quando Usar a Web Audio API

Caso de usoUtilize…
Reproduzir uma faixa de fundo ou podcastUm simples elemento <audio> — mais simples, menos código
Efeitos sonoros em jogos com temporização precisaWeb Audio API + AudioBuffer
Controle de volume, fades, filtros, panningNós de gain/filtro/panner da Web Audio API
Sintetizadores e tons geradosOscillatorNode da Web Audio API
Visualizadores de forma de onda/frequência em tempo realAnalyserNode da Web Audio API

Se você só precisa de reprodução com início/pausa, o elemento <audio> é suficiente. Escolha a Web Audio API no momento em que precisar de processamento, temporização ou síntese.

Conclusão

A Web Audio API transforma o navegador em um console de mixagem programável: você conecta um grafo de nós desde uma fonte, passando por efeitos, até os alto-falantes, e controla cada etapa em tempo real. Lembre-se destes pontos:

  • Crie um AudioContext e retome-o em um gesto do usuário antes de reproduzir.
  • Reutilize AudioBuffers, mas crie um novo nó de fonte/oscilador para cada reprodução.
  • Construa efeitos encadeando nós com connect(), sempre terminando em audioContext.destination.

A partir daqui, explore capacidades relacionadas do navegador, como a Web MIDI API para conectar instrumentos musicais, ou a Web Animations API para sincronizar visuais com seu áudio.

Prática

Prática
Quais características são verdadeiras sobre as capacidades da Web Audio API?
Quais características são verdadeiras sobre as capacidades da Web Audio API?
Was this page helpful?