Overview
Discord Player provides utilities to serialize tracks and playlists into JSON-compatible format for storage and later restoration. This is useful for saving queue state, creating favorites systems, or implementing cross-session queue persistence.
Serialization Utilities
The serde module provides functions to serialize, deserialize, encode, and decode tracks and playlists.
import { serialize , deserialize , encode , decode } from 'discord-player' ;
Serializing Tracks
Basic Serialization
Convert a track to a serializable object:
import { serialize } from 'discord-player' ;
const track = queue . currentTrack ;
// Serialize to JSON-compatible object
const serialized = serialize ( track );
console . log ( serialized );
// {
// $type: 'track',
// title: 'Song Name',
// author: 'Artist Name',
// url: 'https://...',
// ...
// }
Track Method
Tracks have a built-in serialize() method:
const track = queue . currentTrack ;
const serialized = track . serialize ();
Serialized Track Structure
The serialized track includes:
Type identifier for deserialization
And other track metadata fields.
Serializing Playlists
Basic Serialization
import { serialize } from 'discord-player' ;
const playlist = searchResult . playlist ;
const serialized = serialize ( playlist );
console . log ( serialized );
// {
// $type: 'playlist',
// title: 'Playlist Name',
// tracks: [...],
// ...
// }
Playlist Method
const playlist = searchResult . playlist ;
const serialized = playlist . serialize ();
Serialized Playlist Structure
Type identifier for deserialization
Array of serialized tracks
Deserializing
Convert serialized data back into Track or Playlist objects:
import { deserialize } from 'discord-player' ;
// Deserialize a track
const serializedTrack = { $type: 'track' , title: '...' , /* ... */ };
const track = deserialize ( player , serializedTrack );
// Deserialize a playlist
const serializedPlaylist = { $type: 'playlist' , title: '...' , /* ... */ };
const playlist = deserialize ( player , serializedPlaylist );
Static Methods
Tracks and playlists provide static deserialization methods:
import { Track , Playlist } from 'discord-player' ;
// Deserialize track
const track = Track . fromSerialized ( player , serializedTrack );
// Deserialize playlist
const playlist = Playlist . fromSerialized ( player , serializedPlaylist );
Encoding and Decoding
For storage or transmission, you can encode serialized data to base64:
Encoding
import { encode } from 'discord-player' ;
const serialized = track . serialize ();
const encoded = encode ( serialized );
// Returns base64 string: "eyIkdHlwZSI6InRyYWNrIiwidGl0bGUiOi4uLn0="
Decoding
import { decode } from 'discord-player' ;
const encoded = "eyIkdHlwZSI6InRyYWNrIiwidGl0bGUiOi4uLn0=" ;
const decoded = decode ( encoded );
// Returns deserialized object
Complete Example: Queue Persistence
Save and restore queue state across bot restarts:
import { serialize , deserialize , encode , decode } from 'discord-player' ;
import fs from 'fs/promises' ;
// Save queue
async function saveQueue ( queue ) {
const queueData = {
tracks: queue . tracks . data . map ( track => serialize ( track )),
currentTrack: queue . currentTrack ? serialize ( queue . currentTrack ) : null ,
volume: queue . node . volume ,
repeatMode: queue . repeatMode
};
await fs . writeFile (
`queue- ${ queue . guild . id } .json` ,
JSON . stringify ( queueData , null , 2 )
);
console . log ( 'Queue saved!' );
}
// Restore queue
async function restoreQueue ( player , guildId , channel ) {
const data = await fs . readFile ( `queue- ${ guildId } .json` , 'utf-8' );
const queueData = JSON . parse ( data );
// Create new queue
const queue = player . queues . create ( guildId );
await queue . connect ( channel );
// Restore tracks
const tracks = queueData . tracks . map ( t => deserialize ( player , t ));
queue . addTrack ( tracks );
// Restore settings
queue . node . setVolume ( queueData . volume );
queue . setRepeatMode ( queueData . repeatMode );
// Play current track if exists
if ( queueData . currentTrack ) {
const current = deserialize ( player , queueData . currentTrack );
await queue . play ( current );
} else if ( tracks . length > 0 ) {
await queue . node . play ();
}
console . log ( 'Queue restored!' );
}
Database Storage Example
Store serialized tracks in a database:
import { serialize , deserialize } from 'discord-player' ;
// Save to database
async function saveFavorite ( userId , track ) {
const serialized = serialize ( track );
await db . favorites . create ({
userId ,
trackData: JSON . stringify ( serialized ),
addedAt: new Date ()
});
}
// Load from database
async function getFavorites ( player , userId ) {
const favorites = await db . favorites . findMany ({
where: { userId }
});
return favorites . map ( fav => {
const serialized = JSON . parse ( fav . trackData );
return deserialize ( player , serialized );
});
}
// Play a favorite
async function playFavorite ( queue , player , userId , index ) {
const favorites = await getFavorites ( player , userId );
const track = favorites [ index ];
if ( track ) {
queue . addTrack ( track );
if ( ! queue . isPlaying ()) {
await queue . node . play ();
}
}
}
Use Cases
Queue Persistence Save queue state across bot restarts
Favorites System Let users save their favorite tracks
Playlist Export Export playlists to JSON files
Queue Sharing Share queue configurations between servers
Type Safety
The serialization system is type-safe:
export enum SerializedType {
Track = 'track' ,
Playlist = 'playlist' ,
}
export type Encodable = SerializedTrack | SerializedPlaylist ;
The deserialize function automatically detects the type:
function deserialize ( player : Player , data : Encodable ) {
if ( data . $type === 'track' ) return Track . fromSerialized ( player , data );
if ( data . $type === 'playlist' ) return Playlist . fromSerialized ( player , data );
throw new DeserializationError ();
}
Error Handling
SerializationError
DeserializationError
try {
const serialized = serialize ( invalidData );
} catch ( error ) {
if ( error instanceof SerializationError ) {
console . error ( 'Failed to serialize data' );
}
}
Best Practices
Always validate serialized data before deserializing, especially if it comes from user input or external storage.
Include a version field in your serialized data to handle format changes gracefully.
Deserialize may fail if required fields are missing. Use try-catch blocks appropriately.
For large playlists, consider compressing the encoded string before storage.
Queue API Learn about queue management
Track Object Explore track properties