From 5781499aeb44c37c14f2281a7340a403b23b977d Mon Sep 17 00:00:00 2001 From: "sweep-ai[bot]" <128439645+sweep-ai[bot]@users.noreply.github.com> Date: Sat, 12 Aug 2023 21:09:18 +0300 Subject: [PATCH] Add support for playing Spotify URLs by searching same song on YouTube (#30) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: sweep-ai[bot] <128439645+sweep-ai[bot]@users.noreply.github.com> Co-authored-by: Lassi Säike --- package-lock.json | 52 ++++++++++++++++++++++ package.json | 6 ++- src_modules/player/commands/PlayCommand.ts | 33 +++++++++++++- src_modules/player/index.ts | 2 +- 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index af70c6f..4125839 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,6 +51,8 @@ "mocha": "^9.2.1", "opusscript": "^0.0.8", "rimraf": "^3.0.2", + "spotify-uri": "^4.0.0", + "spotify-url-info": "^3.2.6", "ts-node": "^10.5.0", "tslint": "^6.1.3", "typedoc": "^0.22.11", @@ -1682,6 +1684,12 @@ "node": "*" } }, + "node_modules/himalaya": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/himalaya/-/himalaya-1.1.0.tgz", + "integrity": "sha512-LLase1dHCRMel68/HZTFft0N0wti0epHr3nNY7ynpLbyZpmrKMQ8YIpiOV77TM97cNpC8Wb2n6f66IRggwdWPw==", + "dev": true + }, "node_modules/hjson": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/hjson/-/hjson-3.2.2.tgz", @@ -3038,6 +3046,28 @@ "node-gyp-build": "^4.3.0" } }, + "node_modules/spotify-uri": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spotify-uri/-/spotify-uri-4.0.0.tgz", + "integrity": "sha512-ZAJKcnfx73glWG+3SCDRvW4nkVMzA2hqZwJtSDZ/o87EoGawh/CZ8YkqZIoVcLkg94suicEa/ZOiBFSz1MJ6Pg==", + "dev": true, + "engines": { + "node": ">= 16" + } + }, + "node_modules/spotify-url-info": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/spotify-url-info/-/spotify-url-info-3.2.6.tgz", + "integrity": "sha512-AOGU4uyT0FqyEXbyvZc+ZShnTGBY1eMd50BBZBPfiXPT4ihuzmxAmkWj9VzHT9NIjX7MtVDrszATllR8+WeFkw==", + "dev": true, + "dependencies": { + "himalaya": "~1.1.0", + "spotify-uri": "~4.0.0" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -5323,6 +5353,12 @@ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" }, + "himalaya": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/himalaya/-/himalaya-1.1.0.tgz", + "integrity": "sha512-LLase1dHCRMel68/HZTFft0N0wti0epHr3nNY7ynpLbyZpmrKMQ8YIpiOV77TM97cNpC8Wb2n6f66IRggwdWPw==", + "dev": true + }, "hjson": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/hjson/-/hjson-3.2.2.tgz", @@ -6349,6 +6385,22 @@ "node-gyp-build": "^4.3.0" } }, + "spotify-uri": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spotify-uri/-/spotify-uri-4.0.0.tgz", + "integrity": "sha512-ZAJKcnfx73glWG+3SCDRvW4nkVMzA2hqZwJtSDZ/o87EoGawh/CZ8YkqZIoVcLkg94suicEa/ZOiBFSz1MJ6Pg==", + "dev": true + }, + "spotify-url-info": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/spotify-url-info/-/spotify-url-info-3.2.6.tgz", + "integrity": "sha512-AOGU4uyT0FqyEXbyvZc+ZShnTGBY1eMd50BBZBPfiXPT4ihuzmxAmkWj9VzHT9NIjX7MtVDrszATllR8+WeFkw==", + "dev": true, + "requires": { + "himalaya": "~1.1.0", + "spotify-uri": "~4.0.0" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", diff --git a/package.json b/package.json index c34a55f..50f9069 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,8 @@ "ts-node": "^10.5.0", "tslint": "^6.1.3", "typedoc": "^0.22.11", - "typescript": "^4.5.5" + "typescript": "^4.5.5", + "spotify-uri": "^4.0.0", + "spotify-url-info": "^3.2.6" } -} +} \ No newline at end of file diff --git a/src_modules/player/commands/PlayCommand.ts b/src_modules/player/commands/PlayCommand.ts index ee5ae6a..6dc0a02 100644 --- a/src_modules/player/commands/PlayCommand.ts +++ b/src_modules/player/commands/PlayCommand.ts @@ -11,6 +11,8 @@ import ytpl = require("@distube/ytpl"); import ytsr = require("@distube/ytsr"); import fetch from "node-fetch"; import { Readable } from "stream"; +import * as spotifyUri from 'spotify-uri'; +const { getPreview } = require('spotify-url-info')(fetch); export class PlayCommand extends Command<[StringArgument]> { private player: PlayerModule; @@ -90,6 +92,12 @@ export class PlayCommand extends Command<[StringArgument]> { return; } return [item]; + } else if (this.isSpotifyUrl(query)) { + const item = await this.getQueueItemFromSpotifyUrl(query, context); + if (!item) { + return context.respond(musicNotFoundPhrase, { search: query }); + } + return [item]; } else { const item = await this.getQueueItemFromDirectUrl(query); if (!item) { @@ -99,6 +107,16 @@ export class PlayCommand extends Command<[StringArgument]> { } } + private isSpotifyUrl(url: string): boolean { + try { + spotifyUri.parse(url); + + return true; + } catch { + return false; + } + } + private async searchYoutube(query: string, context: ICommandContext): Promise { const respondPromise = context.respond(musicSearchingPhrase, { search: query }); let searchResult: ytsr.VideoResult; @@ -192,6 +210,19 @@ export class PlayCommand extends Command<[StringArgument]> { return new PlayerQueueItem(itemDetails, ytdlResult); } + private async getQueueItemFromSpotifyUrl(url: string, context: ICommandContext): Promise { + try { + const parsed = spotifyUri.parse(url); + const openUrl = spotifyUri.formatOpenURL(parsed); + + const data = await getPreview(openUrl); + + return this.searchYoutube(`${data.artist} - ${data.title}`, context); + } catch { + return undefined; + } + } + private async getQueueItemFromDirectUrl(url: string): Promise { let itemDetails: IQueueItemDetails; const urlObj = new URL(url); @@ -226,4 +257,4 @@ export class PlayCommand extends Command<[StringArgument]> { }; return new PlayerQueueItem(itemDetails); } -} +} \ No newline at end of file diff --git a/src_modules/player/index.ts b/src_modules/player/index.ts index 47093a2..54cb624 100644 --- a/src_modules/player/index.ts +++ b/src_modules/player/index.ts @@ -1,5 +1,5 @@ // extcord module -// requires ffmpeg-static@^5.1.0 @distube/ytdl-core@^4.11.17 @distube/ytsr@^1.1.9 @distube/ytpl@^1.1.1 +// requires ffmpeg-static@^5.1.0 @distube/ytdl-core@^4.11.17 @distube/ytsr@^1.1.9 @distube/ytpl@^1.1.1 spotify-uri@^4.0.0 spotify-url-info@^3.2.6 import { AudioPlayerStatus, createAudioPlayer,