@eldment/meting-mcp 1.6.2 → 1.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -7
- package/package.json +6 -1
- package/src/index.js +6 -4
- package/src/mcp-server.js +83 -34
- package/src/meting.js +21 -22
- package/src/providers/baidu.js +91 -89
- package/src/providers/base.js +13 -13
- package/src/providers/index.js +7 -7
- package/src/providers/kugou.js +118 -113
- package/src/providers/kuwo.js +63 -57
- package/src/providers/netease.js +105 -98
- package/src/providers/tencent.js +98 -93
package/src/providers/kugou.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import crypto from
|
|
2
|
-
import BaseProvider from
|
|
1
|
+
import crypto from "crypto";
|
|
2
|
+
import BaseProvider from "./base.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* 酷狗音乐平台提供者
|
|
@@ -7,7 +7,7 @@ import BaseProvider from './base.js';
|
|
|
7
7
|
export default class KugouProvider extends BaseProvider {
|
|
8
8
|
constructor(meting) {
|
|
9
9
|
super(meting);
|
|
10
|
-
this.name =
|
|
10
|
+
this.name = "kugou";
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -15,8 +15,8 @@ export default class KugouProvider extends BaseProvider {
|
|
|
15
15
|
*/
|
|
16
16
|
getHeaders() {
|
|
17
17
|
return {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
"User-Agent": "IPhone-8990-searchSong",
|
|
19
|
+
"UNI-UserAgent": "iOS11.4-Phone8990-1009-0-WiFi",
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -25,8 +25,8 @@ export default class KugouProvider extends BaseProvider {
|
|
|
25
25
|
*/
|
|
26
26
|
search(keyword, option = {}) {
|
|
27
27
|
return {
|
|
28
|
-
method:
|
|
29
|
-
url:
|
|
28
|
+
method: "GET",
|
|
29
|
+
url: "http://mobilecdn.kugou.com/api/v3/search/song",
|
|
30
30
|
body: {
|
|
31
31
|
api_ver: 1,
|
|
32
32
|
area_code: 1,
|
|
@@ -38,9 +38,9 @@ export default class KugouProvider extends BaseProvider {
|
|
|
38
38
|
showtype: 10,
|
|
39
39
|
page: option.page || 1,
|
|
40
40
|
keyword: keyword,
|
|
41
|
-
version: 8990
|
|
41
|
+
version: 8990,
|
|
42
42
|
},
|
|
43
|
-
format:
|
|
43
|
+
format: "data.info",
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -49,14 +49,14 @@ export default class KugouProvider extends BaseProvider {
|
|
|
49
49
|
*/
|
|
50
50
|
song(id) {
|
|
51
51
|
return {
|
|
52
|
-
method:
|
|
53
|
-
url:
|
|
52
|
+
method: "POST",
|
|
53
|
+
url: "http://m.kugou.com/app/i/getSongInfo.php",
|
|
54
54
|
body: {
|
|
55
|
-
cmd:
|
|
55
|
+
cmd: "playInfo",
|
|
56
56
|
hash: id,
|
|
57
|
-
from:
|
|
57
|
+
from: "mkugou",
|
|
58
58
|
},
|
|
59
|
-
format:
|
|
59
|
+
format: "",
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -65,17 +65,17 @@ export default class KugouProvider extends BaseProvider {
|
|
|
65
65
|
*/
|
|
66
66
|
album(id) {
|
|
67
67
|
return {
|
|
68
|
-
method:
|
|
69
|
-
url:
|
|
68
|
+
method: "GET",
|
|
69
|
+
url: "http://mobilecdn.kugou.com/api/v3/album/song",
|
|
70
70
|
body: {
|
|
71
71
|
albumid: id,
|
|
72
72
|
area_code: 1,
|
|
73
73
|
plat: 2,
|
|
74
74
|
page: 1,
|
|
75
75
|
pagesize: -1,
|
|
76
|
-
version: 8990
|
|
76
|
+
version: 8990,
|
|
77
77
|
},
|
|
78
|
-
format:
|
|
78
|
+
format: "data.info",
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -84,17 +84,17 @@ export default class KugouProvider extends BaseProvider {
|
|
|
84
84
|
*/
|
|
85
85
|
artist(id, limit = 50) {
|
|
86
86
|
return {
|
|
87
|
-
method:
|
|
88
|
-
url:
|
|
87
|
+
method: "GET",
|
|
88
|
+
url: "http://mobilecdn.kugou.com/api/v3/singer/song",
|
|
89
89
|
body: {
|
|
90
90
|
singerid: id,
|
|
91
91
|
area_code: 1,
|
|
92
92
|
page: 1,
|
|
93
93
|
plat: 0,
|
|
94
94
|
pagesize: limit,
|
|
95
|
-
version: 8990
|
|
95
|
+
version: 8990,
|
|
96
96
|
},
|
|
97
|
-
format:
|
|
97
|
+
format: "data.info",
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
100
|
|
|
@@ -103,17 +103,17 @@ export default class KugouProvider extends BaseProvider {
|
|
|
103
103
|
*/
|
|
104
104
|
playlist(id) {
|
|
105
105
|
return {
|
|
106
|
-
method:
|
|
107
|
-
url:
|
|
106
|
+
method: "GET",
|
|
107
|
+
url: "http://mobilecdn.kugou.com/api/v3/special/song",
|
|
108
108
|
body: {
|
|
109
109
|
specialid: id,
|
|
110
110
|
area_code: 1,
|
|
111
111
|
page: 1,
|
|
112
112
|
plat: 2,
|
|
113
113
|
pagesize: -1,
|
|
114
|
-
version: 8990
|
|
114
|
+
version: 8990,
|
|
115
115
|
},
|
|
116
|
-
format:
|
|
116
|
+
format: "data.info",
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -122,53 +122,55 @@ export default class KugouProvider extends BaseProvider {
|
|
|
122
122
|
* 有 cookie 时走新接口(songinfo + 签名),无 cookie 走老接口
|
|
123
123
|
*/
|
|
124
124
|
url(id, br = 320) {
|
|
125
|
-
const cookie = this.parseCookie(this.meting.header[
|
|
125
|
+
const cookie = this.parseCookie(this.meting.header["Cookie"] || "");
|
|
126
126
|
const hasToken = !!(cookie.t && cookie.KugooID);
|
|
127
127
|
|
|
128
128
|
if (hasToken) {
|
|
129
129
|
const now = Date.now();
|
|
130
130
|
const params = {
|
|
131
|
-
srcappid:
|
|
132
|
-
clientver:
|
|
131
|
+
srcappid: "2919",
|
|
132
|
+
clientver: "20000",
|
|
133
133
|
clienttime: String(now),
|
|
134
|
-
mid: cookie.mid || cookie.kg_mid ||
|
|
135
|
-
uuid: cookie.uuid || cookie.mid || cookie.kg_mid ||
|
|
136
|
-
dfid: cookie.dfid || cookie.kg_dfid ||
|
|
137
|
-
appid:
|
|
138
|
-
platid:
|
|
134
|
+
mid: cookie.mid || cookie.kg_mid || "",
|
|
135
|
+
uuid: cookie.uuid || cookie.mid || cookie.kg_mid || "",
|
|
136
|
+
dfid: cookie.dfid || cookie.kg_dfid || "",
|
|
137
|
+
appid: "1014",
|
|
138
|
+
platid: "4",
|
|
139
139
|
hash: id,
|
|
140
|
-
token: cookie.t ||
|
|
141
|
-
userid: cookie.KugooID ||
|
|
140
|
+
token: cookie.t || "",
|
|
141
|
+
userid: cookie.KugooID || "",
|
|
142
142
|
};
|
|
143
143
|
|
|
144
144
|
return {
|
|
145
|
-
method:
|
|
145
|
+
method: "GET",
|
|
146
146
|
url: this.buildSonginfoUrl(params),
|
|
147
147
|
body: null,
|
|
148
|
-
decode:
|
|
148
|
+
decode: "kugou_url_new",
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
// 老接口,无需 cookie
|
|
153
153
|
return {
|
|
154
|
-
method:
|
|
155
|
-
url:
|
|
154
|
+
method: "POST",
|
|
155
|
+
url: "http://media.store.kugou.com/v1/get_res_privilege",
|
|
156
156
|
body: JSON.stringify({
|
|
157
157
|
relate: 1,
|
|
158
|
-
userid:
|
|
158
|
+
userid: "0",
|
|
159
159
|
vip: 0,
|
|
160
160
|
appid: 1000,
|
|
161
|
-
token:
|
|
162
|
-
behavior:
|
|
163
|
-
area_code:
|
|
164
|
-
clientver:
|
|
165
|
-
resource: [
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
161
|
+
token: "",
|
|
162
|
+
behavior: "download",
|
|
163
|
+
area_code: "1",
|
|
164
|
+
clientver: "8990",
|
|
165
|
+
resource: [
|
|
166
|
+
{
|
|
167
|
+
id: 0,
|
|
168
|
+
type: "audio",
|
|
169
|
+
hash: id,
|
|
170
|
+
},
|
|
171
|
+
],
|
|
170
172
|
}),
|
|
171
|
-
decode:
|
|
173
|
+
decode: "kugou_url_legacy",
|
|
172
174
|
};
|
|
173
175
|
}
|
|
174
176
|
|
|
@@ -177,16 +179,16 @@ export default class KugouProvider extends BaseProvider {
|
|
|
177
179
|
*/
|
|
178
180
|
lyric(id) {
|
|
179
181
|
return {
|
|
180
|
-
method:
|
|
181
|
-
url:
|
|
182
|
+
method: "GET",
|
|
183
|
+
url: "http://krcs.kugou.com/search",
|
|
182
184
|
body: {
|
|
183
|
-
keyword:
|
|
185
|
+
keyword: "%20-%20",
|
|
184
186
|
ver: 1,
|
|
185
187
|
hash: id,
|
|
186
|
-
client:
|
|
187
|
-
man:
|
|
188
|
+
client: "mobi",
|
|
189
|
+
man: "yes",
|
|
188
190
|
},
|
|
189
|
-
decode:
|
|
191
|
+
decode: "kugou_lyric",
|
|
190
192
|
};
|
|
191
193
|
}
|
|
192
194
|
|
|
@@ -199,7 +201,7 @@ export default class KugouProvider extends BaseProvider {
|
|
|
199
201
|
this.meting.isFormat = format;
|
|
200
202
|
const songData = JSON.parse(data);
|
|
201
203
|
let url = songData.imgUrl;
|
|
202
|
-
url = url.replace(
|
|
204
|
+
url = url.replace("{size}", "400");
|
|
203
205
|
return JSON.stringify({ url: url });
|
|
204
206
|
}
|
|
205
207
|
|
|
@@ -212,19 +214,19 @@ export default class KugouProvider extends BaseProvider {
|
|
|
212
214
|
id: data.hash,
|
|
213
215
|
name: data.songName || filename,
|
|
214
216
|
artist: [],
|
|
215
|
-
album: data.album_name ||
|
|
217
|
+
album: data.album_name || "",
|
|
216
218
|
url_id: data.encode_album_audio_id || data.hash,
|
|
217
219
|
pic_id: data.hash,
|
|
218
220
|
lyric_id: data.hash,
|
|
219
|
-
source:
|
|
221
|
+
source: "kugou",
|
|
220
222
|
};
|
|
221
223
|
|
|
222
224
|
if (data.authors && Array.isArray(data.authors)) {
|
|
223
|
-
result.artist = data.authors.map(a => a.author_name);
|
|
225
|
+
result.artist = data.authors.map((a) => a.author_name);
|
|
224
226
|
} else if (filename) {
|
|
225
|
-
const parts = filename.split(
|
|
227
|
+
const parts = filename.split(" - ");
|
|
226
228
|
if (parts.length >= 2) {
|
|
227
|
-
result.artist = parts[0].split(
|
|
229
|
+
result.artist = parts[0].split("、");
|
|
228
230
|
result.name = parts[1];
|
|
229
231
|
}
|
|
230
232
|
}
|
|
@@ -238,8 +240,8 @@ export default class KugouProvider extends BaseProvider {
|
|
|
238
240
|
parseCookie(cookieStr) {
|
|
239
241
|
const cookies = {};
|
|
240
242
|
if (!cookieStr) return cookies;
|
|
241
|
-
cookieStr.split(
|
|
242
|
-
const idx = pair.indexOf(
|
|
243
|
+
cookieStr.split(";").forEach((pair) => {
|
|
244
|
+
const idx = pair.indexOf("=");
|
|
243
245
|
if (idx > 0) {
|
|
244
246
|
const key = pair.substring(0, idx).trim();
|
|
245
247
|
const val = pair.substring(idx + 1).trim();
|
|
@@ -253,23 +255,23 @@ export default class KugouProvider extends BaseProvider {
|
|
|
253
255
|
* 生成酷狗 API 签名
|
|
254
256
|
*/
|
|
255
257
|
getSignature(params) {
|
|
256
|
-
const MD5_KEY =
|
|
258
|
+
const MD5_KEY = "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt";
|
|
257
259
|
const paramStr = Object.entries(params)
|
|
258
260
|
.map(([k, v]) => `${k}=${v}`)
|
|
259
|
-
.join(
|
|
260
|
-
const sorted = paramStr.split(
|
|
261
|
-
return crypto.createHash(
|
|
261
|
+
.join("&");
|
|
262
|
+
const sorted = paramStr.split("&").sort().join("");
|
|
263
|
+
return crypto.createHash("md5").update(`${MD5_KEY}${sorted}${MD5_KEY}`).digest("hex");
|
|
262
264
|
}
|
|
263
265
|
|
|
264
266
|
/**
|
|
265
267
|
* 处理酷狗音乐的解码逻辑
|
|
266
268
|
*/
|
|
267
269
|
async handleDecode(decodeType, data) {
|
|
268
|
-
if (decodeType ===
|
|
270
|
+
if (decodeType === "kugou_url_new") {
|
|
269
271
|
return this.urlDecodeNew(data);
|
|
270
|
-
} else if (decodeType ===
|
|
272
|
+
} else if (decodeType === "kugou_url_legacy") {
|
|
271
273
|
return this.urlDecodeLegacy(data);
|
|
272
|
-
} else if (decodeType ===
|
|
274
|
+
} else if (decodeType === "kugou_lyric") {
|
|
273
275
|
return this.lyricDecode(data);
|
|
274
276
|
}
|
|
275
277
|
return data;
|
|
@@ -282,7 +284,7 @@ export default class KugouProvider extends BaseProvider {
|
|
|
282
284
|
const signature = this.getSignature(params);
|
|
283
285
|
const queryString = Object.entries(params)
|
|
284
286
|
.map(([k, v]) => `${k}=${encodeURIComponent(v)}`)
|
|
285
|
-
.join(
|
|
287
|
+
.join("&");
|
|
286
288
|
return `https://wwwapi.kugou.com/play/songinfo?${queryString}&signature=${signature}`;
|
|
287
289
|
}
|
|
288
290
|
|
|
@@ -296,45 +298,45 @@ export default class KugouProvider extends BaseProvider {
|
|
|
296
298
|
const json = JSON.parse(result);
|
|
297
299
|
const data = json.data;
|
|
298
300
|
if (!data || !data.encode_album_audio_id) {
|
|
299
|
-
return JSON.stringify({ url:
|
|
301
|
+
return JSON.stringify({ url: "", size: 0, br: -1 });
|
|
300
302
|
}
|
|
301
303
|
|
|
302
304
|
// 第二步:用 encode_album_audio_id 重新查询
|
|
303
|
-
const cookie = this.parseCookie(this.meting.header[
|
|
305
|
+
const cookie = this.parseCookie(this.meting.header["Cookie"] || "");
|
|
304
306
|
const now = Date.now();
|
|
305
307
|
const params = {
|
|
306
|
-
srcappid:
|
|
307
|
-
clientver:
|
|
308
|
+
srcappid: "2919",
|
|
309
|
+
clientver: "20000",
|
|
308
310
|
clienttime: String(now),
|
|
309
|
-
mid: cookie.mid || cookie.kg_mid ||
|
|
310
|
-
uuid: cookie.uuid || cookie.mid || cookie.kg_mid ||
|
|
311
|
-
dfid: cookie.dfid || cookie.kg_dfid ||
|
|
312
|
-
appid:
|
|
313
|
-
platid:
|
|
311
|
+
mid: cookie.mid || cookie.kg_mid || "",
|
|
312
|
+
uuid: cookie.uuid || cookie.mid || cookie.kg_mid || "",
|
|
313
|
+
dfid: cookie.dfid || cookie.kg_dfid || "",
|
|
314
|
+
appid: "1014",
|
|
315
|
+
platid: "4",
|
|
314
316
|
encode_album_audio_id: data.encode_album_audio_id,
|
|
315
|
-
token: cookie.t ||
|
|
316
|
-
userid: cookie.KugooID ||
|
|
317
|
+
token: cookie.t || "",
|
|
318
|
+
userid: cookie.KugooID || "",
|
|
317
319
|
};
|
|
318
320
|
|
|
319
321
|
const api = {
|
|
320
|
-
method:
|
|
322
|
+
method: "GET",
|
|
321
323
|
url: this.buildSonginfoUrl(params),
|
|
322
|
-
body: null
|
|
324
|
+
body: null,
|
|
323
325
|
};
|
|
324
326
|
const response = JSON.parse(await this.meting._exec(api));
|
|
325
327
|
const detail = response.data;
|
|
326
328
|
if (detail) {
|
|
327
|
-
const url = detail.play_url || detail.play_backup_url ||
|
|
329
|
+
const url = detail.play_url || detail.play_backup_url || "";
|
|
328
330
|
return JSON.stringify({
|
|
329
331
|
url: url,
|
|
330
332
|
size: detail.filesize || 0,
|
|
331
|
-
br: detail.bitrate || -1
|
|
333
|
+
br: detail.bitrate || -1,
|
|
332
334
|
});
|
|
333
335
|
}
|
|
334
336
|
} catch (e) {
|
|
335
337
|
// parse error
|
|
336
338
|
}
|
|
337
|
-
return JSON.stringify({ url:
|
|
339
|
+
return JSON.stringify({ url: "", size: 0, br: -1 });
|
|
338
340
|
}
|
|
339
341
|
|
|
340
342
|
/**
|
|
@@ -350,16 +352,19 @@ export default class KugouProvider extends BaseProvider {
|
|
|
350
352
|
for (const item of data.data[0].relate_goods) {
|
|
351
353
|
if (item.info.bitrate <= this.meting.temp.br && item.info.bitrate > maxBr) {
|
|
352
354
|
const api = {
|
|
353
|
-
method:
|
|
354
|
-
url:
|
|
355
|
+
method: "GET",
|
|
356
|
+
url: "http://trackercdn.kugou.com/i/v2/",
|
|
355
357
|
body: {
|
|
356
358
|
hash: item.hash,
|
|
357
|
-
key: crypto
|
|
359
|
+
key: crypto
|
|
360
|
+
.createHash("md5")
|
|
361
|
+
.update(item.hash + "kgcloudv2")
|
|
362
|
+
.digest("hex"),
|
|
358
363
|
pid: 3,
|
|
359
|
-
behavior:
|
|
360
|
-
cmd:
|
|
361
|
-
version: 8990
|
|
362
|
-
}
|
|
364
|
+
behavior: "play",
|
|
365
|
+
cmd: "25",
|
|
366
|
+
version: 8990,
|
|
367
|
+
},
|
|
363
368
|
};
|
|
364
369
|
|
|
365
370
|
const response = JSON.parse(await this.meting._exec(api));
|
|
@@ -368,7 +373,7 @@ export default class KugouProvider extends BaseProvider {
|
|
|
368
373
|
url = {
|
|
369
374
|
url: Array.isArray(response.url) ? response.url[0] : response.url,
|
|
370
375
|
size: response.fileSize,
|
|
371
|
-
br: response.bitRate / 1000
|
|
376
|
+
br: response.bitRate / 1000,
|
|
372
377
|
};
|
|
373
378
|
}
|
|
374
379
|
}
|
|
@@ -380,7 +385,7 @@ export default class KugouProvider extends BaseProvider {
|
|
|
380
385
|
} catch (e) {
|
|
381
386
|
// parse error
|
|
382
387
|
}
|
|
383
|
-
return JSON.stringify({ url:
|
|
388
|
+
return JSON.stringify({ url: "", size: 0, br: -1 });
|
|
384
389
|
}
|
|
385
390
|
|
|
386
391
|
/**
|
|
@@ -388,30 +393,30 @@ export default class KugouProvider extends BaseProvider {
|
|
|
388
393
|
*/
|
|
389
394
|
async lyricDecode(result) {
|
|
390
395
|
const data = JSON.parse(result);
|
|
391
|
-
|
|
396
|
+
|
|
392
397
|
if (!data.candidates || data.candidates.length === 0) {
|
|
393
|
-
return JSON.stringify({ lyric:
|
|
398
|
+
return JSON.stringify({ lyric: "", tlyric: "" });
|
|
394
399
|
}
|
|
395
|
-
|
|
400
|
+
|
|
396
401
|
const api = {
|
|
397
|
-
method:
|
|
398
|
-
url:
|
|
402
|
+
method: "GET",
|
|
403
|
+
url: "http://lyrics.kugou.com/download",
|
|
399
404
|
body: {
|
|
400
|
-
charset:
|
|
405
|
+
charset: "utf8",
|
|
401
406
|
accesskey: data.candidates[0].accesskey,
|
|
402
407
|
id: data.candidates[0].id,
|
|
403
|
-
client:
|
|
404
|
-
fmt:
|
|
405
|
-
ver: 1
|
|
406
|
-
}
|
|
408
|
+
client: "mobi",
|
|
409
|
+
fmt: "lrc",
|
|
410
|
+
ver: 1,
|
|
411
|
+
},
|
|
407
412
|
};
|
|
408
|
-
|
|
413
|
+
|
|
409
414
|
const response = JSON.parse(await this.meting._exec(api));
|
|
410
415
|
const lyricData = {
|
|
411
|
-
lyric: Buffer.from(response.content,
|
|
412
|
-
tlyric:
|
|
416
|
+
lyric: Buffer.from(response.content, "base64").toString(),
|
|
417
|
+
tlyric: "",
|
|
413
418
|
};
|
|
414
|
-
|
|
419
|
+
|
|
415
420
|
return JSON.stringify(lyricData);
|
|
416
421
|
}
|
|
417
|
-
}
|
|
422
|
+
}
|