From 38c0e209a0756941a1ff0e9118f082cb1e63c329 Mon Sep 17 00:00:00 2001 From: DevAndromeda <46562212+DevAndromeda@users.noreply.github.com> Date: Mon, 6 Sep 2021 21:32:19 +0545 Subject: [PATCH] feat(Queue): add createStream method --- src/Structures/Queue.ts | 60 +++++++++++++++++++++++++++-------------- src/Structures/Track.ts | 2 +- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/Structures/Queue.ts b/src/Structures/Queue.ts index 3289d95..0bbb1fe 100644 --- a/src/Structures/Queue.ts +++ b/src/Structures/Queue.ts @@ -2,13 +2,14 @@ import { Collection, Guild, StageChannel, VoiceChannel, Snowflake, SnowflakeUtil import { Player } from "../Player"; import { StreamDispatcher } from "../VoiceInterface/StreamDispatcher"; import Track from "./Track"; -import { PlayerOptions, PlayerProgressbarOptions, PlayOptions, QueueFilters, QueueRepeatMode } from "../types/types"; +import { PlayerOptions, PlayerProgressbarOptions, PlayOptions, QueueFilters, QueueRepeatMode, TrackSource } from "../types/types"; import ytdl from "discord-ytdl-core"; import { AudioResource, StreamType } from "@discordjs/voice"; import { Util } from "../utils/Util"; import YouTube from "youtube-sr"; import AudioFilters from "../utils/AudioFilters"; import { PlayerError, ErrorStatusCode } from "./PlayerError"; +import type { Readable } from "stream"; class Queue { public readonly guild: Guild; @@ -27,6 +28,7 @@ class Queue { private _filtersUpdate = false; #lastVolume = 0; #destroyed = false; + public createStream: (track: Track, source: TrackSource) => Promise | Readable = null; /** * Queue constructor @@ -630,8 +632,9 @@ class Queue { this.previousTracks.push(track); } - // TODO: remove discord-ytdl-core - let stream; + let stream = null; + const customDownloader = typeof this.createStream === "function"; + if (["youtube", "spotify"].includes(track.raw.source)) { if (track.raw.source === "spotify" && !track.raw.engine) { track.raw.engine = await YouTube.search(`${track.author} ${track.title}`, { type: "video" }) @@ -641,27 +644,44 @@ class Queue { const link = track.raw.source === "spotify" ? track.raw.engine : track.url; if (!link) return void this.play(this.tracks.shift(), { immediate: true }); - stream = ytdl(link, { - ...this.options.ytdlOptions, - // discord-ytdl-core - opusEncoded: false, - fmt: "s16le", - encoderArgs: options.encoderArgs ?? this._activeFilters.length ? ["-af", AudioFilters.create(this._activeFilters)] : [], - seek: options.seek ? options.seek / 1000 : 0 - }).on("error", (err) => { - return err.message.toLowerCase().includes("premature close") ? null : this.player.emit("error", this, err); - }); - } else { - stream = ytdl - .arbitraryStream( - track.raw.source === "soundcloud" ? await track.raw.engine.downloadProgressive() : typeof track.raw.engine === "function" ? await track.raw.engine() : track.raw.engine, - { + if (customDownloader) { + stream = ytdl + .arbitraryStream(await this.createStream(track, link), { opusEncoded: false, fmt: "s16le", encoderArgs: options.encoderArgs ?? this._activeFilters.length ? ["-af", AudioFilters.create(this._activeFilters)] : [], seek: options.seek ? options.seek / 1000 : 0 - } - ) + }) + .on("error", (err) => { + return err.message.toLowerCase().includes("premature close") ? null : this.player.emit("error", this, err); + }); + } else { + stream = ytdl(link, { + ...this.options.ytdlOptions, + // discord-ytdl-core + opusEncoded: false, + fmt: "s16le", + encoderArgs: options.encoderArgs ?? this._activeFilters.length ? ["-af", AudioFilters.create(this._activeFilters)] : [], + seek: options.seek ? options.seek / 1000 : 0 + }).on("error", (err) => { + return err.message.toLowerCase().includes("premature close") ? null : this.player.emit("error", this, err); + }); + } + } else { + const arbitrarySource = customDownloader + ? await this.createStream(track, track.raw.source || track.raw.engine) + : track.raw.source === "soundcloud" + ? await track.raw.engine.downloadProgressive() + : typeof track.raw.engine === "function" + ? await track.raw.engine() + : track.raw.engine; + stream = ytdl + .arbitraryStream(arbitrarySource, { + opusEncoded: false, + fmt: "s16le", + encoderArgs: options.encoderArgs ?? this._activeFilters.length ? ["-af", AudioFilters.create(this._activeFilters)] : [], + seek: options.seek ? options.seek / 1000 : 0 + }) .on("error", (err) => { return err.message.toLowerCase().includes("premature close") ? null : this.player.emit("error", this, err); }); diff --git a/src/Structures/Track.ts b/src/Structures/Track.ts index 7504e55..00165f6 100644 --- a/src/Structures/Track.ts +++ b/src/Structures/Track.ts @@ -121,7 +121,7 @@ class Track { * @type {Queue} */ get queue(): Queue { - return this.player.queues.find((q) => q.tracks.includes(this)); + return this.player.queues.find((q) => q.tracks.some((ab) => ab.id === this.id)); } /**