酷我.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. function kuwo(packages) {
  2. const { axios, he, CookieManager } = packages;
  3. const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  4. const pageSize = 30;
  5. function getRandomCsrf() {
  6. return Array(11).fill(0).map(_ => alphabet[Math.floor(Math.random() * 36)]).join('');
  7. }
  8. async function getHeaders() {
  9. await CookieManager.flush();
  10. const csrfToken = (await CookieManager.get('www.kuwo.cn'))?.kw_token?.value ?? getRandomCsrf();
  11. return {
  12. "user-agent":
  13. "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.63",
  14. accept: "application/json, text/plain, */*",
  15. "accept-encoding": "gzip, deflate, br",
  16. csrf: csrfToken,
  17. cookie: `kw_token=${csrfToken}`,
  18. referer: "http://www.kuwo.cn/",
  19. host: 'www.kuwo.cn',
  20. "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
  21. };
  22. }
  23. function formatMusicItem(_){
  24. return {
  25. id: _.rid,
  26. artwork: _.pic || _.albumpic || _.pic120,
  27. title: he.decode(_.name || ''),
  28. artist: he.decode(_.artist || ''),
  29. album: he.decode(_.album || '')
  30. }
  31. }
  32. function formatAlbumItem(_) {
  33. return {
  34. id: _.albumid,
  35. artist: he.decode(_.artist || ''),
  36. title: he.decode(_.album || ''),
  37. artwork: _.pic,
  38. description: he.decode(_.albuminfo || ''),
  39. date: _.releaseDate,
  40. }
  41. }
  42. async function searchMusic(query, page) {
  43. const headers = await getHeaders();
  44. const res = (await axios({
  45. method: 'get',
  46. url: `http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key=${query}&pn=${page}&rn=${pageSize}&httpStatus=1`,
  47. headers,
  48. }));
  49. const songs = res.data.data.list.filter(_ => !_.isListenFee).map(formatMusicItem)
  50. return {
  51. isEnd: res.data.data.total <= page * pageSize,
  52. data: songs
  53. }
  54. }
  55. async function searchAlbum(query, page) {
  56. const headers = await getHeaders();
  57. const res = (await axios.get('http://www.kuwo.cn/api/www/search/searchAlbumBykeyWord', {
  58. headers,
  59. params: {
  60. key: query,
  61. pn: page,
  62. rn: pageSize,
  63. httpStatus: 1
  64. }
  65. })).data;
  66. const albums = res.data.albumList.map(formatAlbumItem)
  67. return {
  68. isEnd: res.data.total <= page * pageSize,
  69. data: albums
  70. }
  71. }
  72. async function searchArtist(query, page) {
  73. const headers = await getHeaders();
  74. const res = (await axios.get('http://www.kuwo.cn/api/www/search/searchArtistBykeyWord', {
  75. headers,
  76. params: {
  77. key: query,
  78. pn: page,
  79. rn: pageSize,
  80. httpStatus: 1
  81. }
  82. })).data;
  83. const artists = res.data.list.map(_ => ({
  84. name: he.decode(_.name),
  85. id: _.id,
  86. avatar: _.pic || _.pic120 || _.pic700 || _.pic70,
  87. worksNum: _.musicNum
  88. }))
  89. return {
  90. isEnd: res.data.total <= page * pageSize,
  91. data: artists
  92. }
  93. }
  94. async function getArtistMusicWorks (artistItem, page) {
  95. const headers = await getHeaders();
  96. const res = (await axios.get('http://www.kuwo.cn/api/www/artist/artistMusic', {
  97. headers: {
  98. ...headers,
  99. referer: `http://www.kuwo.cn/singer_detail/${artistItem.id}`
  100. },
  101. params: {
  102. artistid: artistItem.id,
  103. pn: page,
  104. rn: pageSize,
  105. httpStatus: 1
  106. }
  107. })).data;
  108. const musicList = res.data.list.filter(_ => !_.isListenFee).map(formatMusicItem);
  109. return {
  110. isEnd: res.data.total <= page * pageSize,
  111. data: musicList
  112. }
  113. }
  114. async function getArtistAlbumWorks (artistItem, page) {
  115. const headers = await getHeaders();
  116. const res = (await axios.get('http://www.kuwo.cn/api/www/artist/artistAlbum', {
  117. headers: {
  118. ...headers,
  119. referer: `http://www.kuwo.cn/singer_detail/${artistItem.id}`
  120. },
  121. params: {
  122. artistid: artistItem.id,
  123. pn: page,
  124. rn: pageSize,
  125. httpStatus: 1
  126. }
  127. })).data;
  128. const albumList = res.data.albumList.map(formatAlbumItem);
  129. return {
  130. isEnd: res.data.total <= page * pageSize,
  131. data: albumList
  132. }
  133. }
  134. async function getArtistWorks(artistItem, page, type) {
  135. if(type === 'music') {
  136. return getArtistMusicWorks(artistItem, page);
  137. } else if (type === 'album') {
  138. return getArtistAlbumWorks(artistItem, page);
  139. }
  140. }
  141. async function getLyric(musicItem) {
  142. const headers = await getHeaders();
  143. const res = (await axios.get('http://m.kuwo.cn/newh5/singles/songinfoandlrc', {
  144. headers,
  145. params: {
  146. musicId: musicItem.id,
  147. httpStatus: 1
  148. }
  149. })).data;
  150. const list = res.data.lrclist;
  151. return {
  152. rawLrc: list.map(_ => `[${_.time}]${_.lineLyric}`).join('\n')
  153. }
  154. }
  155. async function getAlbumInfo(albumItem) {
  156. const headers = await getHeaders();
  157. const res = (await axios.get('http://www.kuwo.cn/api/www/album/albumInfo', {
  158. headers,
  159. params: {
  160. albumId: albumItem.id,
  161. httpStatus: 1
  162. }
  163. })).data;
  164. return {
  165. ...albumItem,
  166. musicList: res.data.musicList.filter(_ => !_.isListenFee).map(formatMusicItem)
  167. }
  168. }
  169. return {
  170. platform: '酷我',
  171. version: '0.0.0',
  172. appVersion: '>0.0.1-alpha.3',
  173. srcUrl: 'https://gitee.com/maotoumao/MusicFreePlugins/raw/master/kuwo.js',
  174. cacheControl: 'no-cache',
  175. async search(query, page, type) {
  176. if (type === 'music') {
  177. return await searchMusic(query, page);
  178. }
  179. if (type === 'album') {
  180. return await searchAlbum(query, page);
  181. }
  182. if (type === 'artist') {
  183. return await searchArtist(query, page);
  184. }
  185. },
  186. async getMediaSource(musicItem) {
  187. const headers = await getHeaders();
  188. const res = (await axios.get('http://www.kuwo.cn/api/v1/www/music/playUrl', {
  189. headers,
  190. params: {
  191. mid: musicItem.id,
  192. type: 'music',
  193. httpStatus: 1
  194. }
  195. })).data;
  196. return {
  197. url: res.data.url
  198. };
  199. },
  200. getAlbumInfo,
  201. getLyric,
  202. getArtistWorks
  203. }
  204. }