Getting Started
DancingPluginSdk provides type definitions, lifecycle contracts, and audio data interfaces for building visualizer plugins that run inside the DancingMusic host application.
Install
npm install @musicdance/plugin-sdk
Basic usage
import type { DancePlugin, AudioData } from '@musicdance/plugin-sdk';
const myPlugin: DancePlugin = {
config: {
id: 'my-visualizer',
name: 'My Visualizer',
description: 'A custom visualizer plugin',
author: 'Your Name',
version: '1.0.0',
category: 'abstract',
price: 0,
},
init(canvas) { /* set up rendering context */ },
render(audioData, deltaTime, isPlaying) { /* draw frame */ },
dispose() { /* release resources */ },
};
Plugin Lifecycle
Every plugin follows a strict lifecycle managed by the host:
init(canvas)— Called once when the plugin is activated. Store a reference to the canvas and set up your rendering context (Canvas 2D, WebGL, Three.js).resize(width, height)— Called when the canvas dimensions change. Optional.render(audioData, deltaTime, isPlaying)— Called every animation frame (~60 fps). Draw your visualization using the real-time audio data.dispose()— Called when the plugin is switched out. Release all resources.
Optional hooks:
updateSettings(settings)— Called when the user changes plugin settings via the UI.setAudioSource(audioContext, sourceNode)— Called when the Web Audio graph becomes available.
Example Plugin
A minimal spectrum bar visualizer:
import type { DancePlugin } from '@musicdance/plugin-sdk';
let ctx: CanvasRenderingContext2D | null = null;
export const spectrumBars: DancePlugin = {
config: {
id: 'spectrum-bars', name: 'Spectrum Bars',
description: 'Simple frequency bar chart',
author: 'Demo', version: '1.0.0',
category: 'abstract', price: 0,
},
init(canvas) { ctx = canvas.getContext('2d'); },
render(audio, dt, playing) {
if (!ctx) return;
const { width: w, height: h } = ctx.canvas;
ctx.clearRect(0, 0, w, h);
const bars = audio.frequencyData.length;
const barW = w / bars;
for (let i = 0; i < bars; i++) {
const barH = (audio.frequencyData[i] / 255) * h;
ctx.fillStyle = `hsl(${i / bars * 240}, 80%, 55%)`;
ctx.fillRect(i * barW, h - barH, barW - 1, barH);
}
},
dispose() { ctx = null; },
};
DancePlugin
The core plugin interface. Every plugin must implement this.
| Method | Signature | Description |
|---|---|---|
init | (canvas: HTMLCanvasElement) => void | Set up rendering context |
render | (audioData, deltaTime, isPlaying) => void | Draw one frame (~60 fps) |
dispose | () => void | Release all resources |
resize | (width, height) => void | Handle canvas resize optional |
updateSettings | (settings) => void | React to user config changes optional |
setAudioSource | (ctx, node) => void | Access Web Audio graph optional |
DancePluginConfig
Static metadata and configurable settings for a plugin.
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (kebab-case) |
name | string | Display name |
description | string | Short description |
author | string | Author name |
version | string | SemVer version string |
category | 'abstract' | 'particle' | 'geometric' | 'nature' | 'other' | Plugin category |
price | number | Price (0 = free) |
thumbnail | string | Preview image URL optional |
settings | Record<string, Setting> | User-configurable parameters optional |
Settings types
Each setting supports type: 'number' | 'boolean' | 'color' | 'select' with label, default, and optional min/max/options.
AudioData
Real-time audio analysis data passed to render() every frame.
| Field | Type | Description |
|---|---|---|
frequencyData | Uint8Array | Full frequency spectrum (0–255 per bin) |
timeDomainData | Uint8Array | Time-domain waveform |
bassLevel | number | Low-frequency energy (0–1) |
midLevel | number | Mid-frequency energy (0–1) |
trebleLevel | number | High-frequency energy (0–1) |
volume | number | Overall volume (0–1) |
energy | number | Non-linear energy curve (0–1) |
beatDetected | boolean | True when a beat is detected |
bpm | number | Estimated BPM (0 if not computed) |
bassChange | number | Bass change rate (-1 to 1) |
volumeChange | number | Volume change rate (-1 to 1) |
PluginRegistry
Types for the remote plugin registry endpoint.
PluginRegistryEntry
| Field | Type | Description |
|---|---|---|
id | string | Plugin identifier |
bundleUrl | string | URL of the ESM plugin bundle |
sdkVersion | string | SDK version range (semver) |
checksumSha256 | string | Bundle integrity hash optional |
tags | string[] | Searchable tags optional |
publishedAt | string | ISO date string optional |
PluginRegistry wraps an array of entries with version and updatedAt.
createEmptyAudioData()
Returns a zeroed-out AudioData object. Useful for rendering in paused/idle state, or for unit tests.
import { createEmptyAudioData } from '@musicdance/plugin-sdk';
const idle = createEmptyAudioData();
plugin.render(idle, 0.016, false);