Guide
Data modes
The three ways to get audio data into the visualizer — local, WebSocket, and external.
The visualizer has one job — render a spectrum — and three ways to get the data, selected
with the mode option (a prop in Vue, a constructor option in Core).
| Mode | How data arrives | Use when |
|---|---|---|
local | Captures mic or display audio and computes the FFT in-browser (Rust/WASM) | You want a zero-backend, client-side visualizer |
websocket (default) | Connects to websocketUrl and reads pre-computed FFT frames | A server/device already produces FFT data (e.g. a Raspberry Pi) |
external | You pass FFT magnitudes as data / dataLeft / dataRight | You have your own audio pipeline (Web Audio, another analyser, etc.) |
Local mode
Set audioSource to display to capture tab/system audio via screen sharing instead of the
microphone.
new FFTVisualizer(canvas, { mode: 'local', audioSource: 'mic', bands: 80 })
<FFTVisualizer mode="local" audio-source="mic" :bands="80" />
WebSocket mode
The server streams a small config message then binary FFT frames — see the
WebSocket protocol. Reference servers for Python, Node.js and
Rust are in the repository's backend-examples/.
new FFTVisualizer(canvas, {
mode: 'websocket',
websocketUrl: 'wss://your-server/fft',
bands: 40,
autoReconnect: true
})
<FFTVisualizer
mode="websocket"
websocket-url="wss://your-server/fft"
:bands="40"
:auto-reconnect="true"
/>
On an HTTPS page you must use a
wss:// URL — browsers block insecure ws:// from
secure pages as mixed content.External mode
Pass a Uint8Array of magnitudes (0–255); update it and the visual follows. For stereo,
pass dataLeft and dataRight instead of data.
const viz = new FFTVisualizer(canvas, { mode: 'external', bands: 40 })
// ...each frame, feed fresh magnitudes (the data is copied):
viz.feedData(myUint8Array)
<script setup>
import { ref } from 'vue'
import { FFTVisualizer } from 'fft-visualizer-vue'
const data = ref(new Uint8Array(80))
// ...fill data.value from your own analyser each frame
</script>
<template>
<FFTVisualizer mode="external" :data="data" :bands="40" />
</template>
Feed data by copy for in-place buffers. Core's
feedData() copies the data, so reusing
one Uint8Array each frame is fine. In Vue the data prop is watched by reference — if
you mutate the same array in place, Vue won't detect the change, so either assign a fresh
array or call the exposed feedData() method (which also copies).