みかづきブログ・カスタム

基本的にはちょちょいのほいです。

音源をFFTで解析してビジュアライズする 🎶

WebAudioAPIAnalyserNode を使って音源をFFTで解析してビジュアライズするデモを作りました。ChromeとSafariで動作確認しています。


JavaScript

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const request = new XMLHttpRequest;
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

request.onload = function() {
  audioCtx.decodeAudioData(this.response, function(evt) {
    const source = audioCtx.createBufferSource();
    const analyser = audioCtx.createAnalyser(evt);

    const LENGTH = 32;
    const data = new Uint8Array(LENGTH);

    analyser.fftSize = 1024;

    source.buffer = evt;
    source.connect(audioCtx.destination);
    source.connect(analyser);

    source.loop = true;

    document.getElementById('canvas').addEventListener('click', function handleClick() {
      source.start();
      document.querySelector('.ttl').classList.add('none');
      this.removeEventListener('click', handleClick, false);
    }, false);

    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    tick();

    function tick() {
      canvas.width = canvas.width;
      canvas.height = canvas.height;

      ctx.fillStyle = '#3e3e3e';

      const w = canvas.width / LENGTH;

      analyser.getByteFrequencyData(data);

      for (let i = 0; i < LENGTH; ++i) {
        ctx.rect(i * w, canvas.height - data[i], w, data[i]);
      }

      ctx.fill();

      requestAnimationFrame(tick);
    }
  });
};

request.open('GET', 'bgm.mp3', true);
request.responseType = 'arraybuffer';

request.send();




個人的にポイントだと思っているところは一点だけで、ChromeだとAudioContext、SafariだとwebkitAudioContextを使わなければならない点です。

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

と書くことでワンライナーで処理してます。