@eldment/meting-mcp 1.6.1 → 1.6.3
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/ACKNOWLEDGEMENTS.md +9 -0
- package/README.md +51 -52
- package/package.json +8 -4
- package/src/index.js +6 -4
- package/src/mcp-server.js +63 -31
- 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/baidu.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 BaiduProvider extends BaseProvider {
|
|
8
8
|
constructor(meting) {
|
|
9
9
|
super(meting);
|
|
10
|
-
this.name =
|
|
10
|
+
this.name = "baidu";
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -15,11 +15,12 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
15
15
|
*/
|
|
16
16
|
getHeaders() {
|
|
17
17
|
return {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
Cookie: `BAIDUID=${this._getRandomHex(32)}:FG=1`,
|
|
19
|
+
"User-Agent":
|
|
20
|
+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) baidu-music/1.2.1 Chrome/66.0.3359.181 Electron/3.0.5 Safari/537.36",
|
|
21
|
+
Accept: "*/*",
|
|
22
|
+
"Content-Type": "application/json;charset=UTF-8",
|
|
23
|
+
"Accept-Language": "zh-CN",
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -28,19 +29,19 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
28
29
|
*/
|
|
29
30
|
search(keyword, option = {}) {
|
|
30
31
|
return {
|
|
31
|
-
method:
|
|
32
|
-
url:
|
|
32
|
+
method: "GET",
|
|
33
|
+
url: "http://musicapi.taihe.com/v1/restserver/ting",
|
|
33
34
|
body: {
|
|
34
|
-
from:
|
|
35
|
-
method:
|
|
35
|
+
from: "qianqianmini",
|
|
36
|
+
method: "baidu.ting.search.merge",
|
|
36
37
|
isNew: 1,
|
|
37
|
-
platform:
|
|
38
|
+
platform: "darwin",
|
|
38
39
|
page_no: option.page || 1,
|
|
39
40
|
query: keyword,
|
|
40
|
-
version:
|
|
41
|
-
page_size: option.limit || 30
|
|
41
|
+
version: "11.2.1",
|
|
42
|
+
page_size: option.limit || 30,
|
|
42
43
|
},
|
|
43
|
-
format:
|
|
44
|
+
format: "result.song_info.song_list",
|
|
44
45
|
};
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -49,18 +50,18 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
49
50
|
*/
|
|
50
51
|
song(id) {
|
|
51
52
|
return {
|
|
52
|
-
method:
|
|
53
|
-
url:
|
|
53
|
+
method: "GET",
|
|
54
|
+
url: "http://musicapi.taihe.com/v1/restserver/ting",
|
|
54
55
|
body: {
|
|
55
|
-
from:
|
|
56
|
-
method:
|
|
56
|
+
from: "qianqianmini",
|
|
57
|
+
method: "baidu.ting.song.getInfos",
|
|
57
58
|
songid: id,
|
|
58
59
|
res: 1,
|
|
59
|
-
platform:
|
|
60
|
-
version:
|
|
60
|
+
platform: "darwin",
|
|
61
|
+
version: "1.0.0",
|
|
61
62
|
},
|
|
62
|
-
encode:
|
|
63
|
-
format:
|
|
63
|
+
encode: "baidu_AESCBC",
|
|
64
|
+
format: "songinfo",
|
|
64
65
|
};
|
|
65
66
|
}
|
|
66
67
|
|
|
@@ -69,16 +70,16 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
69
70
|
*/
|
|
70
71
|
album(id) {
|
|
71
72
|
return {
|
|
72
|
-
method:
|
|
73
|
-
url:
|
|
73
|
+
method: "GET",
|
|
74
|
+
url: "http://musicapi.taihe.com/v1/restserver/ting",
|
|
74
75
|
body: {
|
|
75
|
-
from:
|
|
76
|
-
method:
|
|
76
|
+
from: "qianqianmini",
|
|
77
|
+
method: "baidu.ting.album.getAlbumInfo",
|
|
77
78
|
album_id: id,
|
|
78
|
-
platform:
|
|
79
|
-
version:
|
|
79
|
+
platform: "darwin",
|
|
80
|
+
version: "11.2.1",
|
|
80
81
|
},
|
|
81
|
-
format:
|
|
82
|
+
format: "songlist",
|
|
82
83
|
};
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -87,19 +88,19 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
87
88
|
*/
|
|
88
89
|
artist(id, limit = 50) {
|
|
89
90
|
return {
|
|
90
|
-
method:
|
|
91
|
-
url:
|
|
91
|
+
method: "GET",
|
|
92
|
+
url: "http://musicapi.taihe.com/v1/restserver/ting",
|
|
92
93
|
body: {
|
|
93
|
-
from:
|
|
94
|
-
method:
|
|
94
|
+
from: "qianqianmini",
|
|
95
|
+
method: "baidu.ting.artist.getSongList",
|
|
95
96
|
artistid: id,
|
|
96
97
|
limits: limit,
|
|
97
|
-
platform:
|
|
98
|
+
platform: "darwin",
|
|
98
99
|
offset: 0,
|
|
99
100
|
tinguid: 0,
|
|
100
|
-
version:
|
|
101
|
+
version: "11.2.1",
|
|
101
102
|
},
|
|
102
|
-
format:
|
|
103
|
+
format: "songlist",
|
|
103
104
|
};
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -108,16 +109,16 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
108
109
|
*/
|
|
109
110
|
playlist(id) {
|
|
110
111
|
return {
|
|
111
|
-
method:
|
|
112
|
-
url:
|
|
112
|
+
method: "GET",
|
|
113
|
+
url: "http://musicapi.taihe.com/v1/restserver/ting",
|
|
113
114
|
body: {
|
|
114
|
-
from:
|
|
115
|
-
method:
|
|
115
|
+
from: "qianqianmini",
|
|
116
|
+
method: "baidu.ting.diy.gedanInfo",
|
|
116
117
|
listid: id,
|
|
117
|
-
platform:
|
|
118
|
-
version:
|
|
118
|
+
platform: "darwin",
|
|
119
|
+
version: "11.2.1",
|
|
119
120
|
},
|
|
120
|
-
format:
|
|
121
|
+
format: "content",
|
|
121
122
|
};
|
|
122
123
|
}
|
|
123
124
|
|
|
@@ -126,18 +127,18 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
126
127
|
*/
|
|
127
128
|
url(id, br = 320) {
|
|
128
129
|
return {
|
|
129
|
-
method:
|
|
130
|
-
url:
|
|
130
|
+
method: "GET",
|
|
131
|
+
url: "http://musicapi.taihe.com/v1/restserver/ting",
|
|
131
132
|
body: {
|
|
132
|
-
from:
|
|
133
|
-
method:
|
|
133
|
+
from: "qianqianmini",
|
|
134
|
+
method: "baidu.ting.song.getInfos",
|
|
134
135
|
songid: id,
|
|
135
136
|
res: 1,
|
|
136
|
-
platform:
|
|
137
|
-
version:
|
|
137
|
+
platform: "darwin",
|
|
138
|
+
version: "1.0.0",
|
|
138
139
|
},
|
|
139
|
-
encode:
|
|
140
|
-
decode:
|
|
140
|
+
encode: "baidu_AESCBC",
|
|
141
|
+
decode: "baidu_url",
|
|
141
142
|
};
|
|
142
143
|
}
|
|
143
144
|
|
|
@@ -146,16 +147,16 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
146
147
|
*/
|
|
147
148
|
lyric(id) {
|
|
148
149
|
return {
|
|
149
|
-
method:
|
|
150
|
-
url:
|
|
150
|
+
method: "GET",
|
|
151
|
+
url: "http://musicapi.taihe.com/v1/restserver/ting",
|
|
151
152
|
body: {
|
|
152
|
-
from:
|
|
153
|
-
method:
|
|
153
|
+
from: "qianqianmini",
|
|
154
|
+
method: "baidu.ting.song.lry",
|
|
154
155
|
songid: id,
|
|
155
|
-
platform:
|
|
156
|
-
version:
|
|
156
|
+
platform: "darwin",
|
|
157
|
+
version: "1.0.0",
|
|
157
158
|
},
|
|
158
|
-
decode:
|
|
159
|
+
decode: "baidu_lyric",
|
|
159
160
|
};
|
|
160
161
|
}
|
|
161
162
|
|
|
@@ -178,12 +179,12 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
178
179
|
return {
|
|
179
180
|
id: data.song_id,
|
|
180
181
|
name: data.title,
|
|
181
|
-
artist: data.author ? data.author.split(
|
|
182
|
-
album: data.album_title ||
|
|
182
|
+
artist: data.author ? data.author.split(",") : [],
|
|
183
|
+
album: data.album_title || "",
|
|
183
184
|
pic_id: data.song_id,
|
|
184
185
|
url_id: data.song_id,
|
|
185
186
|
lyric_id: data.song_id,
|
|
186
|
-
source:
|
|
187
|
+
source: "baidu",
|
|
187
188
|
};
|
|
188
189
|
}
|
|
189
190
|
|
|
@@ -191,16 +192,16 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
191
192
|
* 处理百度音乐的编码/解码逻辑
|
|
192
193
|
*/
|
|
193
194
|
async handleEncode(api) {
|
|
194
|
-
if (api.encode ===
|
|
195
|
+
if (api.encode === "baidu_AESCBC") {
|
|
195
196
|
return this.aesEncrypt(api);
|
|
196
197
|
}
|
|
197
198
|
return api;
|
|
198
199
|
}
|
|
199
200
|
|
|
200
201
|
async handleDecode(decodeType, data) {
|
|
201
|
-
if (decodeType ===
|
|
202
|
+
if (decodeType === "baidu_url") {
|
|
202
203
|
return this.urlDecode(data);
|
|
203
|
-
} else if (decodeType ===
|
|
204
|
+
} else if (decodeType === "baidu_lyric") {
|
|
204
205
|
return this.lyricDecode(data);
|
|
205
206
|
}
|
|
206
207
|
return data;
|
|
@@ -210,18 +211,18 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
210
211
|
* 百度音乐 AES 加密
|
|
211
212
|
*/
|
|
212
213
|
async aesEncrypt(api) {
|
|
213
|
-
const key =
|
|
214
|
-
const vi =
|
|
215
|
-
|
|
214
|
+
const key = "DBEECF8C50FD160E";
|
|
215
|
+
const vi = "1231021386755796";
|
|
216
|
+
|
|
216
217
|
const data = `songid=${api.body.songid}&ts=${Date.now()}`;
|
|
217
|
-
|
|
218
|
-
const cipher = crypto.createCipheriv(
|
|
218
|
+
|
|
219
|
+
const cipher = crypto.createCipheriv("aes-128-cbc", key, vi);
|
|
219
220
|
cipher.setAutoPadding(true);
|
|
220
|
-
let encrypted = cipher.update(data,
|
|
221
|
-
encrypted += cipher.final(
|
|
222
|
-
|
|
221
|
+
let encrypted = cipher.update(data, "utf8", "base64");
|
|
222
|
+
encrypted += cipher.final("base64");
|
|
223
|
+
|
|
223
224
|
api.body.e = encrypted;
|
|
224
|
-
|
|
225
|
+
|
|
225
226
|
return api;
|
|
226
227
|
}
|
|
227
228
|
|
|
@@ -230,27 +231,27 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
230
231
|
*/
|
|
231
232
|
urlDecode(result) {
|
|
232
233
|
const data = JSON.parse(result);
|
|
233
|
-
|
|
234
|
+
|
|
234
235
|
let maxBr = 0;
|
|
235
236
|
let url;
|
|
236
|
-
|
|
237
|
-
data.songurl.url.forEach(item => {
|
|
237
|
+
|
|
238
|
+
data.songurl.url.forEach((item) => {
|
|
238
239
|
if (item.file_bitrate <= this.meting.temp.br && item.file_bitrate > maxBr) {
|
|
239
240
|
maxBr = item.file_bitrate;
|
|
240
241
|
url = {
|
|
241
242
|
url: item.file_link,
|
|
242
|
-
br: item.file_bitrate
|
|
243
|
+
br: item.file_bitrate,
|
|
243
244
|
};
|
|
244
245
|
}
|
|
245
246
|
});
|
|
246
|
-
|
|
247
|
+
|
|
247
248
|
if (!url) {
|
|
248
249
|
url = {
|
|
249
|
-
url:
|
|
250
|
-
br: -1
|
|
250
|
+
url: "",
|
|
251
|
+
br: -1,
|
|
251
252
|
};
|
|
252
253
|
}
|
|
253
|
-
|
|
254
|
+
|
|
254
255
|
return JSON.stringify(url);
|
|
255
256
|
}
|
|
256
257
|
|
|
@@ -260,10 +261,10 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
260
261
|
lyricDecode(result) {
|
|
261
262
|
const data = JSON.parse(result);
|
|
262
263
|
const lyricData = {
|
|
263
|
-
lyric: data.lrcContent ||
|
|
264
|
-
tlyric:
|
|
264
|
+
lyric: data.lrcContent || "",
|
|
265
|
+
tlyric: "",
|
|
265
266
|
};
|
|
266
|
-
|
|
267
|
+
|
|
267
268
|
return JSON.stringify(lyricData);
|
|
268
269
|
}
|
|
269
270
|
|
|
@@ -273,8 +274,9 @@ export default class BaiduProvider extends BaseProvider {
|
|
|
273
274
|
* 生成随机十六进制字符串
|
|
274
275
|
*/
|
|
275
276
|
_getRandomHex(length) {
|
|
276
|
-
return crypto
|
|
277
|
-
.
|
|
277
|
+
return crypto
|
|
278
|
+
.randomBytes(Math.ceil(length / 2))
|
|
279
|
+
.toString("hex")
|
|
278
280
|
.slice(0, length);
|
|
279
281
|
}
|
|
280
|
-
}
|
|
282
|
+
}
|
package/src/providers/base.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
export default class BaseProvider {
|
|
6
6
|
constructor(meting) {
|
|
7
7
|
this.meting = meting;
|
|
8
|
-
this.name =
|
|
8
|
+
this.name = "base";
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -134,9 +134,9 @@ export default class BaseProvider {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
// 处理 GET 请求的参数
|
|
137
|
-
if (api.method ===
|
|
137
|
+
if (api.method === "GET" && api.body) {
|
|
138
138
|
const params = new URLSearchParams(api.body);
|
|
139
|
-
api.url +=
|
|
139
|
+
api.url += "?" + params.toString();
|
|
140
140
|
api.body = null;
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -156,7 +156,7 @@ export default class BaseProvider {
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
// 如果有格式化规则,进行数据清理
|
|
159
|
-
if (
|
|
159
|
+
if ("format" in api) {
|
|
160
160
|
data = this.cleanData(data, api.format, meting);
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -181,9 +181,9 @@ export default class BaseProvider {
|
|
|
181
181
|
*/
|
|
182
182
|
async handleDecode(decodeType, data) {
|
|
183
183
|
// 根据解码类型调用相应的方法
|
|
184
|
-
if (decodeType.includes(
|
|
184
|
+
if (decodeType.includes("url")) {
|
|
185
185
|
return this.urlDecode(data);
|
|
186
|
-
} else if (decodeType.includes(
|
|
186
|
+
} else if (decodeType.includes("lyric")) {
|
|
187
187
|
return this.lyricDecode(data);
|
|
188
188
|
}
|
|
189
189
|
return data;
|
|
@@ -208,7 +208,7 @@ export default class BaseProvider {
|
|
|
208
208
|
data = this.pickupData(data, rule);
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
if (!Array.isArray(data) && typeof data ===
|
|
211
|
+
if (!Array.isArray(data) && typeof data === "object" && data !== null) {
|
|
212
212
|
data = [data];
|
|
213
213
|
}
|
|
214
214
|
|
|
@@ -217,8 +217,8 @@ export default class BaseProvider {
|
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
// 使用当前 provider 的格式化方法
|
|
220
|
-
if (typeof this.format ===
|
|
221
|
-
const result = data.map(item => this.format(item));
|
|
220
|
+
if (typeof this.format === "function") {
|
|
221
|
+
const result = data.map((item) => this.format(item));
|
|
222
222
|
return JSON.stringify(result);
|
|
223
223
|
}
|
|
224
224
|
|
|
@@ -232,16 +232,16 @@ export default class BaseProvider {
|
|
|
232
232
|
* @returns {Object} 提取后的数据
|
|
233
233
|
*/
|
|
234
234
|
pickupData(array, rule) {
|
|
235
|
-
const parts = rule.split(
|
|
235
|
+
const parts = rule.split(".");
|
|
236
236
|
let result = array;
|
|
237
|
-
|
|
237
|
+
|
|
238
238
|
for (const part of parts) {
|
|
239
|
-
if (!result || typeof result !==
|
|
239
|
+
if (!result || typeof result !== "object" || !(part in result)) {
|
|
240
240
|
return {};
|
|
241
241
|
}
|
|
242
242
|
result = result[part];
|
|
243
243
|
}
|
|
244
|
-
|
|
244
|
+
|
|
245
245
|
return result;
|
|
246
246
|
}
|
|
247
247
|
}
|
package/src/providers/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import NeteaseProvider from
|
|
2
|
-
import TencentProvider from
|
|
3
|
-
import KugouProvider from
|
|
4
|
-
import BaiduProvider from
|
|
5
|
-
import KuwoProvider from
|
|
1
|
+
import NeteaseProvider from "./netease.js";
|
|
2
|
+
import TencentProvider from "./tencent.js";
|
|
3
|
+
import KugouProvider from "./kugou.js";
|
|
4
|
+
import BaiduProvider from "./baidu.js";
|
|
5
|
+
import KuwoProvider from "./kuwo.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* 音乐平台提供者工厂
|
|
@@ -13,7 +13,7 @@ export default class ProviderFactory {
|
|
|
13
13
|
tencent: TencentProvider,
|
|
14
14
|
kugou: KugouProvider,
|
|
15
15
|
baidu: BaiduProvider,
|
|
16
|
-
kuwo: KuwoProvider
|
|
16
|
+
kuwo: KuwoProvider,
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -46,4 +46,4 @@ export default class ProviderFactory {
|
|
|
46
46
|
static isSupported(platform) {
|
|
47
47
|
return platform in this.providers;
|
|
48
48
|
}
|
|
49
|
-
}
|
|
49
|
+
}
|