From 744fabdb6f0105dda4991d8fb5f327b835db5371 Mon Sep 17 00:00:00 2001 From: Lars Rickert Date: Mon, 23 May 2022 15:54:06 +0200 Subject: [PATCH] feat: support spotify playlists --- src/engines/index.ts | 14 ++++++++++++-- src/engines/spotify.ts | 29 ++++++++++++++++++++++++++--- src/index.ts | 1 + src/player.ts | 2 +- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/engines/index.ts b/src/engines/index.ts index c854491..d60efe7 100644 --- a/src/engines/index.ts +++ b/src/engines/index.ts @@ -1,3 +1,4 @@ +import { stat } from "fs/promises"; import { PlayerEngine, TrackSource } from "../types/engines"; import { fileEngine } from "./file"; import { spotifyEngine } from "./spotify"; @@ -12,8 +13,17 @@ export const playerEngines: Record = { /** * Automatically detect the query type */ -export function detectTrackSource(query: string): TrackSource { - if (!query.startsWith("https://")) return "file"; +export async function detectTrackSource(query: string): Promise { if (query.startsWith("https://open.spotify.com/")) return "spotify"; + if (query.startsWith("https://www.youtube.com/")) return "youtube"; + + // check if query is file path + try { + const stats = await stat(query); + if (stats.isFile()) return "file"; + } catch (e) { + // noop + } + return "youtube"; } diff --git a/src/engines/spotify.ts b/src/engines/spotify.ts index 9d8d121..f6ea8e3 100644 --- a/src/engines/spotify.ts +++ b/src/engines/spotify.ts @@ -1,5 +1,5 @@ -import { getTracks, Tracks } from "spotify-url-info"; -import { PlayerEngine, Track } from "../types/engines"; +import { getData, getTracks, Tracks } from "spotify-url-info"; +import { PlayerEngine, SearchResult, Track } from "../types/engines"; import { youtubeEngine } from "./youtube"; /** @@ -8,7 +8,9 @@ import { youtubeEngine } from "./youtube"; */ export const spotifyEngine: PlayerEngine = { search: async (query, options) => { - // TODO: check how to get playlist info + const isPlaylist = query.startsWith("https://open.spotify.com/playlist"); + if (isPlaylist) return await searchPlaylist(query); + const tracks = await getTracks(query); return [ @@ -31,6 +33,27 @@ export const spotifyEngine: PlayerEngine = { }, }; +async function searchPlaylist(query: string): Promise { + const data = await getData(query); + if (data?.type !== "playlist") return []; + + console.log(data.tracks.items); + + return [ + { + tracks: data.tracks.items.map((i: { track: Tracks }) => + mapSpotifyTrack(i.track) + ), + playlist: { + title: data.name, + url: data.external_urls.spotify, + thumbnailUrl: data.images.length ? data.images[0].url : undefined, + }, + source: "spotify", + }, + ]; +} + function mapSpotifyTrack(track: Tracks): Track { return { title: track.name, diff --git a/src/index.ts b/src/index.ts index 12e9e2d..dedc1f1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ +export { detectTrackSource } from "./engines"; export * from "./player"; export * from "./player-manager"; export * from "./types/engines"; diff --git a/src/player.ts b/src/player.ts index 80cf101..c946607 100644 --- a/src/player.ts +++ b/src/player.ts @@ -284,7 +284,7 @@ export class Player extends TypedEmitter { if (customResult) return customResult; } - const trackSource = detectTrackSource(query); + const trackSource = await detectTrackSource(query); const playerEngine = playerEngines[trackSource]; return await playerEngine.search(query, options); }