千千音乐.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. function qianqian(packages) {
  2. const { axios, dayjs, CryptoJs } = packages;
  3. const pageSize = 20;
  4. const secret = '0b50b02fd0d73a9c4c8c3a781c30845f';
  5. function getSignedParams(e) {
  6. if ("[object Object]" !== Object.prototype.toString.call(e))
  7. throw new Error("The parameter of query must be a Object.");
  8. var t = Math.floor(Date.now() / 1e3);
  9. Object.assign(e, {
  10. timestamp: t
  11. });
  12. var n = Object.keys(e);
  13. n.sort();
  14. for (var r = "", i = 0; i < n.length; i++) {
  15. var s = n[i];
  16. r += (0 == i ? "" : "&") + s + "=" + e[s]
  17. }
  18. return {
  19. ...e,
  20. sign: CryptoJs.MD5(r += secret).toString(),
  21. timestamp: t
  22. }
  23. }
  24. const searchHeaders = {
  25. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
  26. 'referer': 'https://music.91q.com/',
  27. 'from': 'web',
  28. 'accept': 'application/json, text/plain, */*',
  29. 'accept-encoding': 'gzip, deflate, br',
  30. 'accept-language': 'zh-CN,zh;q=0.9'
  31. };
  32. function formatMusicItem(_) {
  33. return {
  34. id: _.id || _.assetId,
  35. artwork: _.pic,
  36. title: _.title,
  37. artist: (_.artist || []).map(ar => ar.name).join('、'),
  38. artistItems: (_.artist || []).map(formatArtistItem),
  39. album: _.albumTitle,
  40. lrc: _.lyric
  41. }
  42. }
  43. function formatAlbumItem(_) {
  44. return {
  45. id: _.albumAssetCode,
  46. artist: (_.artist || []).map(ar => ar.name).join('、'),
  47. title: _.title,
  48. artwork: _.pic,
  49. description: '',
  50. date: dayjs(_.releaseDate).format('YYYY-MM-DD'),
  51. }
  52. }
  53. function formatArtistItem(_) {
  54. return {
  55. name: _.name,
  56. id: _.artistCode,
  57. avatar: _.pic,
  58. worksNum: _.trackTotal,
  59. description: _.introduce,
  60. }
  61. }
  62. function musicCanPlayFilter(_) {
  63. return !_.pay_model;
  64. }
  65. async function searchBase(query, page, type) {
  66. const res = (await axios.get('https://music.91q.com/v1/search', {
  67. headers: searchHeaders,
  68. params: getSignedParams({
  69. appid: '16073360',
  70. type,
  71. word: query,
  72. pageNo: page,
  73. pageSize
  74. })
  75. }));
  76. return res.data;
  77. }
  78. async function searchMusic(query, page) {
  79. const res = await searchBase(query, page, 1);
  80. return {
  81. isEnd: res.data.total <= page * pageSize,
  82. data: res.data.typeTrack.filter(musicCanPlayFilter).map(formatMusicItem)
  83. }
  84. }
  85. async function searchAlbum(query, page) {
  86. const res = await searchBase(query, page, 3);
  87. return {
  88. isEnd: res.data.total <= page * pageSize,
  89. data: res.data.typeAlbum.map(formatAlbumItem)
  90. }
  91. }
  92. async function searchArtist(query, page) {
  93. const res = await searchBase(query, page, 2);
  94. return {
  95. isEnd: res.data.total <= page * pageSize,
  96. data: res.data.typeArtist.map(formatArtistItem)
  97. }
  98. }
  99. async function getArtistMusicWorks(artistItem, page) {
  100. const headers = {
  101. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
  102. 'referer': `https://music.91q.com/search?word=${encodeURIComponent(artistItem.name)}`,
  103. 'from': 'web',
  104. 'accept': 'application/json, text/plain, */*',
  105. 'accept-encoding': 'gzip, deflate, br',
  106. 'accept-language': 'zh-CN,zh;q=0.9'
  107. };
  108. const res = (await axios.get('https://music.91q.com/v1/artist/song', {
  109. headers,
  110. params: getSignedParams({
  111. appid: '16073360',
  112. artistCode: artistItem.id,
  113. pageNo: page,
  114. pageSize
  115. })
  116. })).data;
  117. return {
  118. isEnd: res.data.total <= page * pageSize,
  119. data: res.data.result.filter(musicCanPlayFilter).map(formatMusicItem)
  120. }
  121. }
  122. async function getArtistAlbumWorks(artistItem, page) {
  123. const headers = {
  124. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
  125. 'referer': `https://music.91q.com/search?word=${encodeURIComponent(artistItem.name)}`,
  126. 'from': 'web',
  127. 'accept': 'application/json, text/plain, */*',
  128. 'accept-encoding': 'gzip, deflate, br',
  129. 'accept-language': 'zh-CN,zh;q=0.9'
  130. };
  131. const res = (await axios.get('https://music.91q.com/v1/artist/album', {
  132. headers,
  133. params: getSignedParams({
  134. appid: '16073360',
  135. artistCode: artistItem.id,
  136. pageNo: page,
  137. pageSize
  138. })
  139. })).data;
  140. return {
  141. isEnd: res.data.total <= page * pageSize,
  142. data: res.data.result.map(formatAlbumItem)
  143. }
  144. }
  145. async function getArtistWorks(artistItem, page, type) {
  146. if (type === 'music') {
  147. return getArtistMusicWorks(artistItem, page);
  148. } else if (type === 'album') {
  149. return getArtistAlbumWorks(artistItem, page);
  150. }
  151. }
  152. async function getLyric(musicItem) {
  153. return {
  154. lrc: musicItem.lrc
  155. }
  156. }
  157. async function getAlbumInfo(albumItem) {
  158. if (albumItem.musicList) {
  159. return albumItem;
  160. } else {
  161. const headers = {
  162. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
  163. 'referer': `https://music.91q.com/search?word=${encodeURIComponent(albumItem.name)}`,
  164. 'from': 'web',
  165. 'accept': 'application/json, text/plain, */*',
  166. 'accept-encoding': 'gzip, deflate, br',
  167. 'accept-language': 'zh-CN,zh;q=0.9'
  168. };
  169. const res = (await axios.get('https://music.91q.com/v1/album/info', {
  170. headers,
  171. params: getSignedParams({
  172. appid: '16073360',
  173. albumAssetCode: albumItem.id,
  174. })
  175. }));
  176. const musicList = (res.data.data.trackList || []).filter(musicCanPlayFilter).map(_ => ({
  177. ...formatMusicItem(_),
  178. artwork: albumItem.artwork,
  179. album: albumItem.name
  180. }))
  181. return {
  182. ...albumItem,
  183. musicList
  184. }
  185. }
  186. }
  187. return {
  188. platform: '千千音乐',
  189. version: '0.0.0',
  190. srcUrl: 'https://gitee.com/maotoumao/MusicFreePlugins/raw/master/qianqian.js',
  191. cacheControl: 'no-cache',
  192. async search(query, page, type) {
  193. if (type === 'music') {
  194. return await searchMusic(query, page);
  195. }
  196. if (type === 'album') {
  197. return await searchAlbum(query, page);
  198. }
  199. if (type === 'artist') {
  200. return await searchArtist(query, page);
  201. }
  202. },
  203. async getMediaSource(musicItem) {
  204. const headers = {
  205. 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1',
  206. 'referer': `https://music.91q.com/artist/${(musicItem.artistItems[0] || {}).id}`,
  207. 'from': 'webapp_music',
  208. 'accept': 'application/json, text/plain, */*',
  209. 'accept-encoding': 'gzip, deflate, br',
  210. 'accept-language': 'zh-CN,zh;q=0.9'
  211. }
  212. const res = (await axios.get('https://music.91q.com/v1/song/tracklink', {
  213. headers,
  214. params: getSignedParams({
  215. appid: '16073360',
  216. TSID: musicItem.id,
  217. })
  218. })).data;
  219. return {
  220. url: res.data.path
  221. };
  222. },
  223. getAlbumInfo,
  224. getLyric,
  225. getArtistWorks
  226. }
  227. }