diff --git a/.gitignore b/.gitignore index e8e1662..ce3a6ea 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ yarn*.log # example example/test example/music-bot/node_modules -example/music-bot/package-lock.json \ No newline at end of file +example/music-bot/package-lock.json +example/music-bot/.env \ No newline at end of file diff --git a/example/music-bot/config.js b/example/music-bot/config.js index e9ad43e..50f225e 100644 --- a/example/music-bot/config.js +++ b/example/music-bot/config.js @@ -1,3 +1,3 @@ module.exports = { - token: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + token: process.env.DISCORD_TOKEN }; diff --git a/example/music-bot/index.js b/example/music-bot/index.js index 5a85701..ce15ada 100644 --- a/example/music-bot/index.js +++ b/example/music-bot/index.js @@ -1,7 +1,7 @@ +require("dotenv").config(); const { Client, GuildMember } = require("discord.js"); const config = require("./config"); const { Player, QueryType, QueueRepeatMode } = require("discord-player"); - const client = new Client({ intents: ["GUILD_VOICE_STATES", "GUILD_MESSAGES", "GUILDS"] }); diff --git a/example/music-bot/package.json b/example/music-bot/package.json index 8eab638..76141e0 100644 --- a/example/music-bot/package.json +++ b/example/music-bot/package.json @@ -10,7 +10,8 @@ "license": "MIT", "dependencies": { "@discordjs/opus": "^0.5.3", - "discord-player": "^5.0.0-dev.39f503a.1625470163", - "discord.js": "^13.0.1" + "discord-player": "^5.0.0", + "discord.js": "^13.0.1", + "dotenv": "^10.0.0" } } diff --git a/package.json b/package.json index b50dc0d..d6e59cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "discord-player", - "version": "5.0.0", + "version": "5.0.1", "description": "Complete framework to facilitate music commands using discord.js", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -26,7 +26,7 @@ }, "funding": "https://github.com/Androz2091/discord-player?sponsor=1", "contributors": [ - "Snowflake107" + "DevAndromeda " ], "repository": { "type": "git", diff --git a/src/Player.ts b/src/Player.ts index a635613..1058b8c 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -9,6 +9,7 @@ import YouTube from "youtube-sr"; import { Util } from "./utils/Util"; import Spotify from "spotify-url-info"; import { PlayerError, ErrorStatusCode } from "./Structures/PlayerError"; +import { getInfo as ytdlGetInfo } from "ytdl-core"; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore import { Client as SoundCloud } from "soundcloud-scraper"; @@ -220,6 +221,25 @@ class Player extends EventEmitter { const qt = options.searchEngine === QueryType.AUTO ? QueryResolver.resolve(query) : options.searchEngine; switch (qt) { + case QueryType.YOUTUBE_VIDEO: { + const info = await ytdlGetInfo(query).catch(Util.noop); + if (!info) return { playlist: null, tracks: [] }; + + const track = new Track(this, { + title: info.videoDetails.title, + description: info.videoDetails.description, + author: info.videoDetails.author?.name, + url: info.videoDetails.video_url, + requestedBy: options.requestedBy as User, + thumbnail: Util.last(info.videoDetails.thumbnails)?.url, + views: parseInt(info.videoDetails.viewCount.replace(/[^0-9]/g, "")) || 0, + duration: Util.buildTimeCode(Util.parseMS(parseInt(info.videoDetails.lengthSeconds) * 1000)), + source: "youtube", + raw: info + }); + + return { playlist: null, tracks: [track] }; + } case QueryType.YOUTUBE_SEARCH: { const videos = await YouTube.search(query, { type: "video" @@ -237,6 +257,7 @@ class Player extends EventEmitter { thumbnail: m.thumbnail?.displayThumbnailURL("maxresdefault"), views: m.views, duration: m.durationFormatted, + source: "youtube", raw: m }); }); diff --git a/src/index.ts b/src/index.ts index 49e9ed9..0e7198f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,10 @@ export { PlayerError, ErrorStatusCode } from "./Structures/PlayerError"; export { QueryResolver } from "./utils/QueryResolver"; export { Queue } from "./Structures/Queue"; export { Track } from "./Structures/Track"; -export { Util } from "./utils/Util"; export { VoiceUtils } from "./VoiceInterface/VoiceUtils"; export { VoiceEvents, StreamDispatcher } from "./VoiceInterface/StreamDispatcher"; +export { Util } from "./utils/Util"; export * from "./types/types"; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +export const version: string = require(`${__dirname}/../package.json`).version; diff --git a/src/types/types.ts b/src/types/types.ts index 8a21666..e04f76c 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -216,6 +216,7 @@ export interface ExtractorModelData { * - ARBITRARY * - REVERBNATION * - YOUTUBE_SEARCH + * - YOUTUBE_VIDEO * - SOUNDCLOUD_SEARCH * @typedef {string} QueryType */ @@ -234,6 +235,7 @@ export enum QueryType { ARBITRARY = "arbitrary", REVERBNATION = "reverbnation", YOUTUBE_SEARCH = "youtube_search", + YOUTUBE_VIDEO = "youtube_video", SOUNDCLOUD_SEARCH = "soundcloud_search" } diff --git a/src/utils/QueryResolver.ts b/src/utils/QueryResolver.ts index d39e808..ec1f3ef 100644 --- a/src/utils/QueryResolver.ts +++ b/src/utils/QueryResolver.ts @@ -31,7 +31,7 @@ class QueryResolver { if (SoundcloudValidateURL(query, "track")) return QueryType.SOUNDCLOUD_TRACK; if (SoundcloudValidateURL(query, "playlist") || query.includes("/sets/")) return QueryType.SOUNDCLOUD_PLAYLIST; if (YouTube.isPlaylist(query)) return QueryType.YOUTUBE_PLAYLIST; - if (validateID(query) || validateURL(query)) return QueryType.YOUTUBE_SEARCH; + if (validateID(query) || validateURL(query)) return QueryType.YOUTUBE_VIDEO; if (spotifySongRegex.test(query)) return QueryType.SPOTIFY_SONG; if (spotifyPlaylistRegex.test(query)) return QueryType.SPOTIFY_PLAYLIST; if (spotifyAlbumRegex.test(query)) return QueryType.SPOTIFY_ALBUM;