diff --git a/src/streamers/spotify/main.ts b/src/streamers/spotify/main.ts index d9cd8a0..ea69db1 100644 --- a/src/streamers/spotify/main.ts +++ b/src/streamers/spotify/main.ts @@ -1,5 +1,12 @@ import Librespot, { LibrespotOptions } from 'librespot' -import { parseArtist, parseAlbum, parseTrack, parseEpisode, parsePodcast } from './parse.js' +import { + parseArtist, + parseAlbum, + parseTrack, + parseEpisode, + parsePodcast, + parsePlaylist +} from './parse.js' import { GetByUrlResponse, ItemType, @@ -41,7 +48,9 @@ class Spotify implements StreamerWithLogin { if (this.storedCredential) return await this.client.loginWithStoredCreds(username, password) else return await this.client.login(username, password) } - #getUrlParts(url: string): ['artist' | 'album' | 'track' | 'episode' | 'show', string] { + #getUrlParts( + url: string + ): ['artist' | 'album' | 'track' | 'episode' | 'show' | 'playlist', string] { const urlObj = new URL(url) const parts = urlObj.pathname.slice(1).split('/') if (parts.length > 2) throw new Error('Unknown Spotify URL') @@ -50,7 +59,8 @@ class Spotify implements StreamerWithLogin { parts[0] != 'track' && parts[0] != 'album' && parts[0] != 'show' && - parts[0] != 'episode' + parts[0] != 'episode' && + parts[0] != 'playlist' ) { throw new Error(`Spotify type "${parts[0]}" unsupported`) } @@ -132,6 +142,14 @@ class Spotify implements StreamerWithLogin { episodes: metadata.episodes?.map((e) => parseEpisode(e)) ?? [] } } + case 'playlist': { + const metadata = await this.client.get.playlist(id) + return { + type: 'playlist', + metadata: parsePlaylist(metadata), + tracks: metadata.tracks?.map((e) => parseTrack(e)) ?? [] + } + } } } async search(query: string): Promise { diff --git a/src/streamers/spotify/parse.ts b/src/streamers/spotify/parse.ts index f1ab7b0..421ce40 100644 --- a/src/streamers/spotify/parse.ts +++ b/src/streamers/spotify/parse.ts @@ -4,9 +4,10 @@ import type { SpotifyThumbnail, SpotifyTrack, SpotifyEpisode, - SpotifyPodcast + SpotifyPodcast, + SpotifyPlaylist } from 'librespot/types' -import { Album, Artist, Episode, Podcast, Track } from '../../types.js' +import { Album, Artist, Episode, Playlist, Podcast, Track } from '../../types.js' function parseThumbnails(raw: SpotifyThumbnail[]) { return raw @@ -92,3 +93,14 @@ export function parsePodcast(raw: SpotifyPodcast) { return podcast } + +export function parsePlaylist(raw: SpotifyPlaylist) { + const playlist: Playlist = { + id: raw.id, + title: raw.name, + url: raw.externalUrl, + trackCount: raw.totalTracks + } + + return playlist +} diff --git a/src/streamers/tidal/parse.ts b/src/streamers/tidal/parse.ts index fc94d26..73b40d9 100644 --- a/src/streamers/tidal/parse.ts +++ b/src/streamers/tidal/parse.ts @@ -97,8 +97,7 @@ export function parsePlaylist(raw: RawPlaylist): Playlist { id: raw.uuid, title: raw.title, url: raw.url, - trackCount: raw.numberOfTracks, - tracks: [] + trackCount: raw.numberOfTracks } playlist.coverArtwork = [ diff --git a/src/types.ts b/src/types.ts index 254fce9..b694ee4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -36,7 +36,6 @@ export interface Playlist { url: string coverArtwork?: CoverArtwork[] trackCount?: number - tracks: Track[] } export interface Album {