AutoAdvancePlugin
Most players need nothing more than “when the current track ends, play the next one.”
That is exactly what AutoAdvancePlugin does by default.
You can also tell it to buffer the next track a few seconds early, or hand off to a crossfade instead of a hard cut.
The plugin wires to two player events: ended for the actual advance, and trackEndingSoon for the early-warning preload and crossfade path.
The one time you leave this plugin out is when something else already drives next(), such as a WebSocket sync layer or a Cast session orchestrator.
In that case let the orchestrator call next() and skip this plugin entirely.
import nmMPlayer from '@nomercy-entertainment/nomercy-music-player';
import { AutoAdvancePlugin } from '@nomercy-entertainment/nomercy-music-player/plugins';
import type { MusicPlaylistItem } from '@nomercy-entertainment/nomercy-music-player';
Plugin id: 'auto-advance'
Options
| Option | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Master toggle. Set to false to pause all auto-advance behaviour without removing the plugin. |
preloadNextOnEnding | boolean | false | When true, calls player.load(next, { slot: 'next' }) on the trackEndingSoon event, buffering the next track before it is needed. |
crossfade | boolean | false | When true, calls player.crossfadeTo(next, { duration: crossfadeDuration }) on the trackEndingSoon event. |
crossfadeDuration | number | 0 | Crossfade duration in seconds when crossfade: true. 0 means a hard cut. Set this to match or be less than trackEndingSoonThreshold in the player config. |
Methods
advance()
advance(): Promise<void>
Force-advance to the next track immediately, regardless of playback state.
Calls player.next({ source: 'auto-advance' }).
preloadNext()
preloadNext(): Promise<void>
Peek the queue head and load it into the next slot. No-ops when there is no next track. Safe to call at any time.
addEndedHandler(fn)
addEndedHandler(fn: () => void | Promise<void>): void
Register an additional callback that runs after the built-in ended advance logic.
Use this for analytics, logging, or server sync that should follow the queue advance.
addPreloadHandler(fn)
addPreloadHandler(fn: (next: MusicPlaylistItem | undefined) => void | Promise<void>): void
Register an additional trackEndingSoon handler for preload behaviour.
next is the upcoming track, or undefined when the queue is exhausted.
addCrossfadeHandler(fn)
addCrossfadeHandler(fn: (next: MusicPlaylistItem | undefined, duration: number) => void | Promise<void>): void
Register an additional trackEndingSoon handler for crossfade behaviour.
duration is the resolved crossfadeDuration in seconds.
Execution order
When trackEndingSoon fires:
- If
preloadNextOnEnding: true, callspreloadNext() - If
crossfade: trueand there is a next track, callscrossfadeTo(next, { duration }) - All registered
preloadHandlersrun - All registered
crossfadeHandlersrun
When ended fires:
- Calls
player.next({ source: 'auto-advance' }) - All registered
endedHandlersrun
Registration
const player = nmMPlayer('main')
.addPlugin(AutoAdvancePlugin)
.setup({ playlist: myTracks });
With options:
player.addPlugin(AutoAdvancePlugin, {
enabled: true,
preloadNextOnEnding: true,
crossfade: true,
crossfadeDuration: 5,
});
Full example with crossfade, preload, and an analytics hook:
const player = nmMPlayer('main')
.addPlugin(AutoAdvancePlugin, {
crossfade: true,
crossfadeDuration: 5,
preloadNextOnEnding: true,
})
.setup({
baseUrl: 'https://raw.githubusercontent.com/NoMercy-Entertainment/nomercy-media/master/Music',
trackEndingSoonThreshold: 8,
crossfadeDefaults: {
duration: 5,
curve: 'equal-power',
},
playlist: [
{
id: 'kjc-01',
name: 'Thaw You Out',
url: '/D/Derek%20Clegg/%5B2010%5D%20KJC/01%20Thaw%20You%20Out.mp3',
artist: 'Derek Clegg',
},
{
id: 'kjc-02',
name: 'Hope',
url: '/D/Derek%20Clegg/%5B2010%5D%20KJC/02%20Hope.mp3',
artist: 'Derek Clegg',
},
],
});
const plugin = player.getPlugin(AutoAdvancePlugin)!;
plugin.addEndedHandler(() => {
analytics.track('track_completed', { id: player.item()?.id });
});
player.on('ready', () => {
player.item(0, { autoplay: true });
});
See also
- Crossfade,
crossfadeTo()API and crossfade events - Events,
trackEndingSoon,crossfadeStart,crossfadeComplete - Configuration,
trackEndingSoonThreshold - Recipes: Crossfade and Gapless, practical timing guide