PlayOptions
export interface PlayOptions {
createNewInstance?: boolean; // Create a new instance of the sound when playing it. By default this is false. This is useful when you want to play the same sound multiple times simultaneously.
duration?:number; // in seconds
fadeInDuration?: number; // in seconds
fadeInStartVolume?: number; // 0 to 1
fadeOutDuration?: number; // in seconds, when you play a sound it will immidiately start fading out
fadeOutEndVolume?: number; // 0 to 1
fadeOutBeforeEndDuration?: number; // in seconds, fade out before the sound ends
groupId?: string; // Group ID for the sounds that will be in this group.
isSeeking?: boolean; // used internally for the seek method
loop?: boolean; // default: false
maxLoops?: number; // -1 for infinte, number > 0 for specific number of loops
pan?: number; // -1 (left) to 1 (right)
panSpatialPosition?: { x: number; y: number; z: number }; // If you want to use 3D panning you must also set panType to SoundPanType.Spatial
panType?: SoundPanType; // 'stereo' or 'spatial' (default is 'stereo')
pauseAtDurationReached?: boolean; // This will only work if you set the duration and if that duration is reached it will pause. Note: Loop must be false.
playbackRate?: number; // 0.5 to 4 (normal speed is 1)
startTime?: number; // in seconds
trackProgress?: boolean; // Track progress of the sound playback. This will keep track of the process and will dispatch the 'progress' event. This is useful when you want to show the progress of the sound playback.
volume?: number; // 0 to 1
}
You can use the PlayOptions to pass to the play() method.
Basic PlayOptions Example
The most common use case is setting basic playback options like volume, pan, and playback rate:
import { SoundManager, type PlayOptions } from 'sound-manager-ts';
const soundManager = new SoundManager();
await soundManager.loadSound('music', '/audio/music.mp3');
soundManager.play('music', {
volume: 0.8,
pan: 0.3,
playbackRate: 1.0,
startTime: 0,
});
// The sound plays at 80% volume, slightly panned to the right,
// at normal speed, starting from the beginning.
Fade In / Fade Out
You can smoothly fade a sound in when it starts playing and/or fade it out:
const soundManager = new SoundManager();
await soundManager.loadSound('voice', '/audio/voice.mp3');
// Fade in over 2 seconds, fade out over 3 seconds
soundManager.play('voice', {
volume: 1.0,
// Fade in settings
fadeInDuration: 2,
fadeInStartVolume: 0, // Start from silence
// Fade out settings
fadeOutDuration: 3,
fadeOutEndVolume: 0, // Fade to silence
});
// The sound fades in from 0 to full volume over 2 seconds,
// then immediately starts fading out over 3 seconds until silent.
Fade Out Before Sound Ends
If you want a natural fade-out just before a sound finishes playing (not immediately after start):
const soundManager = new SoundManager();
await soundManager.loadSound('jingle', '/audio/jingle.mp3');
soundManager.play('jingle', {
fadeOutBeforeEndDuration: 4, // Fade out the last 4 seconds
});
// The sound plays at full volume, then fades out smoothly
// during the final 4 seconds of playback.
Looping with maxLoops
Play a sound repeatedly for a specific number of times, or infinitely:
const soundManager = new SoundManager();
await soundManager.loadSound('bgm', '/audio/background.mp3');
// Loop 3 times then stop
soundManager.play('bgm', {
loop: true,
maxLoops: 3,
});
// The sound plays 3 times in total and then automatically stops.
// Infinite looping (plays until manually stopped)
soundManager.play('bgm', {
loop: true,
maxLoops: -1, // -1 means infinite
});
// Later, stop it manually:
soundManager.stop('bgm');
// The sound loops forever until stop() is called.
Duration and pauseAtDurationReached
Play a sound for a specific duration and automatically pause when that duration is reached:
const soundManager = new SoundManager();
await soundManager.loadSound('alert', '/audio/alert.mp3');
// Play only the first 5 seconds, then pause
soundManager.play('alert', {
duration: 5,
pauseAtDurationReached: true,
loop: false, // Must be false for pauseAtDurationReached to work
});
// After 5 seconds, the sound pauses automatically.
// Resume it later if needed:
soundManager.resume('alert');
Progress Tracking
Track the playback progress of a sound and listen for progress events:
const soundManager = new SoundManager();
await soundManager.loadSound('podcast', '/audio/podcast.mp3');
soundManager.play('podcast', {
trackProgress: true, // Enable progress tracking for this sound
});
// Listen for progress updates
soundManager.addEventListener('progress', (event) => {
console.log(`Progress: ${event.progressPercentage}%`);
console.log(`Current time: ${event.currentTime}s`);
console.log(`Duration: ${event.duration}s`);
});
// The progress event fires at regular intervals (default: every 250ms).
// You can configure the interval with setProgressUpdateInterval(ms).
Spatial Audio (3D Panning)
Use 3D spatial positioning for immersive audio experiences:
import { SoundManager, SoundPanType, type PlayOptions } from 'sound-manager-ts';
const soundManager = new SoundManager();
await soundManager.loadSound('explosion', '/audio/explosion.mp3');
soundManager.play('explosion', {
panType: SoundPanType.Spatial, // Enable 3D spatial audio
panSpatialPosition: { // Position in 3D space
x: 5,
y: 0,
z: -10,
},
volume: 0.9,
});
// The explosion sound is positioned 5 units to the right,
// at ground level, and 10 units behind the listener.
For comparison, stereo panning only requires a single pan value:
soundManager.play('explosion', {
panType: SoundPanType.Stereo, // This is the default if not specified
pan: -0.8, // -1 (full left) to 1 (full right)
});
// The explosion sound is panned hard to the left speaker.
Playing Multiple Instances (createNewInstance)
Play the same sound multiple times simultaneously, creating independent instances:
const soundManager = new SoundManager();
await soundManager.loadSound('coin', '/audio/coin.mp3');
// First instance
soundManager.play('coin', {
createNewInstance: false, // Default: uses the existing instance (re-plays it)
playbackRate: 1.0,
volume: 0.8,
pan: -0.5,
});
// Wait a moment, then play another instance while the first is still playing
setTimeout(() => {
soundManager.play('coin', {
createNewInstance: true, // Creates a new independent instance
playbackRate: 1.5, // Higher pitch
volume: 0.6,
pan: 0.5, // Different pan position
});
}, 500);
// Now two instances of 'coin' play simultaneously,
// each with their own playback rate, volume, and pan.
Sound Groups
Assign a sound to a group when playing it:
import { SoundManager, type PlayOptions } from 'sound-manager-ts';
const soundManager = new SoundManager();
await soundManager.loadSounds([
{ id: 'sfx1', url: '/audio/sfx1.mp3' },
{ id: 'sfx2', url: '/audio/sfx2.mp3' },
{ id: 'bgm', url: '/audio/music.mp3' },
]);
// Play sounds and assign them to a group
soundManager.play('sfx1', {
groupId: 'sfx',
volume: 0.7,
});
soundManager.play('sfx2', {
groupId: 'sfx',
volume: 0.5,
});
soundManager.play('bgm', {
groupId: 'music',
volume: 0.8,
loop: true,
});
// Stop all sounds in the 'sfx' group at once
const sfxGroup = soundManager.getGroup('sfx');
if (sfxGroup) {
sfxGroup.sounds.forEach(soundId => {
soundManager.stop(soundId);
});
}
// Or pause the entire music group
const musicGroup = soundManager.getGroup('music');
soundManager.pauseAllSounds(); // Pauses all sounds regardless of group
Complete Practical Example
A full example combining multiple PlayOptions features together:
import { SoundManager, SoundPanType, SoundEventsEnum, type PlayOptions } from 'sound-manager-ts';
const soundManager = new SoundManager();
async function playCinematicSound() {
await soundManager.loadSound('cinematic', '/audio/cinematic-intro.mp3');
// Play with advanced options
soundManager.play('cinematic', {
volume: 0.85,
pan: 0,
playbackRate: 1.0,
loop: false,
trackProgress: true,
// Fade in over 3 seconds starting from silence
fadeInDuration: 3,
fadeInStartVolume: 0,
// Fade out during the last 5 seconds
fadeOutBeforeEndDuration: 5,
});
// Set up duration display using progress tracking
soundManager.addEventListener(SoundEventsEnum.PROGRESS, (event) => {
if (event.soundId === 'cinematic') {
const progressBar = '█'.repeat(Math.round(event.progressPercentage / 10));
const emptyBar = '░'.repeat(10 - Math.round(event.progressPercentage / 10));
console.log(`[${progressBar}${emptyBar}] ${event.progressPercentage.toFixed(1)}%`);
}
});
// Listen for when the sound finishes
soundManager.addEventListener(SoundEventsEnum.FINISHED, (event) => {
if (event.soundId === 'cinematic') {
console.log('Cinematic playback finished.');
}
});
}
playCinematicSound();
Related Methods
play- Play a sound with PlayOptionsgetSoundState- Get the current state of a soundSoundManagerConfig- Configure default values for the sound manager