5sing.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. function fiveSing(packages) {
  2. const { axios, cheerio } = packages;
  3. const pageSize = 10;
  4. function formatMusicItem(_) {
  5. return {
  6. id: _.songId,
  7. title: cheerio.load(_.songName).text(),
  8. artist: _.singer,
  9. singerId: _.singerId,
  10. album: _.typeName,
  11. type: _.type,
  12. typeName: _.typeName,
  13. typeEname: _.typeEname
  14. }
  15. }
  16. function formatAlbumItem(_) {
  17. return {
  18. id: _.songListId,
  19. artist: _.userName,
  20. title: cheerio.load(_.title).text(),
  21. artwork: _.pictureUrl,
  22. description: _.content,
  23. date: _.createTime,
  24. }
  25. }
  26. function formatArtistItem(_) {
  27. return ({
  28. id: _.id,
  29. name: cheerio.load(_.nickName).text(),
  30. fans: _.fans,
  31. avatar: _.pictureUrl,
  32. description: _.description,
  33. worksNum: _.totalSong
  34. })
  35. }
  36. const searchHeaders = {
  37. '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',
  38. 'Host': 'search.5sing.kugou.com',
  39. 'Accept': 'application/json, text/javascript, */*; q=0.01',
  40. 'Accept-Encoding': 'gzip, deflate',
  41. 'Accept-Language': 'zh-CN,zh;q=0.9',
  42. 'Referer': 'http://search.5sing.kugou.com/home/index'
  43. }
  44. async function searchMusic(query, page) {
  45. const res = (await axios.get('http://search.5sing.kugou.com/home/json', {
  46. headers: searchHeaders,
  47. params: {
  48. keyword: query,
  49. sort: 1,
  50. page,
  51. filter: 0,
  52. type: 0,
  53. }
  54. })).data;
  55. const songs = res.list.map(formatMusicItem);
  56. return {
  57. isEnd: res.pageInfo.cur >= res.pageInfo.totalPages,
  58. data: songs
  59. }
  60. }
  61. async function searchAlbum(query, page) {
  62. const res = (await axios.get('http://search.5sing.kugou.com/home/json', {
  63. headers: searchHeaders,
  64. params: {
  65. keyword: query,
  66. sort: 1,
  67. page,
  68. filter: 0,
  69. type: 1,
  70. }
  71. })).data;
  72. const songs = res.list.map(formatAlbumItem);
  73. return {
  74. isEnd: res.pageInfo.cur >= res.pageInfo.totalPages,
  75. data: songs
  76. }
  77. }
  78. async function searchArtist(query, page) {
  79. const res = (await axios.get('http://search.5sing.kugou.com/home/json', {
  80. headers: searchHeaders,
  81. params: {
  82. keyword: query,
  83. sort: 1,
  84. page,
  85. filter: 1,
  86. type: 2,
  87. }
  88. })).data;
  89. const songs = res.list.map(formatArtistItem);
  90. return {
  91. isEnd: res.pageInfo.cur >= res.pageInfo.totalPages,
  92. data: songs
  93. }
  94. }
  95. let fcEnd = false;
  96. let ycEnd = false;
  97. let bzEnd = false;
  98. async function getArtistMusicWorks(artistItem, page) {
  99. if(page === 1) {
  100. fcEnd = false;
  101. ycEnd = false;
  102. bzEnd = false;
  103. }
  104. const headers = {
  105. 'Accept': 'application/json, text/plain, */*',
  106. 'Accept-Encoding': 'gzip, deflate',
  107. 'Accept-Language': 'zh-CN,zh;q=0.9',
  108. 'Cache-Control': 'no-cache',
  109. 'Connection': 'keep-alive',
  110. 'Host': 'service.5sing.kugou.com',
  111. 'Origin': 'http://5sing.kugou.com',
  112. 'Pragma': 'no-cache',
  113. 'Referer': 'http://5sing.kugou.com/',
  114. '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'
  115. }
  116. let data = [];
  117. if(!fcEnd) {
  118. const res = (await (axios.get('http://service.5sing.kugou.com/user/songlist', {
  119. headers,
  120. params: {
  121. userId: artistItem.id,
  122. type: 'fc',
  123. pageSize,
  124. page
  125. }
  126. }))).data;
  127. if(res.count <= page * pageSize) {
  128. fcEnd = true;
  129. }
  130. data = data.concat(res.data.map(_ => ({
  131. id: _.songId,
  132. artist: artistItem.name,
  133. title: _.songName,
  134. typeEname: 'fc',
  135. typeName: '翻唱',
  136. type: _.songType,
  137. album: '翻唱'
  138. })))
  139. }
  140. if(!ycEnd) {
  141. const res = (await (axios.get('http://service.5sing.kugou.com/user/songlist', {
  142. headers,
  143. params: {
  144. userId: artistItem.id,
  145. type: 'yc',
  146. pageSize,
  147. page
  148. }
  149. }))).data;
  150. if(res.count <= page * pageSize) {
  151. ycEnd = true;
  152. }
  153. data = data.concat(res.data.map(_ => ({
  154. id: _.songId,
  155. artist: artistItem.name,
  156. title: _.songName,
  157. typeEname: 'yc',
  158. typeName: '原唱',
  159. type: _.songType,
  160. album: '原唱'
  161. })));
  162. }
  163. if(!bzEnd) {
  164. const res = (await (axios.get('http://service.5sing.kugou.com/user/songlist', {
  165. headers,
  166. params: {
  167. userId: artistItem.id,
  168. type: 'bz',
  169. pageSize,
  170. page
  171. }
  172. }))).data;
  173. if(res.count <= page * pageSize) {
  174. bzEnd = true;
  175. }
  176. data = data.concat(res.data.map(_ => ({
  177. id: _.songId,
  178. artist: artistItem.name,
  179. title: _.songName,
  180. typeEname: 'bz',
  181. typeName: '伴奏',
  182. type: _.songType,
  183. album: '伴奏'
  184. })));
  185. }
  186. return {
  187. isEnd: fcEnd && ycEnd && bzEnd,
  188. data
  189. }
  190. }
  191. async function getArtistWorks(artistItem, page, type) {
  192. if (type === 'music') {
  193. return getArtistMusicWorks(artistItem, page);
  194. }
  195. }
  196. async function getLyric(musicItem) {
  197. const headers = {
  198. 'Accept': '*/*',
  199. 'Accept-Encoding': 'gzip, deflate',
  200. 'Accept-Language': 'zh-CN,zh;q=0.9',
  201. 'Host': 'service.5sing.kugou.com',
  202. 'Referer': 'http://5sing.kugou.com/',
  203. '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'
  204. };
  205. const res = (await axios.get('http://5sing.kugou.com/fm/m/json/lrc', {
  206. headers,
  207. params: {
  208. songId: musicItem.id,
  209. songType: musicItem.typeEname
  210. }
  211. })).data;
  212. return {
  213. rawLrc: res.txt
  214. }
  215. }
  216. async function getAlbumInfo(albumItem) {
  217. const headers = {
  218. 'Accept': 'application/json, text/plain, */*',
  219. 'Accept-Encoding': 'gzip, deflate',
  220. 'Accept-Language': 'zh-CN,zh;q=0.9',
  221. 'Cache-Control': 'no-cache',
  222. 'Host': 'service.5sing.kugou.com',
  223. 'Origin': 'http://5sing.kugou.com',
  224. 'Referer': 'http://5sing.kugou.com/',
  225. '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'
  226. }
  227. const res = (await axios.get('http://service.5sing.kugou.com/song/getPlayListSong', {
  228. headers: headers,
  229. params: {
  230. id: albumItem.id,
  231. }
  232. })).data;
  233. return {
  234. ...albumItem,
  235. musicList: res.data.map(_ => ({
  236. id: _.ID,
  237. typeEname: _.SK,
  238. title: _.SN,
  239. artist: _.user.NN,
  240. singerId: _.user.ID,
  241. album: albumItem.title,
  242. artwork: albumItem.artwork,
  243. }))
  244. }
  245. }
  246. return {
  247. platform: '5sing',
  248. version: '0.0.0',
  249. srcUrl: 'https://gitee.com/maotoumao/MusicFreePlugins/raw/master/5sing.js',
  250. cacheControl: 'no-cache',
  251. async search(query, page, type) {
  252. if (type === 'music') {
  253. return await searchMusic(query, page);
  254. }
  255. if (type === 'album') {
  256. return await searchAlbum(query, page);
  257. }
  258. if (type === 'artist') {
  259. return await searchArtist(query, page);
  260. }
  261. },
  262. async getMediaSource(musicItem) {
  263. const headers = {
  264. 'Accept': '*/*',
  265. 'Accept-Encoding': 'gzip, deflate',
  266. 'Accept-Language': 'zh-CN,zh;q=0.9',
  267. 'Host': 'service.5sing.kugou.com',
  268. 'Referer': 'http://5sing.kugou.com/',
  269. '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'
  270. };
  271. const res = (await axios.get('http://service.5sing.kugou.com/song/getsongurl', {
  272. headers,
  273. params: {
  274. songid: musicItem.id,
  275. songtype: musicItem.typeEname,
  276. from: 'web',
  277. version: '6.6.72',
  278. _: Date.now()
  279. }
  280. })).data;
  281. const data = JSON.parse(res.substring(1, res.length - 1)).data;
  282. return {
  283. url: data.hqurl || data.lqurl || data.squrl
  284. };
  285. },
  286. getAlbumInfo,
  287. getLyric,
  288. getArtistWorks
  289. }
  290. }