spotify track support
This commit is contained in:
parent
2e75728d11
commit
11de5d8038
2 changed files with 43 additions and 9 deletions
|
@ -7,6 +7,7 @@ import Track from "./Structures/Track";
|
||||||
import { QueryResolver } from "./utils/QueryResolver";
|
import { QueryResolver } from "./utils/QueryResolver";
|
||||||
import YouTube from "youtube-sr";
|
import YouTube from "youtube-sr";
|
||||||
import { Util } from "./utils/Util";
|
import { Util } from "./utils/Util";
|
||||||
|
import Spotify from "spotify-url-info";
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { Client as SoundCloud } from "soundcloud-scraper";
|
import { Client as SoundCloud } from "soundcloud-scraper";
|
||||||
|
|
||||||
|
@ -138,6 +139,27 @@ class DiscordPlayer extends EventEmitter<PlayerEvents> {
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
case QueryType.SPOTIFY_SONG: {
|
||||||
|
const spotifyData = await Spotify.getData(query).catch(() => {});
|
||||||
|
if (!spotifyData) return [];
|
||||||
|
const spotifyTrack = new Track(this, {
|
||||||
|
title: spotifyData.name,
|
||||||
|
description: spotifyData.description ?? "",
|
||||||
|
author: spotifyData.artists[0]?.name ?? "Unknown Artist",
|
||||||
|
url: spotifyData.external_urls?.spotify ?? query,
|
||||||
|
thumbnail:
|
||||||
|
spotifyData.album?.images[0]?.url ?? spotifyData.preview_url?.length
|
||||||
|
? `https://i.scdn.co/image/${spotifyData.preview_url?.split("?cid=")[1]}`
|
||||||
|
: "https://www.scdn.co/i/_global/twitter_card-default.jpg",
|
||||||
|
duration: Util.buildTimeCode(Util.parseMS(spotifyData.duration_ms)),
|
||||||
|
views: 0,
|
||||||
|
requestedBy: options.requestedBy,
|
||||||
|
fromPlaylist: false,
|
||||||
|
source: "spotify"
|
||||||
|
});
|
||||||
|
|
||||||
|
return [spotifyTrack];
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { PlayerOptions, PlayOptions, QueueRepeatMode } 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";
|
||||||
|
|
||||||
class Queue<T = unknown> {
|
class Queue<T = unknown> {
|
||||||
public readonly guild: Guild;
|
public readonly guild: Guild;
|
||||||
|
@ -119,7 +120,7 @@ class Queue<T = unknown> {
|
||||||
return await this.play(Util.last(this.previousTracks), { immediate: true });
|
return await this.play(Util.last(this.previousTracks), { immediate: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
async play(src?: Track, options: PlayOptions = {}) {
|
async play(src?: Track, options: PlayOptions = {}): Promise<void> {
|
||||||
if (!this.connection || !this.connection.voiceConnection) throw new Error("Voice connection is not available, use <Queue>.connect()!");
|
if (!this.connection || !this.connection.voiceConnection) throw new Error("Voice connection is not available, use <Queue>.connect()!");
|
||||||
if (src && (this.playing || this.tracks.length) && !options.immediate) return this.addTrack(src);
|
if (src && (this.playing || this.tracks.length) && !options.immediate) return this.addTrack(src);
|
||||||
const track = options.filtersUpdate ? this.current : src ?? this.tracks.shift();
|
const track = options.filtersUpdate ? this.current : src ?? this.tracks.shift();
|
||||||
|
@ -128,7 +129,15 @@ class Queue<T = unknown> {
|
||||||
this.previousTracks.push(track);
|
this.previousTracks.push(track);
|
||||||
let stream;
|
let stream;
|
||||||
if (["youtube", "spotify"].includes(track.raw.source)) {
|
if (["youtube", "spotify"].includes(track.raw.source)) {
|
||||||
stream = ytdl(track.raw.source === "spotify" ? track.raw.engine : track.url, {
|
if (track.raw.source === "spotify" && !track.raw.engine) {
|
||||||
|
track.raw.engine = await YouTube.search(`${track.author} ${track.title}`, { type: "video" })
|
||||||
|
.then((x) => x[0].url)
|
||||||
|
.catch(() => null);
|
||||||
|
}
|
||||||
|
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, {
|
||||||
// because we don't wanna decode opus into pcm again just for volume, let discord.js handle that
|
// because we don't wanna decode opus into pcm again just for volume, let discord.js handle that
|
||||||
opusEncoded: false,
|
opusEncoded: false,
|
||||||
fmt: "s16le",
|
fmt: "s16le",
|
||||||
|
@ -136,13 +145,16 @@ class Queue<T = unknown> {
|
||||||
seek: options.seek
|
seek: options.seek
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
stream = ytdl.arbitraryStream(track.raw.source === "soundcloud" ? await track.raw.engine.downloadProgressive() : (track.raw.engine as string), {
|
stream = ytdl.arbitraryStream(
|
||||||
// because we don't wanna decode opus into pcm again just for volume, let discord.js handle that
|
track.raw.source === "soundcloud" ? await track.raw.engine.downloadProgressive() : typeof track.raw.engine === "function" ? await track.raw.engine() : track.raw.engine,
|
||||||
opusEncoded: false,
|
{
|
||||||
fmt: "s16le",
|
// because we don't wanna decode opus into pcm again just for volume, let discord.js handle that
|
||||||
encoderArgs: options.encoderArgs ?? [],
|
opusEncoded: false,
|
||||||
seek: options.seek
|
fmt: "s16le",
|
||||||
});
|
encoderArgs: options.encoderArgs ?? [],
|
||||||
|
seek: options.seek
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const resource: AudioResource<Track> = this.connection.createStream(stream, {
|
const resource: AudioResource<Track> = this.connection.createStream(stream, {
|
||||||
|
|
Loading…
Reference in a new issue