
Security News
Vite Releases Technical Preview of Rolldown-Vite, a Rust-Based Bundler
Vite releases Rolldown-Vite, a Rust-based bundler preview offering faster builds and lower memory usage as a drop-in replacement for Vite.
@educandu/multitrack-audio-player
Advanced tools
A multitrack audio player using the Web Audio API
A multitrack audio player using the Web Audio API
npm i -g gulp-cli
The output of this repository is an npm package (@educandu/multitrack-audio-player
).
$ yarn add @educandu/multitrack-audio-player
import { MultitrackAudioPlayer, TrackGroup, Track, ... } from '@educandu/multitrack-audio-player';
The Track
class is the main building block of this library and represents a single playable
audio file.
// Minimal example for creating a new track:
const track = new Track({ sourceUrl: 'https://somedomain.com/some-sound.mp3' });
// Full example for creating a new track:
const track = new Track({
// Mandatory, has to be a valid URL:
sourceUrl: 'https://somedomain.com/some-sound.mp3',
// Optional, has to be an array of two floats between 0 and 1 that indicate
// the range withing the media file that should be played (0 means the first sample,
// 1 means the last sample of the sound file). Default: [0, 1]
playbackRange = [0.25, 0.75],
// Optional, has to be an object with two fields:
// * `gain` (float between 0 and 1) that stands for the volume between 0% and 100%.
// * `mute` (boolean), if set to `true`, playback of this track will be muted.
// Default: { gain: 1, mute: false }
gainParams = { gain: 0.5, mute: false },
// Optional, will be used as a factor when calculating the actual gain of the track.
masterGain = 1,
// Optional, can be used to associate custom data with individual tracks. Default: {}
customProps: { key: 'some-key', name: 'My track', usage: 'internal' },
// Optional, will be used to decode the audio file, can be replaced
// by a custom implementation.
mediaDecoder = new MediaDecoder(),
// Optional, will be used to download the audio file, can be replaced
// by a custom implementation.
mediaDownloader = new MediaDownloader(),
// Optional, will be used to retrieve an `AudioContext` that is ready to be used,
// can be replaced by a custom implementation.
audioContextProvider = new AudioContextProvider(),
// Optional, will be called each time the track's `state` property has changed.
onStateChanged = (state, error) => { console.log(error ?? state); },
// Optional, will be called each time the track's `playState` property has changed.
onPlayStateChanged = playState => { console.log(playState); }
});
// Methods:
track.initialize(); // Waits for the audio context. Has to be called before loading.
track.load(); // Downloads and decodes the media file. Has to be called before any playback.
track.start(); // Starts at the current position, if not already playing.
track.start(5.5); // Starts the track 5.5 seconds into the media.
track.pause(); // Pauses the track at the current position.
track.stop(); // Stops the track at the current position, equivalent to calling `track.pause()`.
track.stop(true); // Stops the track and moves to the very end of the media.
track.dispose(); // Disposes this instance, no further calls should be made after this.
// Read-only properties:
console.log(track.customProps); // Any custom data associated with this track.
console.log(track.error); // The error in case the state of this track is 'faulted'.
console.log(track.sourceUrl); // The url of the loaded sound file.
console.log(track.state); // The track state.
console.log(track.playState); // The track's play state.
console.log(track.duration); // The track's duration as a float in seconds.
console.log(track.playbackRange); // The track's playback range.
// Read-write properties:
track.position = 3.75; // Sets the track's current playback position.
track.gainParams = { gain: 0.5, mute: false }; // Sets the track's gain params.
track.masterGain = 1; // Sets the track's master gain.
// Example for reading the current time code:
setInterval(() => console.log(track.position), 100);
// Example for changing the volume to 50%:
track.gainParams = { ...track.gainParams, gain: 0.5 };
The TrackGroup
class wraps a collection of tracks while providing an API (mostly) identical
to a single track. It manages state, play state and volume coordination between the tracks,
including solo state. It also adds options for automatic rewinding and looping.
// Example for creating a new track group:
const trackGroup = new TrackGroup({
// Mandatory, the track configuration
trackConfiguration: {
// Tracks with their initial configuration
tracks: [
{
sourceUrl: 'https://somedomain.com/some-sound.mp3',
playbackRange: [0, 1],
gainParams: { gain: 0.5, mute: false },
customProps: { name: 'First track' }
},
{
sourceUrl: 'https://somedomain.com/some-other-sound.mp3',
playbackRange: [0, 1],
gainParams: { gain: 0.75, mute: false },
customProps: { name: 'Second track' }
},
],
// Determines, which track should play solo initially (-1 for none)
soloTrackIndex: -1
},
// Optional, will automatically start from the beginning, when the end of the
// main track is reached (Play state will remain `started`). Default: false
loop: true,
// Optional, will automatically start from the beginning, when `start` is called
// after the track has been played previously unto the very end. Default: false
autoRewind: true,
// Optional, has to be an object with two fields:
// * `gain` (float between 0 and 1) that stands for the volume between 0% and 100%.
// * `mute` (boolean), if set to `true`, playback of this track will be muted.
// Default: { gain: 1, mute: false }
gainParams = { gain: 0.5, mute: false },
// Optional, will be used to decode the audio file, can be replaced
// by a custom implementation.
mediaDecoder = new MediaDecoder(),
// Optional, will be used to download the audio file, can be replaced
// by a custom implementation.
mediaDownloader = new MediaDownloader(),
// Optional, will be used to retrieve an `AudioContext` that is ready to be used,
// can be replaced by a custom implementation.
audioContextProvider = new AudioContextProvider(),
// Optional, will be called each time the track group's `state` property has changed.
onStateChanged = (state, error) => { console.log(error ?? state); },
// Optional, will be called each time the track group's `playState` property has changed.
onPlayStateChanged = playState => { console.log(playState); }
});
// Example for changing the volume to 50% in the second track:
trackGroup.tracks[1].gainParams = { ...track.gainParams, gain: 0.5 };
// Example for setting the second track as the solo track:
trackGroup.soloTrackIndex = 1;
The MultitrackAudioPlayer
class wraps a TrackGroup
and adds a clock with change notifications
on the current playback position as well as an option for automatic initialization and loading
on top. In most cases this is the API that should be used by consumers of this library.
// Example for creating a new player:
const player = new MultitrackAudioPlayer({
// Mandatory, the track configuration
trackConfiguration: {
// Tracks with their initial configuration
tracks: [
{
sourceUrl: 'https://somedomain.com/some-sound.mp3',
playbackRange: [0, 1],
gainParams: { gain: 0.5, mute: false },
customProps: { name: 'First track' }
},
{
sourceUrl: 'https://somedomain.com/some-other-sound.mp3',
playbackRange: [0, 1],
gainParams: { gain: 0.75, mute: false },
customProps: { name: 'Second track' }
},
],
// Determines, which track should play solo initially (-1 for none)
soloTrackIndex: -1
},
// Optional (default: false), will immediately start waiting for the audio context,
// without explicit call to the `initialize` function. Consumers nevertheless
// have to wait until the `state` changes to `initialized` before calling `load`.
autoInitialize: true,
// Optional (default: false), will immediately start loading the tracks after initialization,
// without explicit call to the `load` function. Consumers nevertheless have
// to wait until the `state` changes to `ready` before starting playback.
autoLoad: true,
// Optional, will automatically start from the beginning, when `start` is called
// after the track has been played previously unto the very end. Default: false
loop: true,
// Optional, will automatically start from the beginning, when the end of the
// main track is reached (Play state will remain `started`). Default: false
autoRewind: true,
// Optional, has to be an object with two fields:
// * `gain` (float between 0 and 1) that stands for the volume between 0% and 100%.
// * `mute` (boolean), if set to `true`, playback of this track will be muted.
// Default: { gain: 1, mute: false }
gainParams = { gain: 0.5, mute: false },
// Optional, will be used to decode the audio file, can be replaced
// by a custom implementation.
mediaDecoder = new MediaDecoder(),
// Optional, will be used to download the audio file, can be replaced
// by a custom implementation.
mediaDownloader = new MediaDownloader(),
// Optional, will be used to retrieve an `AudioContext` that is ready to be used,
// can be replaced by a custom implementation.
audioContextProvider = new AudioContextProvider(),
// Optional, will be called each time the track group's `state` property has changed.
onStateChanged = (state, error) => { console.log(error ?? state); },
// Optional, will be called each time the track group's `playState` property has changed.
onPlayStateChanged = playState => { console.log(playState); },
// Optional, will be called each time the current `position` property has changed.
onPositionChanged = position => { console.log(position); },
});
// Example for changing the volume to 50% in the second track:
player.tracks[1].gainParams = { ...track.gainParams, gain: 0.5 };
// Example for setting the second track as the solo track:
player.soloTrackIndex = 1;
// See the `Track` class for methods and properties
As downloading and decoding multiple media files can get pretty resource-intensive
(and therefore can even lead to browser craches), there is some concurrency control
built into this library that ensures that only a certain number of files can be
processed (downloaded/decoded) at the same time. In order to changes these global settings,
you can use the GlobalMediaQueue
object:
// Only allow 5 parallel downloads (default: 2)
GlobalMediaQueue.maxDownloadConcurrency = 5;
// Only allow 5 parallel decoding processes (default: 2)
GlobalMediaQueue.maxDecodingConcurrency = 5;
// Only allow 5 media files to be processed (i.e. downloaded AND decoded)
// at the same time (default: 2)
GlobalMediaQueue.maxMediaSourceConcurrency = 5;
Funded by 'Stiftung Innovation in der Hochschullehre'
A Project of the 'Hochschule für Musik und Theater München' (University for Music and Performing Arts)
Project owner: Hochschule für Musik und Theater München
Project management: Ulrich Kaiser
FAQs
A multitrack audio player using the Web Audio API
The npm package @educandu/multitrack-audio-player receives a total of 1 weekly downloads. As such, @educandu/multitrack-audio-player popularity was classified as not popular.
We found that @educandu/multitrack-audio-player demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Vite releases Rolldown-Vite, a Rust-based bundler preview offering faster builds and lower memory usage as a drop-in replacement for Vite.
Research
Security News
A malicious npm typosquat uses remote commands to silently delete entire project directories after a single mistyped install.
Research
Security News
Malicious PyPI package semantic-types steals Solana private keys via transitive dependency installs using monkey patching and blockchain exfiltration.