Skip to main content
The Playlist class represents a collection of tracks from sources like Spotify playlists, YouTube playlists, or albums.

Properties

id
string
Unique playlist identifier
title
string
Playlist title
description
string
Playlist description
thumbnail
string
Playlist thumbnail/cover art URL
type
'album' | 'playlist'
Whether this is an album or playlist
source
TrackSource
Source platform: “youtube”, “soundcloud”, “spotify”, “apple_music”, or “arbitrary”
author
object
Playlist author information
url
string
Playlist URL
tracks
Track[]
Array of tracks in this playlist
player
Player
The player instance
rawPlaylist
any
Raw playlist data from the extractor
estimatedDuration
number
Total duration of all tracks in milliseconds
durationFormatted
string
Formatted total duration (e.g., “1:23:45”)

Methods

toJSON()

Convert playlist to JSON:
const json = playlist.toJSON();
console.log(json.title, json.tracks.length);
withTracks
boolean
default:"true"
Whether to include track data in JSON
returns
PlaylistJSON
JSON representation of the playlist

serialize()

Serialize playlist for storage:
const serialized = playlist.serialize();
await db.playlists.save(serialized);
returns
SerializedPlaylist
Serialized playlist data including all tracks

fromSerialized()

Deserialize playlist from storage:
const data = await db.playlists.get(playlistId);
const playlist = Playlist.fromSerialized(player, data);
player
Player
required
Player instance
data
SerializedPlaylist
required
Serialized playlist data
returns
Playlist
Reconstructed playlist instance

play()

Play this playlist:
await playlist.play(voiceChannel, {
  nodeOptions: { metadata: interaction }
});
channel
GuildVoiceChannelResolvable
required
Voice channel to play in
options
PlayerNodeInitializerOptions
Play options
returns
Promise<PlayerNodeInitializationResult>
Play result with first track and queue info

Iterating Tracks

Playlists are iterable:
// Using for...of
for (const track of playlist) {
  console.log(track.title);
}

// Using spread operator
const allTracks = [...playlist];

// Direct array access
const firstTrack = playlist.tracks[0];
const trackCount = playlist.tracks.length;

Example Usage

Display Playlist Info

import { EmbedBuilder } from 'discord.js';

const result = await player.search('spotify playlist url', {
  requestedBy: interaction.user
});

const playlist = result.playlist;

if (!playlist) {
  return interaction.reply('No playlist found!');
}

const embed = new EmbedBuilder()
  .setTitle(playlist.title)
  .setDescription(playlist.description)
  .setURL(playlist.url)
  .setThumbnail(playlist.thumbnail)
  .addFields(
    {
      name: 'Type',
      value: playlist.type === 'album' ? '📀 Album' : '🎵 Playlist',
      inline: true
    },
    {
      name: 'Source',
      value: playlist.source,
      inline: true
    },
    {
      name: 'Tracks',
      value: playlist.tracks.length.toString(),
      inline: true
    },
    {
      name: 'Duration',
      value: playlist.durationFormatted,
      inline: true
    },
    {
      name: 'Author',
      value: `[${playlist.author.name}](${playlist.author.url})`,
      inline: true
    }
  );

await interaction.reply({ embeds: [embed] });

Play Entire Playlist

const result = await player.search(query, {
  requestedBy: interaction.user
});

if (result.playlist) {
  await result.playlist.play(voiceChannel, {
    nodeOptions: {
      metadata: interaction
    }
  });
  
  await interaction.reply(
    `Queued **${result.playlist.tracks.length}** tracks from **${result.playlist.title}**`
  );
}

Add Playlist Tracks to Queue

const queue = useQueue(interaction.guildId);
const result = await player.search(playlistUrl);

if (result.playlist) {
  queue.addTrack(result.playlist.tracks);
  
  await interaction.reply(
    `Added **${result.playlist.tracks.length}** tracks from **${result.playlist.title}** to the queue`
  );
}

Save Playlist to Database

const result = await player.search('spotify:playlist:...', {
  requestedBy: interaction.user
});

const playlist = result.playlist;

if (playlist) {
  // Serialize playlist
  const serialized = playlist.serialize();
  
  // Save to database
  await db.collection('playlists').insert({
    userId: interaction.user.id,
    name: playlist.title,
    data: serialized,
    createdAt: new Date()
  });
  
  await interaction.reply(`Saved playlist **${playlist.title}** to your library!`);
}

Load Saved Playlist

// Retrieve from database
const doc = await db.collection('playlists').findOne({
  userId: interaction.user.id,
  _id: playlistId
});

if (!doc) {
  return interaction.reply('Playlist not found!');
}

// Deserialize
const playlist = Playlist.fromSerialized(player, doc.data);

// Play it
await playlist.play(voiceChannel, {
  nodeOptions: { metadata: interaction }
});

await interaction.reply(`Now playing your saved playlist: **${playlist.title}**`);

Filter Tracks

const playlist = result.playlist;

// Get tracks over 5 minutes
const longTracks = playlist.tracks.filter(track => track.durationMS > 300000);

// Get tracks by specific artist
const artistTracks = playlist.tracks.filter(
  track => track.author.toLowerCase().includes('artist name')
);

// Play filtered tracks
queue.addTrack(longTracks);

TypeScript Types

interface PlaylistInitData {
  tracks: Track[];
  title: string;
  description: string;
  thumbnail: string;
  type: 'album' | 'playlist';
  source: TrackSource;
  author: {
    name: string;
    url: string;
  };
  id: string;
  url: string;
  rawPlaylist?: any;
}

interface PlaylistJSON {
  id: string;
  url: string;
  title: string;
  description: string;
  thumbnail: string;
  type: 'album' | 'playlist';
  source: TrackSource;
  author: {
    name: string;
    url: string;
  };
  tracks: TrackJSON[];
}

type SerializedPlaylist = ReturnType<Playlist['serialize']>;

Build docs developers (and LLMs) love