Visualizador de Ondas Sonoras com JavaScript


Para esta dica usaremos uma das muitas funcionalidades da Web Audio API do JavaScript, que é a capacidade de extrair a frequência, formas de onda e outros dados do seu arquivo de áudio e vamos usar isto para criar um visualizador de ondas sonoras básico. Para não dar problema com o Cors, execute seu código de um localhost

Iniciando

O primeiro passo é informar um arquivo de áudio.

HTML

<audio id="Audio" controls>
    <source src="SeuArquivoDeAudio.mp3" type="audio/mpeg" />
</audio>

JavaScript:

let audio = document.getElementById("Audio");

Extraindo dados de um arquivo de áudio

Agora precisamos usar o método AudioContext.createAnalyser() para criar um AnalyserNode, que vai nos permitir acessar dados como tempo e frequência do nosso arquivo de áudio.

// Audio Context
let audioCtx = new AudioContext();
// Analyser Node
let analyser = audioCtx.createAnalyser();

Depois de instanciar AudioContext e criar o AnalyserNode, vamos criar um MediaElementAudioSourceNode e conectar o nosso analyser e nosso AudioContext.destination

let source = audioCtx.createMediaElementSource(audio);
source.connect(analyser);
source.connect(audioCtx.destination);

O AnalyserNode irá pegar os dados do áudio usando a Transformada Rápida de Fourier (FFT) de um determinado domínio de frequência, dependendo do valor que iremos especificar na propriedade AnalyserNode.fftSize (o valor padrão é 2048)

Criando o Visualizador de Ondas

Vamos começar usando nosso AnalyserNode.fftSize para configurar nosso buffer

analyser.fftSize = 2048;
let bufferLength = analyser.fftSize;
let dataArray = new Uint8Array(bufferLength);

Com isso feito, vamos agora configurar o nosso canvas

HTML:

<div class="waves-container">
    <canvas id="waves-canvas"></canvas>
</div>

JavaScript:

// CAPTURANDO O CANVAS
let canvas = document.getElementById('waves-canvas');

// CONFIGURANDO O TAMANHO DO CANVAS
canvas.width = window.innerWidth;
canvas.height = window.innerHeight / 2;
let wid = canvas.width;
let hei = canvas.height;

// DEFINE A LARGURA DE CADA SEGMENTO DA LINHA 
// A SER DESENHADA, BASEADO NO fftSize
let sliceWidth = wid * 1.0 / bufferLength;

// CONFIGURANDO ESTILO DO CANVAS
canvasCtx = canvas.getContext('2d');
canvasCtx.clearRect(0, 0, wid, hei);
canvasCtx.fillStyle = '#151515';

// ESTILO DA LINHA
canvasCtx.lineWidth = 2;
canvasCtx.strokeStyle = 'rgb(249, 251, 250)';
canvasCtx.shadowOffsetX = 1;
canvasCtx.shadowOffsetY = 1;
canvasCtx.shadowBlur = 10;
canvasCtx.shadowColor = "rgb(28, 213, 254)";

Agora vamos definir a função draw() que vai servir para desenhar as linhas do nosso visualizador.

function draw() {
    // SERÁ USADO PARA MANTER A FUNÇÃO draw() EM LOOP
    loopDraw = requestAnimationFrame(draw);
    // INSERE NO dataArray A FORMA DE ONDA
    analyser.getByteTimeDomainData(dataArray);
    // CONFIGURANDO O PREENCIMENTO E INICIO DO DESENHO
    canvasCtx.fillRect(0, 0, wid, hei);
    canvasCtx.beginPath();
}

Logo abaixo do nosso beginPath() iremos iniciar o loop que definirá a posição de pequenos segmentos de onda para cada ponto no buffer a uma certa altura com base no valor do dataArray, em seguida, moverá a linha para onde o próximo segmento será desenhado.

Deverá ficar assim:

function draw() {
    // SERÁ USADO PARA MANTER A FUNÇÃO draw() EM LOOP
    loopDraw = requestAnimationFrame(draw);
    // INSERE NO dataArray A FORMA DE ONDA
    analyser.getByteTimeDomainData(dataArray);
    // CONFIGURANDO O PREENCIMENTO 
    canvasCtx.fillRect(0, 0, wid, hei);
    // INFORMA O INICIO DO DESENHO
    canvasCtx.beginPath();
    let x = 0;
    for (let i = 0; i < bufferLength; i++) {
        let v = dataArray[i] / 128.0;
        let y = v * hei / 2;
        if (i === 0) {
            canvasCtx.moveTo(x, y);
        } else {
            canvasCtx.lineTo(x, y);
        }
        x += sliceWidth;
    }
    // MANDA A LINHA PARA O CENTRO DO CANVAS 
    canvasCtx.lineTo(canvas.width, canvas.height / 2);
    canvasCtx.stroke();
}

Depois disso fazemos a camada da função draw() logo a baixo

draw();

Neste ponto, devemos ter isso

Sem Áudio:

 

 

 

 

 

Com Áudio

Código utilizado neste projeto:

[download id=”1268″]

Fontes:

https://pt.wikipedia.org/wiki/Transformada_r%C3%A1pida_de_Fourier

https://www.w3schools.com/graphics/canvas_drawing.asp

Código Adaptado do artigo:

https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API

Informações sobre Web Audio API:

https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API

Deixe um comentário