audiomack.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * @File : audiomack.js
  3. * @Author : jade
  4. * @Date : 2024/1/31 15:56
  5. * @Email : jadehh@1ive.com
  6. * @Software : Samples
  7. * @Desc : 音乐之声
  8. */
  9. import {Spider} from "./spider.js";
  10. import {BookShort} from "../lib/book.js";
  11. import {Crypto} from "../lib/cat.js";
  12. function u(e) {
  13. (this._parameters = {}), this._loadParameters(e || {});
  14. }
  15. u.prototype = {
  16. _loadParameters: function (e) {
  17. e instanceof Array ? this._loadParametersFromArray(e) : "object" == typeof e && this._loadParametersFromObject(e);
  18. }, _loadParametersFromArray: function (e) {
  19. var n;
  20. for (n = 0; n < e.length; n++) this._loadParametersFromObject(e[n]);
  21. }, _loadParametersFromObject: function (e) {
  22. var n;
  23. for (n in e) if (e.hasOwnProperty(n)) {
  24. var r = this._getStringFromParameter(e[n]);
  25. this._loadParameterValue(n, r);
  26. }
  27. }, _loadParameterValue: function (e, n) {
  28. var r;
  29. if (n instanceof Array) {
  30. for (r = 0; r < n.length; r++) {
  31. var i = this._getStringFromParameter(n[r]);
  32. this._addParameter(e, i);
  33. }
  34. 0 == n.length && this._addParameter(e, "");
  35. } else this._addParameter(e, n);
  36. }, _getStringFromParameter: function (e) {
  37. var n = e || "";
  38. try {
  39. ("number" == typeof e || "boolean" == typeof e) && (n = e.toString());
  40. } catch (e) {
  41. }
  42. return n;
  43. }, _addParameter: function (e, n) {
  44. this._parameters[e] || (this._parameters[e] = []), this._parameters[e].push(n);
  45. }, get: function () {
  46. return this._parameters;
  47. },
  48. };
  49. function _decode(e) {
  50. return e ? decodeURIComponent(e) : "";
  51. }
  52. function getNormalizedParams(parameters) {
  53. const sortedKeys = [];
  54. const normalizedParameters = [];
  55. for (let e in parameters) {
  56. sortedKeys.push(_encode(e));
  57. }
  58. sortedKeys.sort();
  59. for (let idx = 0; idx < sortedKeys.length; idx++) {
  60. const e = sortedKeys[idx];
  61. var n, r, i = _decode(e), a = parameters[i];
  62. for (a.sort(), n = 0; n < a.length; n++) (r = _encode(a[n])), normalizedParameters.push(e + "=" + r);
  63. }
  64. return normalizedParameters.join("&");
  65. }
  66. function nonce(e = 10) {
  67. let n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", r = "";
  68. for (let i = 0; i < e; i++) r += n.charAt(Math.floor(Math.random() * n.length));
  69. return r;
  70. }
  71. function _encode(e) {
  72. return e ? encodeURIComponent(e)
  73. .replace(/[!'()]/g, escape)
  74. .replace(/\*/g, "%2A") : "";
  75. }
  76. function getSignature(method, urlPath, params, secret = "f3ac5b086f3eab260520d8e3049561e6") {
  77. urlPath = urlPath.split("?")[0];
  78. urlPath = urlPath.startsWith("http") ? urlPath : "https://api.audiomack.com/v1" + urlPath;
  79. const r = new u(params).get();
  80. const httpMethod = method.toUpperCase();
  81. const normdParams = getNormalizedParams(r);
  82. const l = _encode(httpMethod) + "&" + _encode(urlPath) + "&" + _encode(normdParams);
  83. return Crypto.HmacSHA1(l, secret + "&").toString(Crypto.enc.Base64);
  84. }
  85. class AudioMackSpider extends Spider {
  86. constructor() {
  87. super();
  88. this.siteUrl = "https://api.audiomack.com/v1";
  89. }
  90. getName() {
  91. return "🎵┃音声┃🎵"
  92. }
  93. getAppName() {
  94. return "音声"
  95. }
  96. getJSName() {
  97. return "audiomack"
  98. }
  99. getType() {
  100. return 10
  101. }
  102. async parseVodShortListFromJson(obj) {
  103. let books = []
  104. for (const data of obj["results"]["playlists"]) {
  105. let bookShort = new BookShort()
  106. bookShort.book_id = data["id"]
  107. bookShort.book_pic = data["image"]
  108. bookShort.book_name = data["title"]
  109. bookShort.book_remarks = data["description"]
  110. books.push(bookShort)
  111. }
  112. return books
  113. }
  114. async setClasses() {
  115. this.classes = [{"type_name": "推荐榜单", "type_id": "最近更新"}]
  116. const genres = [{
  117. title: "All Genres", url_slug: "null",
  118. }, {
  119. title: "Afrosounds", url_slug: "afrobeats",
  120. }, {
  121. title: "Hip-Hop/Rap", url_slug: "rap",
  122. }, {
  123. title: "Latin", url_slug: "latin",
  124. }, {
  125. title: "Caribbean", url_slug: "caribbean",
  126. }, {
  127. title: "Pop", url_slug: "pop",
  128. }, {
  129. title: "R&B", url_slug: "rb",
  130. }, {
  131. title: "Gospel", url_slug: "gospel",
  132. }, {
  133. title: "Electronic", url_slug: "electronic",
  134. }, {
  135. title: "Rock", url_slug: "rock",
  136. }, {
  137. title: "Punjabi", url_slug: "punjabi",
  138. }, {
  139. title: "Country", url_slug: "country",
  140. }, {
  141. title: "Instrumental", url_slug: "instrumental",
  142. }, {
  143. title: "Podcast", url_slug: "podcast",
  144. },];
  145. for (const genre of genres) {
  146. this.classes.push(this.getTypeDic(genre["title"], genre["url_slug"]))
  147. }
  148. }
  149. /* 推荐歌单
  150. * */
  151. async setHomeVod() {
  152. let tag = {id: "34", title: "What's New", url_slug: "whats-new"};
  153. const params = {
  154. featured: "yes",
  155. limit: 20,
  156. oauth_consumer_key: "audiomack-js",
  157. oauth_nonce: nonce(32),
  158. oauth_signature_method: "HMAC-SHA1",
  159. oauth_timestamp: Math.round(Date.now() / 1e3),
  160. oauth_version: "1.0",
  161. page: 1,
  162. slug: tag.url_slug,
  163. };
  164. const oauth_signature = getSignature("GET", "/playlist/categories", params);
  165. let url = this.siteUrl + "/playlist/categories"
  166. let content = await this.fetch(url, Object.assign(Object.assign({}, params), {oauth_signature}), this.getHeader());
  167. this.homeVodList = await this.parseVodShortListFromJson(JSON.parse(content))
  168. }
  169. async setCategory(tid, pg, filter, extend) {
  170. let partialUrl;
  171. if (tid === "null"){
  172. partialUrl = `/music/page/${pg}`;
  173. }else{
  174. partialUrl = `/music/${tid}/page/${pg}`;
  175. }
  176. const url = `https://api.audiomack.com/v1${partialUrl}`;
  177. const params = {
  178. oauth_consumer_key: "audiomack-js",
  179. oauth_nonce: nonce(32),
  180. oauth_signature_method: "HMAC-SHA1",
  181. oauth_timestamp: Math.round(Date.now() / 1e3),
  182. oauth_version: "1.0",
  183. type: "song",
  184. };
  185. const oauth_signature = getSignature("GET", partialUrl, params);
  186. const results = await this.fetch(url, Object.assign(Object.assign({}, params), {oauth_signature}),this.getHeader())
  187. let x = 0
  188. }
  189. }
  190. let spider = new AudioMackSpider()
  191. async function init(cfg) {
  192. await spider.init(cfg)
  193. }
  194. async function home(filter) {
  195. return await spider.home(filter)
  196. }
  197. async function homeVod() {
  198. return await spider.homeVod()
  199. }
  200. async function category(tid, pg, filter, extend) {
  201. return await spider.category(tid, pg, filter, extend)
  202. }
  203. async function detail(id) {
  204. return await spider.detail(id)
  205. }
  206. async function play(flag, id, flags) {
  207. return await spider.play(flag, id, flags)
  208. }
  209. async function search(wd, quick) {
  210. return await spider.search(wd, quick)
  211. }
  212. async function proxy(segments, headers) {
  213. return await spider.proxy(segments, headers)
  214. }
  215. export function __jsEvalReturn() {
  216. return {
  217. init: init,
  218. home: home,
  219. homeVod: homeVod,
  220. category: category,
  221. detail: detail,
  222. play: play,
  223. search: search,
  224. proxy: proxy
  225. };
  226. }
  227. export {spider}