feat(Queue): add createStream method

This commit is contained in:
DevAndromeda 2021-09-06 21:32:19 +05:45
parent 1c9a00bf1a
commit 38c0e209a0
No known key found for this signature in database
GPG key ID: FA40E3EC5CB6DCD6
2 changed files with 41 additions and 21 deletions

View file

@ -2,13 +2,14 @@ import { Collection, Guild, StageChannel, VoiceChannel, Snowflake, SnowflakeUtil
import { Player } from "../Player"; import { Player } from "../Player";
import { StreamDispatcher } from "../VoiceInterface/StreamDispatcher"; import { StreamDispatcher } from "../VoiceInterface/StreamDispatcher";
import Track from "./Track"; 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 ytdl from "discord-ytdl-core";
import { AudioResource, StreamType } from "@discordjs/voice"; import { AudioResource, StreamType } from "@discordjs/voice";
import { Util } from "../utils/Util"; import { Util } from "../utils/Util";
import YouTube from "youtube-sr"; import YouTube from "youtube-sr";
import AudioFilters from "../utils/AudioFilters"; import AudioFilters from "../utils/AudioFilters";
import { PlayerError, ErrorStatusCode } from "./PlayerError"; import { PlayerError, ErrorStatusCode } from "./PlayerError";
import type { Readable } from "stream";
class Queue<T = unknown> { class Queue<T = unknown> {
public readonly guild: Guild; public readonly guild: Guild;
@ -27,6 +28,7 @@ class Queue<T = unknown> {
private _filtersUpdate = false; private _filtersUpdate = false;
#lastVolume = 0; #lastVolume = 0;
#destroyed = false; #destroyed = false;
public createStream: (track: Track, source: TrackSource) => Promise<Readable> | Readable = null;
/** /**
* Queue constructor * Queue constructor
@ -630,8 +632,9 @@ class Queue<T = unknown> {
this.previousTracks.push(track); this.previousTracks.push(track);
} }
// TODO: remove discord-ytdl-core let stream = null;
let stream; const customDownloader = typeof this.createStream === "function";
if (["youtube", "spotify"].includes(track.raw.source)) { if (["youtube", "spotify"].includes(track.raw.source)) {
if (track.raw.source === "spotify" && !track.raw.engine) { if (track.raw.source === "spotify" && !track.raw.engine) {
track.raw.engine = await YouTube.search(`${track.author} ${track.title}`, { type: "video" }) track.raw.engine = await YouTube.search(`${track.author} ${track.title}`, { type: "video" })
@ -641,6 +644,18 @@ class Queue<T = unknown> {
const link = track.raw.source === "spotify" ? track.raw.engine : track.url; const link = track.raw.source === "spotify" ? track.raw.engine : track.url;
if (!link) return void this.play(this.tracks.shift(), { immediate: true }); if (!link) return void this.play(this.tracks.shift(), { immediate: true });
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, { stream = ytdl(link, {
...this.options.ytdlOptions, ...this.options.ytdlOptions,
// discord-ytdl-core // discord-ytdl-core
@ -651,17 +666,22 @@ class Queue<T = unknown> {
}).on("error", (err) => { }).on("error", (err) => {
return err.message.toLowerCase().includes("premature close") ? null : this.player.emit("error", this, err); return err.message.toLowerCase().includes("premature close") ? null : this.player.emit("error", this, err);
}); });
}
} else { } 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 stream = ytdl
.arbitraryStream( .arbitraryStream(arbitrarySource, {
track.raw.source === "soundcloud" ? await track.raw.engine.downloadProgressive() : typeof track.raw.engine === "function" ? await track.raw.engine() : track.raw.engine,
{
opusEncoded: false, opusEncoded: false,
fmt: "s16le", fmt: "s16le",
encoderArgs: options.encoderArgs ?? this._activeFilters.length ? ["-af", AudioFilters.create(this._activeFilters)] : [], encoderArgs: options.encoderArgs ?? this._activeFilters.length ? ["-af", AudioFilters.create(this._activeFilters)] : [],
seek: options.seek ? options.seek / 1000 : 0 seek: options.seek ? options.seek / 1000 : 0
} })
)
.on("error", (err) => { .on("error", (err) => {
return err.message.toLowerCase().includes("premature close") ? null : this.player.emit("error", this, err); return err.message.toLowerCase().includes("premature close") ? null : this.player.emit("error", this, err);
}); });

View file

@ -121,7 +121,7 @@ class Track {
* @type {Queue} * @type {Queue}
*/ */
get queue(): 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));
} }
/** /**