koishi-plugin-video-parser-all 0.4.4 → 0.4.5

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/lib/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { Schema, Dict } from 'koishi';
2
2
  export declare const name = "video-parser-all";
3
3
  export declare const Config: Schema<{
4
4
  enable?: boolean | null | undefined;
5
+ autoParse?: boolean | null | undefined;
5
6
  botName?: string | null | undefined;
6
7
  showWaitingTip?: boolean | null | undefined;
7
8
  waitingTipText?: string | null | undefined;
@@ -72,6 +73,7 @@ export declare const Config: Schema<{
72
73
  } & Dict) | null | undefined;
73
74
  }, {
74
75
  enable: boolean;
76
+ autoParse: boolean;
75
77
  botName: string;
76
78
  showWaitingTip: boolean;
77
79
  waitingTipText: string;
package/lib/index.js CHANGED
@@ -12,10 +12,33 @@ const fs_1 = __importDefault(require("fs"));
12
12
  const path_1 = __importDefault(require("path"));
13
13
  const promises_1 = require("stream/promises");
14
14
  const worker_threads_1 = require("worker_threads");
15
+ // 先定义 API_CONFIG,以便在 Config 中使用
16
+ const API_CONFIG = {
17
+ universal: 'https://api.bugpk.com/api/short_videos ',
18
+ xingzhige: {
19
+ bilibili: { url: 'https://api.xingzhige.com/API/b_parse/ ', vidUrl: 'https://api.xingzhige.com/API/b_parse/ ', bangumiUrl: 'https://api.xingzhige.com/API/b_bangumi/ ' },
20
+ kuaishou: { url: 'https://api.xingzhige.com/API/kuaishou/ ' },
21
+ douyin: { url: 'https://api.xingzhige.com/API/douyin/ ' },
22
+ xigua: { url: 'https://api.xingzhige.com/API/xigua/ ' }
23
+ },
24
+ platform: {
25
+ bilibili: ['https://api.bugpk.com/api/bilibili '],
26
+ kuaishou: ['https://api.bugpk.com/api/ksjx ', 'https://api.bugpk.com/api/kuaishou ', 'https://api.bugpk.com/api/ksimg ', 'https://api.suyanw.cn/api/kuaishou.php '],
27
+ xiaohongshu: ['https://api.bugpk.com/api/xhsjx ', 'https://api.bugpk.com/api/xhsimg ', 'https://api.bugpk.com/api/xhslive '],
28
+ weibo: ['https://api.bugpk.com/api/weibo ', 'https://api.bugpk.com/api/weibo_v '],
29
+ toutiao: ['https://api.bugpk.com/api/toutiao '],
30
+ pipigx: ['https://api.bugpk.com/api/pipigx ', 'https://api.suyanw.cn/api/pipigx.php '],
31
+ pipixia: ['https://api.bugpk.com/api/pipixia '],
32
+ douyin: ['https://api.bugpk.com/api/douyin ', 'https://api.bugpk.com/api/dyjx ', 'https://api.bugpk.com/api/dylive '],
33
+ zuiyou: ['https://api.suyanw.cn/api/zuiyou.php '],
34
+ xigua: ['https://api.bugpk.com/api/toutiao ']
35
+ }
36
+ };
15
37
  exports.name = 'video-parser-all';
16
38
  exports.Config = koishi_1.Schema.intersect([
17
39
  koishi_1.Schema.object({
18
40
  enable: koishi_1.Schema.boolean().default(true).description('是否启用视频解析插件'),
41
+ autoParse: koishi_1.Schema.boolean().default(true).description('是否自动解析消息中的视频链接(关闭后需手动使用 parse 命令解析)'),
19
42
  botName: koishi_1.Schema.string().default('视频解析机器人').description('机器人显示名称'),
20
43
  showWaitingTip: koishi_1.Schema.boolean().default(true).description('解析时显示等待提示'),
21
44
  waitingTipText: koishi_1.Schema.string().default('正在解析视频,请稍候...').description('等待提示文本内容'),
@@ -36,7 +59,7 @@ exports.Config = koishi_1.Schema.intersect([
36
59
  pipigx: koishi_1.Schema.boolean().default(true).description('皮皮搞笑'),
37
60
  pipixia: koishi_1.Schema.boolean().default(true).description('皮皮虾'),
38
61
  zuiyou: koishi_1.Schema.boolean().default(true).description('最右'),
39
- }).description('启用平台(勾选即开启对应平台解析)')
62
+ }).description('平台开关')
40
63
  }).description('平台开关'),
41
64
  koishi_1.Schema.object({
42
65
  platformFormat: koishi_1.Schema.object({
@@ -83,16 +106,51 @@ exports.Config = koishi_1.Schema.intersect([
83
106
  }).description('缓存清理设置'),
84
107
  koishi_1.Schema.object({
85
108
  preferredApi: koishi_1.Schema.object({
86
- bilibili: koishi_1.Schema.union(['xingzhige', 'universal', 'platform', 'official']).default('xingzhige').description('B站首选解析源'),
87
- douyin: koishi_1.Schema.union(['xingzhige', 'universal', 'platform']).default('xingzhige').description('抖音首选解析源'),
88
- kuaishou: koishi_1.Schema.union(['xingzhige', 'universal', 'platform']).default('xingzhige').description('快手首选解析源'),
89
- xigua: koishi_1.Schema.union(['xingzhige', 'universal', 'platform']).default('xingzhige').description('西瓜视频首选解析源'),
90
- xiaohongshu: koishi_1.Schema.union(['universal', 'platform']).default('universal').description('小红书首选解析源'),
91
- weibo: koishi_1.Schema.union(['universal', 'platform']).default('universal').description('微博首选解析源'),
92
- toutiao: koishi_1.Schema.union(['universal', 'platform']).default('universal').description('今日头条首选解析源'),
93
- pipigx: koishi_1.Schema.union(['universal', 'platform']).default('universal').description('皮皮搞笑首选解析源'),
94
- pipixia: koishi_1.Schema.union(['universal', 'platform']).default('universal').description('皮皮虾首选解析源'),
95
- zuiyou: koishi_1.Schema.union(['universal', 'platform']).default('universal').description('最右首选解析源'),
109
+ bilibili: koishi_1.Schema.union([
110
+ 'xingzhige',
111
+ 'universal',
112
+ 'platform',
113
+ 'official'
114
+ ]).default('xingzhige').description(`B站首选解析源\n平台内置API列表:\n${(API_CONFIG.platform.bilibili || []).map(url => url.trim()).join('\n')}`),
115
+ douyin: koishi_1.Schema.union([
116
+ 'xingzhige',
117
+ 'universal',
118
+ 'platform'
119
+ ]).default('xingzhige').description(`抖音首选解析源\n平台内置API列表:\n${(API_CONFIG.platform.douyin || []).map(url => url.trim()).join('\n')}`),
120
+ kuaishou: koishi_1.Schema.union([
121
+ 'xingzhige',
122
+ 'universal',
123
+ 'platform'
124
+ ]).default('xingzhige').description(`快手首选解析源\n平台内置API列表:\n${(API_CONFIG.platform.kuaishou || []).map(url => url.trim()).join('\n')}`),
125
+ xigua: koishi_1.Schema.union([
126
+ 'xingzhige',
127
+ 'universal',
128
+ 'platform'
129
+ ]).default('xingzhige').description(`西瓜视频首选解析源\n平台内置API列表:\n${(API_CONFIG.platform.xigua || []).map(url => url.trim()).join('\n')}`),
130
+ xiaohongshu: koishi_1.Schema.union([
131
+ 'universal',
132
+ 'platform'
133
+ ]).default('universal').description(`小红书首选解析源\n平台内置API列表:\n${(API_CONFIG.platform.xiaohongshu || []).map(url => url.trim()).join('\n')}`),
134
+ weibo: koishi_1.Schema.union([
135
+ 'universal',
136
+ 'platform'
137
+ ]).default('universal').description(`微博首选解析源\n平台内置API列表:\n${(API_CONFIG.platform.weibo || []).map(url => url.trim()).join('\n')}`),
138
+ toutiao: koishi_1.Schema.union([
139
+ 'universal',
140
+ 'platform'
141
+ ]).default('universal').description(`今日头条首选解析源\n平台内置API列表:\n${(API_CONFIG.platform.toutiao || []).map(url => url.trim()).join('\n')}`),
142
+ pipigx: koishi_1.Schema.union([
143
+ 'universal',
144
+ 'platform'
145
+ ]).default('universal').description(`皮皮搞笑首选解析源\n平台内置API列表:\n${(API_CONFIG.platform.pipigx || []).map(url => url.trim()).join('\n')}`),
146
+ pipixia: koishi_1.Schema.union([
147
+ 'universal',
148
+ 'platform'
149
+ ]).default('universal').description(`皮皮虾首选解析源\n平台内置API列表:\n${(API_CONFIG.platform.pipixia || []).map(url => url.trim()).join('\n')}`),
150
+ zuiyou: koishi_1.Schema.union([
151
+ 'universal',
152
+ 'platform'
153
+ ]).default('universal').description(`最右首选解析源\n平台内置API列表:\n${(API_CONFIG.platform.zuiyou || []).map(url => url.trim()).join('\n')}`),
96
154
  }).description('首选解析源设置(将优先尝试用户选择的API,失败后自动尝试其他)')
97
155
  }).description('API选择设置'),
98
156
  ]);
@@ -161,27 +219,6 @@ const PLATFORM_KEYWORDS = {
161
219
  xigua: ['ixigua', '西瓜视频', 'xigua.com', '699pic.com', 'ixigua.com/video', 'ixigua.com/album'],
162
220
  universal_card: ['mini_program', '小程序卡片', 'lightapp', 'json', 'markdown', 'share', 'contact', 'location', 'music', 'forward', 'node', 'mface', 'file']
163
221
  };
164
- const API_CONFIG = {
165
- universal: 'https://api.bugpk.com/api/short_videos ',
166
- xingzhige: {
167
- bilibili: { url: 'https://api.xingzhige.com/API/b_parse/ ', vidUrl: 'https://api.xingzhige.com/API/b_parse/ ', bangumiUrl: 'https://api.xingzhige.com/API/b_bangumi/ ' },
168
- kuaishou: { url: 'https://api.xingzhige.com/API/kuaishou/ ' },
169
- douyin: { url: 'https://api.xingzhige.com/API/douyin/ ' },
170
- xigua: { url: 'https://api.xingzhige.com/API/xigua/ ' }
171
- },
172
- platform: {
173
- bilibili: ['https://api.bugpk.com/api/bilibili '],
174
- kuaishou: ['https://api.bugpk.com/api/ksjx ', 'https://api.bugpk.com/api/kuaishou ', 'https://api.bugpk.com/api/ksimg ', 'https://api.suyanw.cn/api/kuaishou.php '],
175
- xiaohongshu: ['https://api.bugpk.com/api/xhsjx ', 'https://api.bugpk.com/api/xhsimg ', 'https://api.bugpk.com/api/xhslive '],
176
- weibo: ['https://api.bugpk.com/api/weibo ', 'https://api.bugpk.com/api/weibo_v '],
177
- toutiao: ['https://api.bugpk.com/api/toutiao '],
178
- pipigx: ['https://api.bugpk.com/api/pipigx ', 'https://api.suyanw.cn/api/pipigx.php '],
179
- pipixia: ['https://api.bugpk.com/api/pipixia '],
180
- douyin: ['https://api.bugpk.com/api/douyin ', 'https://api.bugpk.com/api/dyjx ', 'https://api.bugpk.com/api/dylive '],
181
- zuiyou: ['https://api.suyanw.cn/api/zuiyou.php '],
182
- xigua: ['https://api.bugpk.com/api/toutiao ']
183
- }
184
- };
185
222
  function vid_type_parse(id) {
186
223
  const idRegex = [
187
224
  { pattern: /av([0-9]+)/i, type: "av" },
@@ -516,6 +553,9 @@ function parseData(data, maxDescLength, platform) {
516
553
  let type = data.type || 'video';
517
554
  let title = data.title || data.desc || '无标题';
518
555
  let author = data.author || data.name || '未知作者';
556
+ if (author && typeof author === 'object') {
557
+ author = author.name || author.nickname || author.username || '未知作者';
558
+ }
519
559
  let desc = (data.desc || data.description || title).slice(0, maxDescLength);
520
560
  let cover = data.cover || data.imgurl || data.pic || data.fm || '';
521
561
  let images = data.images || [];
@@ -631,7 +671,6 @@ function apply(ctx, config) {
631
671
  }
632
672
  if (platform === 'bilibili') {
633
673
  const preferred = config.preferredApi?.bilibili || 'xingzhige';
634
- // 根据首选源构建尝试顺序
635
674
  const tryOrder = [];
636
675
  if (preferred === 'xingzhige') {
637
676
  tryOrder.push('xingzhige_vid', 'xingzhige_bangumi', 'universal', 'official', 'platform');
@@ -1225,7 +1264,6 @@ function apply(ctx, config) {
1225
1264
  }
1226
1265
  return { data: null, msg: '解析失败,请稍后重试' };
1227
1266
  }
1228
- // 其他平台(不应该走到这里)
1229
1267
  return { data: null, msg: '未知平台' };
1230
1268
  }
1231
1269
  async function processSingleUrl(session, url) {
@@ -1266,7 +1304,7 @@ function apply(ctx, config) {
1266
1304
  async function flush(session, manualUrls) {
1267
1305
  const key = `${session.platform}:${session.userId}:${session.channelId}`;
1268
1306
  const buffer = linkBuffer.get(key);
1269
- const urls = manualUrls || buffer?.urls || [];
1307
+ const urls = [...new Set(manualUrls || buffer?.urls || [])];
1270
1308
  if (buffer) {
1271
1309
  clearTimeout(buffer.timer);
1272
1310
  linkBuffer.delete(key);
@@ -1278,7 +1316,7 @@ function apply(ctx, config) {
1278
1316
  if (result.data) {
1279
1317
  items.push(result.data);
1280
1318
  }
1281
- else {
1319
+ else if (result.msg !== '请勿重复解析') {
1282
1320
  errs.push(`【${url.slice(0, 22)}...】:${result.msg}`);
1283
1321
  if (config.debug) {
1284
1322
  ctx.logger.debug(`解析失败: ${url}, 原因: ${result.msg}`);
@@ -1287,6 +1325,10 @@ function apply(ctx, config) {
1287
1325
  ctx.logger.error(`解析失败: ${url}, 原因: ${result.msg}`);
1288
1326
  }
1289
1327
  }
1328
+ else {
1329
+ if (config.debug)
1330
+ ctx.logger.debug(`忽略重复解析: ${url}`);
1331
+ }
1290
1332
  }
1291
1333
  if (errs.length) {
1292
1334
  ctx.logger.error(`解析失败数量: ${errs.length}, 示例: ${errs[0]}`);
@@ -1425,6 +1467,8 @@ function apply(ctx, config) {
1425
1467
  ctx.on('message', async (session) => {
1426
1468
  if (!config.enable)
1427
1469
  return;
1470
+ if (!config.autoParse)
1471
+ return;
1428
1472
  const content = session.content.trim();
1429
1473
  let urls = extractUrl(content);
1430
1474
  if (urls.length === 0 && hasPlatformKeyword(content)) {
@@ -1434,6 +1478,7 @@ function apply(ctx, config) {
1434
1478
  if (urls.length === 0)
1435
1479
  return;
1436
1480
  const key = `${session.platform}:${session.userId}:${session.channelId}`;
1481
+ urls = [...new Set(urls)];
1437
1482
  if (linkBuffer.has(key)) {
1438
1483
  const buffer = linkBuffer.get(key);
1439
1484
  const newUrls = urls.filter(url => !buffer.urls.includes(url));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-video-parser-all",
3
3
  "description": "Koishi 全平台视频解析插件,支持抖音/快手/B站/小红书/微博/今日头条/皮皮搞笑/皮皮虾/西瓜视频/最右视频链接解析",
4
- "version": "0.4.4",
4
+ "version": "0.4.5",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [