Skip to content

naomiaro/waveform-playlist

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,416 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Waveform Playlist

A multi-track audio editor and player built with React, Tone.js, and the Web Audio API. Features canvas-based waveform visualization, drag-and-drop clip editing, and professional audio effects.

Waveform Playlist Screenshot

Features

  • Multi-track editing - Multiple clips per track with drag-to-move and trim
  • Waveform visualization - Canvas-based rendering with zoom controls
  • 20+ audio effects - Reverb, delay, filters, distortion, and more via Tone.js
  • Recording - AudioWorklet-based recording with live waveform preview
  • Export - WAV export with effects, individual tracks or full mix
  • Annotations - Time-synced text annotations with keyboard navigation
  • Theming - Full theme customization with dark/light mode support
  • MIDI playback - MIDI file parsing with piano roll visualization and SoundFont sample playback
  • TypeScript - Full type definitions included

Quick Start

npm install @waveform-playlist/browser tone @dnd-kit/react

Note: tone and @dnd-kit/react are peer dependencies and must be installed separately. @dnd-kit/dom and @dnd-kit/abstract are transitive dependencies of @dnd-kit/react.

import { WaveformPlaylistProvider, Waveform, PlayButton, PauseButton, StopButton } from '@waveform-playlist/browser';
import { createTrack, createClipFromSeconds } from '@waveform-playlist/core';

function App() {
  const [tracks, setTracks] = useState([]);

  // Load audio and create tracks
  useEffect(() => {
    async function loadAudio() {
      const response = await fetch('/audio/song.mp3');
      const arrayBuffer = await response.arrayBuffer();
      const audioContext = new AudioContext();
      const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);

      const track = createTrack({
        name: 'My Track',
        clips: [createClipFromSeconds({ audioBuffer, startTime: 0 })],
      });

      setTracks([track]);
    }
    loadAudio();
  }, []);

  return (
    <WaveformPlaylistProvider tracks={tracks}>
      <div>
        <PlayButton />
        <PauseButton />
        <StopButton />
      </div>
      <Waveform />
    </WaveformPlaylistProvider>
  );
}

Documentation

Examples

Example Description
Stem Tracks Multi-track playback with mute/solo/volume controls
Effects 20 Tone.js effects with real-time parameter control
Recording Live recording with VU meter and waveform preview
Multi-Clip Drag-and-drop clip editing with trim handles
Annotations Time-synced text with keyboard navigation
Waveform Data Pre-computed peaks for fast loading
MIDI MIDI file playback with piano roll and SoundFont samples
Beats & Bars Tempo-synced timescale with beats and bars ruler
Fades Fade in/out with configurable curves
Stereo Stereo waveform rendering and pan controls
Spectrogram FFT-based spectrogram visualization
Media Element HTMLMediaElement playout with playback rate
Styling Bar width, gaps, gradients, and theme colors
Flexible API Custom playheads, timestamps, and full UI customization

Packages

Package Description
@waveform-playlist/browser Main React components, hooks, and context
@waveform-playlist/core Types, utilities, and clip/track creation
@waveform-playlist/engine Framework-agnostic timeline engine with pure operations
@waveform-playlist/ui-components Styled UI components (buttons, sliders, etc.)
@waveform-playlist/playout Tone.js audio engine
@waveform-playlist/webaudio-peaks Peak extraction from AudioBuffer or sample arrays
@waveform-playlist/loaders Audio loaders

Optional packages:

Package Description
@waveform-playlist/midi MIDI file parsing, piano roll visualization, and SoundFont playback
@waveform-playlist/annotations Time-synced text annotations with drag editing
@waveform-playlist/recording AudioWorklet recording with live waveform preview (requires setup)
@waveform-playlist/worklets Shared AudioWorklet processors for metering and recording (auto-installed with recording)
@waveform-playlist/spectrogram Spectrogram visualization with FFT worker
@waveform-playlist/media-element-playout HTMLMediaElement-based playout with pitch-preserving playback rate

Key Hooks

// Load audio files into tracks
const { tracks, loading, error } = useAudioTracks([
  { src: '/audio/vocals.mp3', name: 'Vocals' },
  { src: '/audio/drums.mp3', name: 'Drums' },
]);

// Playback controls
const { play, pause, stop, seekTo } = usePlaylistControls();

// Playback animation (60fps updates)
const { currentTime, isPlaying } = usePlaybackAnimation();

// Zoom controls
const { zoomIn, zoomOut, samplesPerPixel } = useZoomControls();

// Master effects chain
const { masterEffects, toggleBypass, updateParameter } = useDynamicEffects();

// WAV export
const { exportWav, isExporting, progress } = useExportWav();

// Recording
const { startRecording, stopRecording, isRecording } = useIntegratedRecording();

Web Components (Experimental)

@dawcore/components provides framework-agnostic Web Components for multi-track audio editing — no React required. Built with Lit, using @dawcore/transport for native Web Audio playback (no Tone.js dependency).

npm install @dawcore/components
<script type="module">
  import '@dawcore/components';
</script>

<daw-editor id="editor" clip-headers interactive-clips timescale file-drop>
  <daw-track name="Vocals">
    <daw-clip src="/audio/vocals.mp3" start="0" duration="10"></daw-clip>
  </daw-track>
  <daw-keyboard-shortcuts playback splitting undo></daw-keyboard-shortcuts>
</daw-editor>

<daw-transport for="editor">
  <daw-play-button></daw-play-button>
  <daw-pause-button></daw-pause-button>
  <daw-stop-button></daw-stop-button>
  <daw-record-button></daw-record-button>
</daw-transport>

Features:

  • Declarative <daw-track> and <daw-clip> elements with auto-loading
  • Clip move, trim, and split with collision detection
  • Undo/redo with transaction-based grouping
  • Keyboard shortcuts (Space=play/pause, S=split, Cmd/Ctrl+Z=undo)
  • File drop for adding tracks
  • Recording with overdub and latency compensation
  • Metronome with mixed meters and tempo changes
  • Tempo automation — linear ramps and Möbius-Ease curves with exact integration
  • Pre-computed peaks for fast initial render
  • Native Web Audio — no Tone.js, full sampleRate and latencyHint control

Packages:

Package Description
@dawcore/components Lit Web Components for multi-track editing
@dawcore/transport Native Web Audio transport — scheduling, looping, tempo automation, time signatures, metronome

Run the examples locally:

cd packages/dawcore && pnpm dev:page

Then open http://localhost:5173/dev/ — example pages:

  • index.html — Basic playback with timescale and file drop
  • multiclip.html — Multi-clip editing with move, trim, and split
  • record.html — Recording with overdub
  • metronome.html — Metronome with mixed meters, tempo presets, and looping sequences
  • automation.html — Tempo automation with step, linear, and curve presets

Browser Support

Requires Web Audio API support: Chrome, Firefox, Safari, Edge (modern versions).

See Can I Use: Web Audio API

Development

# Install dependencies
pnpm install

# Start dev server
pnpm website

# Run tests
pnpm test

# Build all packages
pnpm build

Visit http://localhost:3000/waveform-playlist to see the examples.

Books

Currently writing: Mastering Tone.js

Mastering Tone.js

Credits

Originally created for the Airtime project at Sourcefabric.

License

MIT License

Sponsors

Moises.ai

Become a sponsor

Partners

Télécom Paris

About

Multitrack Web Audio editor and player with canvas waveform preview. Set cues, fades and shift multiple tracks in time. Record audio tracks or provide audio annotations. Export your mix to AudioBuffer or WAV! Add effects from Tone.js. Project inspired by Audacity.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

 
 
 

Contributors