From dad6510fd41b6efc1aad95a1b4ed5c1bc931e154 Mon Sep 17 00:00:00 2001 From: Yuzu Date: Sat, 17 Aug 2024 20:10:50 +0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Skip=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/speaker.ts | 9 +++--- src/player/index.ts | 55 ++++++++++++++++++++++--------------- src/utils/Request.ts | 3 +- src/utils/SeekableStream.ts | 4 +++ 4 files changed, 43 insertions(+), 28 deletions(-) diff --git a/example/speaker.ts b/example/speaker.ts index 0875028..71cd559 100644 --- a/example/speaker.ts +++ b/example/speaker.ts @@ -21,12 +21,10 @@ const main = async () => { player.startCurrentStream(); }); - const info = await player.enqueue( - `https://www.youtube.com/watch?v=${videoId}`, - ); - console.log(info); - + await player.enqueue(`https://www.youtube.com/watch?v=${videoId}`); await player.enqueue(`https://www.youtube.com/watch?v=${videoId2}`); + + console.log(player.getQueue()); }; let lastFFmpeg: ffmpeg.FfmpegCommand | null = null; @@ -68,6 +66,7 @@ const playSpeaker = async (player: Player) => { // .on("end", async () => { // await closeSpeaker(); // }) + // @ts-expect-error - ffmpeg typings are incorrect .on("error", (err) => { console.error("[FFmpeg] > Error:", err.message); }); diff --git a/src/player/index.ts b/src/player/index.ts index baf4725..a701eb9 100644 --- a/src/player/index.ts +++ b/src/player/index.ts @@ -12,6 +12,7 @@ export class Player { private currentAudioInformation: AudioInformation | null = null; public _stream: SeekableStream | null = null; + private _skipFlag: boolean = false; constructor(providers: Provider[]) { this.providers = providers; @@ -25,26 +26,17 @@ export class Player { information: AudioInformation, url: string, seekTime: number, + noDestroy: boolean = false, ) { // If already playing, destroy the current stream - if (this._stream) { + if (this._stream && !noDestroy) { this._stream.destroy(); } this._stream = new SeekableStream(information, url, seekTime); this.currentAudioInformation = information; this._stream.on("destroy", () => { - console.log("Stream destroyed, total song", this.queue.length); - if (this.queue.length > 0) { - const next = this.queue.shift(); - console.log("Playing next in queue"); - if (next) { - this._createStream(next, next.url, 0); - } - } else { - this._stream = null; - this.currentAudioInformation = null; - } + console.debug("Stream destroyed"); }); this.playerEvent.emit("play", information); @@ -56,10 +48,30 @@ export class Player { } } - public endCurrentStream() { + public endCurrentStream(skip: boolean = false) { + if (this._skipFlag) { + return; + } + + if (skip) { + this._skipFlag = true; + } + if (this._stream) { this._stream.destroy(); } + + if (this.queue.length > 0) { + const next = this.queue.shift(); + if (next) { + this._createStream(next, next.url, 0); + } + } else { + this._stream = null; + this.currentAudioInformation = null; + } + + this._skipFlag = false; } public on(event: string, listener: (...args: any[]) => void) { @@ -79,12 +91,17 @@ export class Player { this.currentProvider = providers[0]; } + console.debug( + "Using provider", + this.currentProvider.constructor.name, + url, + ); + return await this.currentProvider.getInformation(url); } public async play(url: string, seekTime: number = 0) { const information = await this.getInformation(url); - //console.log(information); if (information.livestream) // TODO: Implement livestreams @@ -124,14 +141,8 @@ export class Player { } public async skip() { - if (this.queue.length === 0) { - throw new Error("No song in queue"); - } - - const next = this.queue.shift(); - if (next) { - this._createStream(next, next.url, 0); - } + this.endCurrentStream(true); + console.debug("Skipping"); } public getCurrentSampleRate() { diff --git a/src/utils/Request.ts b/src/utils/Request.ts index 8e71aee..9920125 100644 --- a/src/utils/Request.ts +++ b/src/utils/Request.ts @@ -65,7 +65,7 @@ export async function getYouTubeFormats(id: string) { waitUntil: "networkidle2", }); const body = await page.evaluate(() => document.body.innerHTML); - await page.close(); + page.close(); const match = body.match( /var ytInitialPlayerResponse = (.*?)(?=;\s*<\/script>)/, @@ -91,6 +91,7 @@ export async function getYouTubeFormats(id: string) { return formats; } catch (err) { + console.error(err); throw new Error("Failed to parse YouTube formats"); } } diff --git a/src/utils/SeekableStream.ts b/src/utils/SeekableStream.ts index 01dc525..ee4f44c 100644 --- a/src/utils/SeekableStream.ts +++ b/src/utils/SeekableStream.ts @@ -366,6 +366,10 @@ export class SeekableStream { this.event.on(event, listener); } + public removeAllListeners(event: string) { + this.event.removeAllListeners(event); + } + public destroy() { if (this.destroyed) return;