Skip to content

Playlist and Queue

Queue manipulation beyond the basic queue([...]) call in the quickstart: inserting tracks mid-stream, a shuffle toggle, peek-ahead for preloading, or custom repeat behaviour. The queue API is identical on video and music players. Examples use the music player but every method applies to both.

Queue basics

TypeScript
import nmMPlayer from '@nomercy-entertainment/nomercy-music-player';

const player = nmMPlayer('main').setup({
playlist: [track1, track2, track3], // initial queue
});

// Replace the entire queue:
player.queue([trackA, trackB, trackC]);

// Read the queue (returns a readonly snapshot):
const tracks = player.queue();
console.log(tracks.length); // 3

Append, prepend, and insert

TypeScript
// Add to the end:
player.queueAppend(track4);

// Add at the start of the queue (index 0):
player.queuePrepend(track5);

// Insert at a specific index:
player.queueInsert(track6, 2); // inserts before index 2

Remove and move

TypeScript
// Remove by item id:
player.queueRemove('track-id-3');

// Move a track from one position to another:
player.queueMove(0, 4); // move index 0 to index 4

Jump to a track

TypeScript
// Set current item by id or by object reference:
player.item(track2);

// Jump to index:
player.seekToIndex(2);

// Read current item:
const nowPlaying = player.item();

Peek next and previous

Peek is read-only, it does not change playback:

TypeScript
const next = player.peekNext(); // next item in queue | undefined
const prev = player.peekPrevious(); // previous item | undefined

// Use peek for preloading artwork before a crossfade:
player.on('trackEndingSoon', async ({ remaining }) => {
const upcoming = player.peekNext();
if (upcoming) await prefetchArtwork(upcoming);
});

Shuffle

TypeScript
import { ShuffleState } from '@nomercy-entertainment/nomercy-music-player';

player.shuffleState(ShuffleState.ON);
player.shuffleState(ShuffleState.OFF);

// Read state:
const shuffled = player.shuffleState(); // ShuffleState.ON | ShuffleState.OFF

// Listen for changes:
player.on('shuffle', ({ state }) => {
updateShuffleButton(state === ShuffleState.ON);
});

When shuffle is on, peekNext() returns the next shuffled item.

Repeat modes

TypeScript
import { RepeatState } from '@nomercy-entertainment/nomercy-music-player';

player.repeatState(RepeatState.OFF); // no repeat
player.repeatState(RepeatState.ONE); // repeat the current track
player.repeatState(RepeatState.ALL); // repeat the entire queue

// Read state:
const repeat = player.repeatState();

player.on('repeat', ({ state }) => {
updateRepeatButton(state);
});

AutoAdvancePlugin calls player.next() when a track ends. The player’s next() implementation respects repeat state: when RepeatState.ONE is set, it reloads and replays the current track instead of advancing the queue cursor.

AutoAdvancePlugin

AutoAdvancePlugin drives automatic advancement when a track ends. Without it, the player stops at the end of each track.

TypeScript
import { AutoAdvancePlugin } from '@nomercy-entertainment/nomercy-music-player/plugins';

player.addPlugin(AutoAdvancePlugin, {
crossfade: true, // use crossfade instead of immediate next()
crossfadeDuration: 5, // seconds (defaults to crossfadeDefaults.duration)
});
TypeScript
import { AutoAdvancePlugin } from '@nomercy-entertainment/nomercy-music-player/plugins';

player.addPlugin(AutoAdvancePlugin);
// When the current track ends, player.next() is called automatically

Sorting the queue

Use player.queueSort((a, b) => (a.name ?? '').localeCompare(b.name ?? '')) to sort in place, or sort the array yourself and set it:

TypeScript
const sorted = [...player.queue()].sort((a, b) => a.name.localeCompare(b.name));
player.queue(sorted);

For in-place shuffling, use Fisher-Yates before setting:

TypeScript
function shuffle<T>(array: T[]): T[] {
const out = [...array];
for (let i = out.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[out[i], out[j]] = [out[j], out[i]];
}
return out;
}

player.queue(shuffle([...player.queue()]));

This is a blunt replacement, but the active track is preserved because the player matches by id.

Queue events

TypeScript
player.on('current', ({ item, index }) => {
// fires when the active track changes
nowPlayingDisplay.textContent = item.name;
});

player.on('queue', (items) => {
// fires when the queue array changes (append, remove, reorder, replace)
renderQueueList(items);
});