From 01644b6432fbba57c02772da0e09c182173f43ca Mon Sep 17 00:00:00 2001 From: pan93412 Date: Fri, 11 Aug 2023 22:48:38 +0800 Subject: [PATCH] fix(lyrics-plus/netease): Use PyNCMd API The old xianqiao.wang API seems like removed; therefore, I switch it to PyNCMd, which is actively maintained. --- CustomApps/lyrics-plus/ProviderNetease.js | 80 +++++++++++++++++++---- 1 file changed, 66 insertions(+), 14 deletions(-) diff --git a/CustomApps/lyrics-plus/ProviderNetease.js b/CustomApps/lyrics-plus/ProviderNetease.js index 91c57d8945..57eba37cce 100644 --- a/CustomApps/lyrics-plus/ProviderNetease.js +++ b/CustomApps/lyrics-plus/ProviderNetease.js @@ -1,26 +1,78 @@ -const ProviderNetease = (function () { - const requestHeader = { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0" - }; +/** + * @typedef {{ + * result: { + * songs: { + * name: string, + * id: number, + * dt: number, // duration in ms + * al: { // album + * name: string, + * }, + * }[], + * }, + * }} SearchResponse + * + * @typedef {{ + * title: string, + * artist: string, + * album: string, + * duration: number, + * }} Info + */ - async function findLyrics(info) { - const searchURL = `https://music.xianqiao.wang/neteaseapiv2/search?limit=10&type=1&keywords=`; - const lyricURL = `https://music.xianqiao.wang/neteaseapiv2/lyric?id=`; +const ProviderNetease = (function () { + /** + * Search with PyNCM api. + * + * @param {Info} info + * @throw "Cannot find track" + */ + async function search(info) { + const searchURL = `https://pyncmd.apis.imouto.in/api/pyncm?module=cloudsearch&method=GetSearchResult&keyword=`; const cleanTitle = Utils.removeExtraInfo(Utils.removeSongFeat(Utils.normalize(info.title))); const finalURL = searchURL + encodeURIComponent(`${cleanTitle} ${info.artist}`); - const searchResults = await CosmosAsync.get(finalURL, null, requestHeader); + /** @type {SearchResponse} */ + const searchResults = await Spicetify.CosmosAsync.get(finalURL); const items = searchResults.result.songs; - if (!items?.length) { - throw "Cannot find track"; + + // Find the best match. + for (const song of items) { + const expectedDuration = info.duration; + const actualDuration = song.dt; + + const expectedAlbumName = Utils.normalize(info.album); + const actualAlbumName = Utils.normalize(song.al.name); + + if ( + actualAlbumName == expectedAlbumName || + Math.abs(expectedDuration - actualDuration) < 1000 + ) { + return song; + } } - const album = Utils.capitalize(info.album); - let itemId = items.findIndex(val => Utils.capitalize(val.album.name) === album || Math.abs(info.duration - val.duration) < 1000); - if (itemId === -1) throw "Cannot find track"; + throw "Cannot find track"; + } + + /** + * @param {Info} info + * + * @returns {{ + * lrc: { + * lyric: string, + * klyric: undefined, // unimplemented + * }, + * }} + */ + async function findLyrics(info) { + const lyricURL = `https://pyncmd.apis.imouto.in/api/pyncm?module=track&method=GetTrackLyrics&song_id=`; + + const searchResponse = await search(info); + const songID = searchResponse.id; - return await CosmosAsync.get(lyricURL + items[itemId].id, null, requestHeader); + return CosmosAsync.get(lyricURL + songID); } const creditInfo = [