UNPKG

distube-apple-music

Version:

A DisTube info extractor plugin for supporting Apple Music.

1 lines 20 kB
{"version":3,"sources":["../src/API.ts","../src/index.ts"],"sourcesContent":["import fetch from \"isomorphic-unfetch\";\nimport { parse } from \"node-html-parser\";\nimport type { HTMLElement } from \"node-html-parser\";\n\nfunction getHTML(link: string): Promise<HTMLElement | null> {\n return fetch(link, {\n headers: {\n \"User-Agent\":\n // eslint-disable-next-line max-len\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.49\",\n },\n })\n .then(r => r.text())\n .then(\n txt => parse(txt),\n () => null,\n );\n}\n\nfunction makeImage({ height, url, width, ext = \"jpg\" }: { url: string; width: number; height: number; ext?: string }) {\n return url.replace(\"{w}\", `${width}`).replace(\"{h}\", `${height}`).replace(\"{f}\", ext);\n}\n\nexport class AppleMusic {\n public constructor() {\n return AppleMusic;\n }\n\n public static async search(query: string) {\n try {\n const url = `https://music.apple.com/us/search?term=${encodeURIComponent(query)}`;\n const node = await getHTML(url);\n if (!node) return [];\n\n const rawData = node.getElementById(\"serialized-server-data\");\n if (!rawData) return [];\n\n const data = JSON.parse(rawData.innerText)[0].data.sections;\n const tracks = data.find((s: any) => s.itemKind === \"trackLockup\")?.items;\n if (!tracks) return [];\n\n return tracks.map((track: any) => ({\n id: track.contentDescriptor.identifiers.storeAdamID,\n duration: track.duration || \"0:00\",\n title: track.title,\n url: track.contentDescriptor.url,\n thumbnail: track?.artwork?.dictionary\n ? makeImage({\n url: track.artwork.dictionary.url,\n height: track.artwork.dictionary.height,\n width: track.artwork.dictionary.width,\n })\n : \"https://music.apple.com/assets/favicon/favicon-180.png\",\n artist: {\n name: track.subtitleLinks?.[0]?.title ?? \"Unknown Artist\",\n },\n type: \"track\",\n }));\n } catch {\n return [];\n }\n }\n\n public static getSongInfoFallback(res: HTMLElement, name: string, id: string, link: string) {\n try {\n const metaTags = res.getElementsByTagName(\"meta\");\n if (!metaTags.length) return null;\n\n const title =\n metaTags.find(r => r.getAttribute(\"name\") === \"apple:title\")?.getAttribute(\"content\") ||\n res.querySelector(\"title\")?.innerText ||\n name;\n const contentId =\n metaTags.find(r => r.getAttribute(\"name\") === \"apple:content_id\")?.getAttribute(\"content\") || id;\n\n const song = {\n id: contentId,\n title,\n url: link,\n thumbnail:\n metaTags\n .find(r => [\"og:image:secure_url\", \"og:image\"].includes(r.getAttribute(\"property\")!))\n ?.getAttribute(\"content\") || \"https://music.apple.com/assets/favicon/favicon-180.png\",\n artist: {\n name: res.querySelector(\".song-subtitles__artists>a\")?.textContent?.trim() || \"Apple Music\",\n },\n type: \"track\",\n };\n\n return song;\n } catch {\n return null;\n }\n }\n\n public static async getSongInfo(link: string) {\n const url = new URL(link);\n const id = url.searchParams.get(\"i\");\n const name = url.pathname.split(\"album/\")[1]?.split(\"/\")[0];\n\n if (!id || !name) return null;\n\n const res = await getHTML(`https://music.apple.com/us/song/${name}/${id}`);\n if (!res) return null;\n\n try {\n const datasrc =\n res.getElementById(\"serialized-server-data\")?.innerText ||\n res.innerText\n .split('<script type=\"application/json\" id=\"serialized-server-data\">')?.[1]\n ?.split(\"</script>\")?.[0];\n if (!datasrc) throw \"not found\";\n const data = JSON.parse(datasrc)[0].data.seoData;\n const song = data.ogSongs[0]?.attributes;\n\n return {\n id: data.ogSongs[0]?.id || data.appleContentId || id,\n title: song?.name || data.appleTitle,\n url: song?.url || data.url || link,\n thumbnail: song?.artwork\n ? makeImage({\n url: song.artwork.url,\n height: song.artwork.height,\n width: song.artwork.width,\n })\n : data.artworkUrl\n ? makeImage({\n height: data.height,\n width: data.width,\n url: data.artworkUrl,\n ext: data.fileType || \"jpg\",\n })\n : \"https://music.apple.com/assets/favicon/favicon-180.png\",\n artist: {\n name: song?.artistName || data.socialTitle || \"Apple Music\",\n },\n type: \"track\",\n };\n } catch {\n return this.getSongInfoFallback(res, name, id, link);\n }\n }\n\n public static async getPlaylistInfo(link: string) {\n const res = await getHTML(link);\n if (!res) return null;\n\n try {\n const datasrc =\n res.getElementById(\"serialized-server-data\")?.innerText ||\n res.innerText\n .split('<script type=\"application/json\" id=\"serialized-server-data\">')?.[1]\n ?.split(\"</script>\")?.[0];\n if (!datasrc) throw \"not found\";\n const pl = JSON.parse(datasrc)[0].data.seoData;\n const thumbnail = pl.artworkUrl\n ? makeImage({\n height: pl.height,\n width: pl.width,\n url: pl.artworkUrl,\n ext: pl.fileType || \"jpg\",\n })\n : \"https://music.apple.com/assets/favicon/favicon-180.png\";\n return {\n id: pl.appleContentId,\n title: pl.appleTitle,\n thumbnail,\n artist: {\n name: pl.ogSongs?.[0]?.attributes?.artistName || \"Apple Music\",\n },\n url: pl.url,\n type: \"playlist\",\n tracks:\n // eslint-disable-next-line\n pl.ogSongs?.map((m: any) => {\n const song = m.attributes;\n return {\n id: m.id,\n title: song.name,\n url: song.url,\n thumbnail: song.artwork\n ? makeImage({\n url: song.artwork.url,\n height: song.artwork.height,\n width: song.artwork.width,\n })\n : thumbnail,\n artist: {\n name: song.artistName || \"Apple Music\",\n },\n type: \"track\",\n };\n }) || [],\n };\n } catch {\n return null;\n }\n }\n\n public static async getAlbumInfo(link: string) {\n const res = await getHTML(link);\n if (!res) return null;\n\n try {\n const datasrc =\n res.getElementById(\"serialized-server-data\")?.innerText ||\n res.innerText\n .split('<script type=\"application/json\" id=\"serialized-server-data\">')?.[1]\n ?.split(\"</script>\")?.[0];\n if (!datasrc) throw \"not found\";\n const pl = JSON.parse(datasrc)[0].data.seoData;\n const thumbnail = pl.artworkUrl\n ? makeImage({\n height: pl.height,\n width: pl.width,\n url: pl.artworkUrl,\n ext: pl.fileType || \"jpg\",\n })\n : \"https://music.apple.com/assets/favicon/favicon-180.png\";\n return {\n id: pl.appleContentId,\n title: pl.appleTitle,\n thumbnail,\n artist: {\n name: pl.ogSongs?.[0]?.attributes?.artistName || \"Apple Music\",\n },\n url: pl.url,\n type: \"album\",\n tracks:\n // eslint-disable-next-line\n pl.ogSongs?.map((m: any) => {\n const song = m.attributes;\n return {\n id: m.id,\n title: song.name,\n url: song.url,\n thumbnail: song.artwork\n ? makeImage({\n url: song.artwork.url,\n height: song.artwork.height,\n width: song.artwork.width,\n })\n : thumbnail,\n artist: {\n name: song.artistName || \"Apple Music\",\n },\n type: \"track\",\n };\n }) || [],\n };\n } catch {\n return null;\n }\n }\n}\n","import { AppleMusic } from \"./API\";\nimport { DisTubeError, InfoExtractorPlugin, Playlist, Song } from \"distube\";\nimport type { ResolveOptions } from \"distube\";\nimport type { ApplePlaylist, AppleSong } from \"./interfaces\";\n\nconst SUPPORTED_TYPES = [\"album\", \"playlist\", \"track\"];\n\nconst SONG_REGEX = /^https?:\\/\\/music\\.apple\\.com\\/.+?\\/(song|album)\\/.+?(\\/.+?\\?i=|\\/)([0-9]+)$/;\nconst PLAYLIST_REGEX = /^https?:\\/\\/music\\.apple\\.com\\/.+?\\/playlist\\/.+\\/pl\\.(u-|pm-)?[a-zA-Z0-9]+$/;\nconst ALBUM_REGEX = /^https?:\\/\\/music\\.apple\\.com\\/.+?\\/album\\/.+\\/([0-9]+)$/;\n\nconst parseURL = (url: string): { type?: string } => {\n let type: string | undefined;\n if (SONG_REGEX.test(url)) {\n type = \"track\";\n } else if (PLAYLIST_REGEX.test(url)) {\n type = \"playlist\";\n } else if (ALBUM_REGEX.test(url)) {\n type = \"album\";\n }\n return { type };\n};\n\nexport class AppleMusicPlugin extends InfoExtractorPlugin {\n validate(url: string) {\n if (typeof url !== \"string\" || !url.includes(\"music.apple.com\")) return false;\n const { type } = parseURL(url);\n if (!type || !SUPPORTED_TYPES.includes(type)) return false;\n return true;\n }\n\n async resolve<T>(url: string, { member, metadata }: ResolveOptions<T>): Promise<Song<T> | Playlist<T>> {\n const { type } = parseURL(url);\n if (!type) throw new DisTubeError(\"APPLE_MUSIC_PLUGIN_INVALID_URL\", `Invalid Apple Music url: ${url}`);\n const data =\n type === \"track\"\n ? await AppleMusic.getSongInfo(url)\n : type === \"album\"\n ? await AppleMusic.getAlbumInfo(url)\n : await AppleMusic.getPlaylistInfo(url);\n if (!data) {\n throw new DisTubeError(\"APPLE_MUSIC_PLUGIN_API_ERROR\", \"Failed to get data from Apple Music API.\");\n }\n if (!data.type || !SUPPORTED_TYPES.includes(data.type)) {\n throw new DisTubeError(\"APPLE_MUSIC_PLUGIN_NOT_SUPPORTED\", \"This applemusic link is not supported.\");\n }\n if (data.type === \"track\") {\n return new Song(\n {\n plugin: this,\n source: \"applemusic\",\n playFromSource: false,\n id: data.id.toString(),\n url: data.url,\n name: data.title,\n uploader: {\n name: data.artist.name,\n url: data.artist.name,\n },\n thumbnail: data.thumbnail,\n },\n { member, metadata },\n );\n }\n return new Playlist(\n {\n source: \"applemusic\",\n url: data.url,\n name: data.title,\n id: data.id.toString(),\n thumbnail: data.thumbnail,\n songs: (data as ApplePlaylist).tracks.map(\n song =>\n new Song(\n {\n plugin: this,\n source: \"applemusic\",\n playFromSource: false,\n url: song.url,\n name: song.title,\n uploader: {\n name: song.artist.name,\n },\n thumbnail: song.thumbnail,\n },\n { member, metadata },\n ),\n ),\n },\n { member, metadata },\n );\n }\n\n createSearchQuery<T>(song: Song<T>) {\n return `${song.name} ${song.uploader.name}`;\n }\n\n async getRelatedSongs(song: Song<undefined>) {\n if (!song || !song.url) {\n throw new DisTubeError(\"APPLE_MUSIC_PLUGIN_INVALID_SONG\", \"Cannot get related songs from invalid song.\");\n }\n const related = await AppleMusic.search(`${song.uploader.name || song.name}`);\n const unique = related.filter((r: AppleSong) => r.url !== song.url);\n return unique.map(\n (t: AppleSong) =>\n new Song(\n {\n plugin: this,\n source: \"applemusic\",\n playFromSource: false,\n url: t.url,\n name: t.title,\n uploader: {\n name: t.artist.name,\n },\n thumbnail: t.thumbnail,\n },\n {},\n ),\n );\n }\n}\n\nexport default AppleMusicPlugin;\n"],"mappings":"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","names":[]}