WebAudioAPI の AnalyserNode を使って音源をFFTで解析してビジュアライズするデモを作りました。ChromeとSafariで動作確認しています。
DEMO
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)();
と書くことでワンライナーで処理してます。