𧬠Colmena Waveform Playlist: A Deep Dive #
A comprehensive guide to the
colmena-waveform-playlist, a multitrack web audio editor inspired by Audacity.
π Overview #
colmena-waveform-playlist is a powerful fork of the original waveform-playlist library. It’s a feature-rich, in-browser audio editor that uses the Web Audio API to provide multitrack editing capabilities with a canvas waveform preview.
Key features include:
- Multitrack Editing: Load and manage multiple audio tracks.
- Waveform Visualization: Renders interactive waveforms for each track.
- Core Editing: Set cue points, create fades (in/out), and shift tracks in time.
- Recording: Record new audio directly in the editor.
- Annotations: Add time-based text annotations to tracks.
- Effects: Integrate effects from the popular
Tone.jslibrary. - Export: Export the final mix as an
AudioBufferor a.wavfile.
β¨ Fork-Specific Features #
The ColmenaDev fork adds critical new events and functionalities not present in the original, making it a more complete editor:
undo/redo: Full undo/redo stack for editor actions.commit: Commits changes to the state.split: Splits a track at the cursor position.cut: Removes a selected portion of a track.importZipProject/exportZipProject: Save and load entire projects.
π οΈ 1. Installation #
Interestingly, you install this fork using the original npm package name.
# Install via npm
npm install waveform-playlist --save
You can also get it via a CDN like Unpkg: https://unpkg.com/browse/waveform-playlist/
π¬ 2. Quick Start #
Here is a basic setup to get a playlist running in your HTML.
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Colmena Waveform Playlist</title>
</head>
<body>
<div id="playlist"></div>
<script src="https://unpkg.com/waveform-playlist/dist/waveform-playlist.js"></script>
<script src="app.js"></script>
</body>
</html>
JavaScript (app.js):
// 1. Initialize the playlist
const playlist = WaveformPlaylist({
samplesPerPixel: 4096, // Zoom level
waveHeight: 90,
container: document.getElementById('playlist'),
state: 'cursor', // Initial interaction state
colors: {
waveOutlineColor: '#E0EFF1',
timeColor: 'grey',
fadeColor: 'black',
},
zoomLevels: [512, 1024, 2048, 4096],
});
// 2. Load audio tracks
playlist.load([
{
src: 'media/audio/Vocals30.mp3',
name: 'Vocals',
gain: 0.7,
},
{
src: 'media/audio/BassDrums30.mp3',
name: 'Drums',
start: 5.0, // Start 5 seconds into the playlist
fadeIn: { duration: 0.5 },
fadeOut: { shape: 'logarithmic', duration: 1.0 },
},
]).then(function () {
// 3. Setup event listeners to control the playlist
const ee = playlist.getEventEmitter();
// ee.emit('play');
console.log('Playlist loaded and ready.');
});
π§ 3. Core Concepts #
The Playlist Object #
This is the main object created by WaveformPlaylist(). It takes a large configuration object to customize its appearance and behavior. Key options include:
container: The DOM element to render the playlist in (Required).samplesPerPixel: The initial zoom level.waveHeight: The height of each track’s waveform.colors: An object to customize UI colors.controls: Configuration for the track control panel (mute, solo, volume).effects: A function to insert a custom Web Audio graph (e.g., forTone.js).
Track Configuration #
When you .load() tracks, each track is an object with its own set of options:
src: Path to the audio file, a Blob, or an AudioBuffer.name: Display name for the track.start: Time in seconds where the track begins in the playlist.cuein/cueout: The start and end points of the audio to use from the source file.fadeIn/fadeOut: Objects defining the duration and shape of fades.stereoPan: A value from -1 (left) to 1 (right).
The Event Emitter #
Interaction is handled through a built-in event emitter. You get it via playlist.getEventEmitter().
- Invoking Events: You can control the playlist by emitting events like
play,stop,trim,zoomin,cut,undo, etc. - Listening to Events: The playlist emits events about its state, such as
timeupdate,select(when a user selects a region), andaudiosourcesloaded.
π‘ 4. API Deep Dive: Events #
Mastering the event system is key to building a full-featured editor.
Events to Invoke (a selection):
| Event | Arguments | Description |
|---|---|---|
play |
start?, end? |
Plays the timeline, optionally within a range. |
stop |
- | Stops playback. |
trim |
- | Trims the selection, removing audio outside it. |
cut |
- | (Fork) Cuts the selected audio region. |
split |
- | (Fork) Splits the track at the playhead. |
undo |
- | (Fork) Reverts the last action. |
redo |
- | (Fork) Restores the last undone action. |
zoomin |
- | Zooms in one level. |
zoomout |
- | Zooms out one level. |
statechange |
state |
Changes the mouse interaction mode (‘cursor’, ‘select’, ‘shift’). |
exportZipProject |
- | (Fork) Exports the project state and assets to a zip. |
Events to Listen For (a selection):
| Event | Arguments | Description |
|---|---|---|
timeupdate |
playbackPosition |
Fired continuously during playback. |
select |
start, end, track |
Fired when a user makes or clears a selection. |
audiosourcesloaded |
- | Fired when all initial tracks have been loaded and decoded. |
audiosourcesrendered |
- | Fired when all waveforms have been drawn. |
audiorenderingfinished |
type, data |
Fired when an export is complete. type is ‘wav’ or ‘buffer’. |
zipProjectExported |
blob |
(Fork) Fired when the project zip has been created. |
π» 5. Development #
To contribute or run examples locally:
# Install dependencies
npm install
# Start the webpack dev server
npm start
# To also build the Jekyll example pages
gem install jekyll
npm run dev
# Run tests
npm test