Shoukaku
A stable and updated wrapper around Lavalink
This is a modified version used in our application infrastructure.
Shoukaku: https://github.com/shipgirlproject/Shoukaku
What's the difference?
We added the "player.info" interface, which wasn't included in Shoukaku, and implemented session recovery from a dump stored in Redis or a Database.
Please, make sure that only the added changes and examples of their usage will be shown, so it's recommended to familiarize yourself with the original repository before starting to read.
Track Interface:
export interface Track {
encoded: string;
info: TrackInfo;
};
export interface TrackInfo {
identifier: string;
isSeekable: boolean;
author: string;
duration: number;
isStream: boolean;
position: number;
title: string;
uri?: string;
sourceName?: string;
artworkUrl?: string;
isTrackUnavailable?: string;
isrc?: string;
};
Note that "isTrackUnavailable" won't be accessible, as it's used in our Lavalink fork to check if the track is regionally restricted or a preview.
So, now information will be available by calling:
shoukaku.players.get("id").track.info
Session Restore:
You should listen to the "raw" event from Shoukaku and redirect it to your functions, as regular "player.on" will stop working after a restart and will need to be reassigned manually.
shoukaku.on("raw", (name: string, json: any) => {
this.listeners[(json.op.type || json.op) as keyof PlayerListeners]?.(name, json)
});
"this.listeners" — the "PlayerListeners" assigned through the constructor. An example class is provided below.
export class PlayerListeners {
TrackStartEvent(name: string, data: TrackStartEvent) {
};
};
Following the example above, we listen to the "raw" event "playerUpdate" and store the data in a Database.
import { PlayerUpdate } from "@moscowcity/shoukaku";
export class PlayerListeners {
playerUpdate(name: string, data: PlayerUpdate) {
this.database.updateData("queue", { guild: data.guildId },
{ session: this.shoukaku.playersDump.get(data.guildId) }
);
};
};
Upon restart, we retrieve the data from the model and give it to Shoukaku.
const QueueData = (await Database.getAllData("queue")).filter((queue: any) => queue.session);
const PreviousSessions = QueueData.map((queue: QueueModel) => [queue.guild, queue.session]);
this.shoukaku = new Shoukaku(new Connectors.Eris(this.app.client),
this.app.config.values.nodes, {
moveOnDisconnect: true,
resume: true
}, PreviousSessions
);
© MoscowMusic Discord Bot