koishi-plugin-video-parser-all 1.0.0 → 1.0.2
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 +2 -0
- package/lib/index.js +53 -27
- package/package.json +1 -1
- package/readme.md +4 -3
package/lib/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare const Config: Schema<{
|
|
|
14
14
|
videoDownloadTimeout?: number | null | undefined;
|
|
15
15
|
tempDir?: string | null | undefined;
|
|
16
16
|
maxVideoSize?: number | null | undefined;
|
|
17
|
+
forceDownloadVideo?: boolean | null | undefined;
|
|
17
18
|
} & {
|
|
18
19
|
timeout?: number | null | undefined;
|
|
19
20
|
videoSendTimeout?: number | null | undefined;
|
|
@@ -44,6 +45,7 @@ export declare const Config: Schema<{
|
|
|
44
45
|
videoDownloadTimeout: number;
|
|
45
46
|
tempDir: string;
|
|
46
47
|
maxVideoSize: number;
|
|
48
|
+
forceDownloadVideo: boolean;
|
|
47
49
|
} & {
|
|
48
50
|
timeout: number;
|
|
49
51
|
videoSendTimeout: number;
|
package/lib/index.js
CHANGED
|
@@ -29,6 +29,7 @@ exports.Config = koishi_1.Schema.intersect([
|
|
|
29
29
|
videoDownloadTimeout: koishi_1.Schema.number().default(120000).description('视频下载超时(毫秒)'),
|
|
30
30
|
tempDir: koishi_1.Schema.string().default('./temp_videos').description('临时视频存储目录'),
|
|
31
31
|
maxVideoSize: koishi_1.Schema.number().min(0).step(1).default(0).description('最大下载视频大小(MB),0 为不限制大小'),
|
|
32
|
+
forceDownloadVideo: koishi_1.Schema.boolean().default(true).description('强制下载视频后发送(解决B站、小红书等平台URL无法直接发送的问题)'),
|
|
32
33
|
}).description('内容显示设置'),
|
|
33
34
|
koishi_1.Schema.object({
|
|
34
35
|
timeout: koishi_1.Schema.number().min(0).default(180000).description('API 请求超时(毫秒)'),
|
|
@@ -41,7 +42,7 @@ exports.Config = koishi_1.Schema.intersect([
|
|
|
41
42
|
retryInterval: koishi_1.Schema.number().min(0).default(1000).description('重试间隔(毫秒,同时用于消息发送重试)'),
|
|
42
43
|
}).description('错误与重试设置'),
|
|
43
44
|
koishi_1.Schema.object({
|
|
44
|
-
enableForward: koishi_1.Schema.boolean().default(false).description('启用合并转发(仅 OneBot
|
|
45
|
+
enableForward: koishi_1.Schema.boolean().default(false).description('启用合并转发(仅 OneBot 平台),视频会单独发送'),
|
|
45
46
|
}).description('发送方式设置'),
|
|
46
47
|
koishi_1.Schema.object({
|
|
47
48
|
waitingTipText: koishi_1.Schema.string().default('正在解析视频,请稍候...').description('解析等待提示'),
|
|
@@ -401,6 +402,19 @@ function getErrorMessage(error) {
|
|
|
401
402
|
return error.message;
|
|
402
403
|
return String(error);
|
|
403
404
|
}
|
|
405
|
+
function isSpecialPlatformVideo(url) {
|
|
406
|
+
const specialHosts = [
|
|
407
|
+
'bilibili.com',
|
|
408
|
+
'akamaized.net',
|
|
409
|
+
'hdslb.com',
|
|
410
|
+
'xiaohongshu.com',
|
|
411
|
+
'xhslink.com',
|
|
412
|
+
'zhihu.com',
|
|
413
|
+
'weibo.com',
|
|
414
|
+
'sinaimg.cn'
|
|
415
|
+
];
|
|
416
|
+
return specialHosts.some(host => url.includes(host));
|
|
417
|
+
}
|
|
404
418
|
function apply(ctx, config) {
|
|
405
419
|
debugEnabled = config.debug || false;
|
|
406
420
|
debugLog('INFO', '插件初始化开始');
|
|
@@ -514,23 +528,29 @@ function apply(ctx, config) {
|
|
|
514
528
|
async function sendVideoFile(session, videoUrl) {
|
|
515
529
|
if (!videoUrl)
|
|
516
530
|
throw new Error('视频链接为空');
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
return await sendWithTimeout(session, koishi_1.h.video(videoUrl));
|
|
520
|
-
}
|
|
521
|
-
catch (err) {
|
|
522
|
-
debugLog('ERROR', `直接发送URL失败,开始下载视频: ${getErrorMessage(err)}`);
|
|
523
|
-
let tempFilePath = null;
|
|
531
|
+
const shouldForceDownload = config.forceDownloadVideo || isSpecialPlatformVideo(videoUrl);
|
|
532
|
+
if (!shouldForceDownload) {
|
|
524
533
|
try {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
debugLog('INFO', `视频下载完成,发送本地文件: ${localFile}`);
|
|
528
|
-
return await sendWithTimeout(session, koishi_1.h.video(localFile));
|
|
534
|
+
debugLog('INFO', `尝试直接发送视频URL: ${videoUrl.substring(0, 100)}...`);
|
|
535
|
+
return await sendWithTimeout(session, koishi_1.h.video(videoUrl));
|
|
529
536
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
537
|
+
catch (err) {
|
|
538
|
+
debugLog('ERROR', `直接发送URL失败,开始下载视频: ${getErrorMessage(err)}`);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
debugLog('INFO', `检测到特殊平台视频,强制下载后发送: ${videoUrl.substring(0, 100)}...`);
|
|
543
|
+
}
|
|
544
|
+
let tempFilePath = null;
|
|
545
|
+
try {
|
|
546
|
+
tempFilePath = await downloadVideoFile(videoUrl, config.tempDir || './temp_videos', config.videoDownloadTimeout || 120000, config.maxVideoSize || 0);
|
|
547
|
+
const localFile = `file://${path_1.default.resolve(tempFilePath)}`;
|
|
548
|
+
debugLog('INFO', `视频下载完成,发送本地文件: ${localFile}`);
|
|
549
|
+
return await sendWithTimeout(session, koishi_1.h.video(localFile));
|
|
550
|
+
}
|
|
551
|
+
finally {
|
|
552
|
+
if (tempFilePath) {
|
|
553
|
+
promises_1.default.unlink(tempFilePath).catch(e => debugLog('WARN', `删除临时文件失败: ${e}`));
|
|
534
554
|
}
|
|
535
555
|
}
|
|
536
556
|
}
|
|
@@ -567,6 +587,7 @@ function apply(ctx, config) {
|
|
|
567
587
|
return;
|
|
568
588
|
const enableForward = config.enableForward && session.platform === 'onebot';
|
|
569
589
|
const botName = config.botName || '视频解析机器人';
|
|
590
|
+
const videoItems = [];
|
|
570
591
|
if (enableForward) {
|
|
571
592
|
const forwardMessages = [];
|
|
572
593
|
for (const item of items) {
|
|
@@ -584,6 +605,9 @@ function apply(ctx, config) {
|
|
|
584
605
|
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(imgUrl), botName));
|
|
585
606
|
}
|
|
586
607
|
}
|
|
608
|
+
if (p.video && config.showVideoFile && (p.type === 'video' || (p.type === 'live' && !p.live_photo?.length && !p.images?.length))) {
|
|
609
|
+
videoItems.push(p);
|
|
610
|
+
}
|
|
587
611
|
}
|
|
588
612
|
if (forwardMessages.length) {
|
|
589
613
|
const forwardMsg = (0, koishi_1.h)('message', { forward: true }, forwardMessages.slice(0, 100));
|
|
@@ -598,18 +622,15 @@ function apply(ctx, config) {
|
|
|
598
622
|
}
|
|
599
623
|
}
|
|
600
624
|
}
|
|
601
|
-
for (const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
try {
|
|
605
|
-
await sendVideoFile(session, p.video);
|
|
606
|
-
}
|
|
607
|
-
catch (err) {
|
|
608
|
-
debugLog('ERROR', `视频发送失败(降级发送链接): ${getErrorMessage(err)}`);
|
|
609
|
-
await sendWithTimeout(session, `视频链接:${p.video}`).catch(() => { });
|
|
610
|
-
}
|
|
611
|
-
await delay(500);
|
|
625
|
+
for (const p of videoItems) {
|
|
626
|
+
try {
|
|
627
|
+
await sendVideoFile(session, p.video);
|
|
612
628
|
}
|
|
629
|
+
catch (err) {
|
|
630
|
+
debugLog('ERROR', `视频发送失败(降级发送链接): ${getErrorMessage(err)}`);
|
|
631
|
+
await sendWithTimeout(session, `视频链接:${p.video}`).catch(() => { });
|
|
632
|
+
}
|
|
633
|
+
await delay(500);
|
|
613
634
|
}
|
|
614
635
|
}
|
|
615
636
|
else {
|
|
@@ -647,6 +668,11 @@ function apply(ctx, config) {
|
|
|
647
668
|
ctx.on('message', async (session) => {
|
|
648
669
|
if (!config.enable)
|
|
649
670
|
return;
|
|
671
|
+
// 修复:使用正确的小写subtype属性名
|
|
672
|
+
if (session.subtype === 'file_upload')
|
|
673
|
+
return;
|
|
674
|
+
if (session.elements?.some(elem => elem.type === 'file' || elem.type === 'folder'))
|
|
675
|
+
return;
|
|
650
676
|
const urls = extractAllUrlsFromMessage(session);
|
|
651
677
|
if (!urls.length)
|
|
652
678
|
return;
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
- 💬 所有提示文案均可自定义,适配多语言场景
|
|
13
13
|
- 🔁 消息发送支持自动重试,与API重试配置联动,增强稳定性
|
|
14
14
|
- 🚀 内置内存缓存,避免短时间内重复解析同一链接;并发控制,防止资源耗尽
|
|
15
|
-
- ⚡
|
|
15
|
+
- ⚡ 智能视频发送策略:普通平台优先直接发送URL,特殊平台自动降级为本地文件发送
|
|
16
16
|
- 🛡️ 可选视频大小限制,防止超大文件占满服务器磁盘;自动清理所有临时文件
|
|
17
17
|
|
|
18
18
|
### English
|
|
@@ -25,7 +25,7 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
|
|
|
25
25
|
- 💬 All prompt texts are customizable for multilingual scenarios
|
|
26
26
|
- 🔁 Message sending supports automatic retries, linked with API retry configuration for improved stability
|
|
27
27
|
- 🚀 Built-in memory cache to avoid repeated parsing of the same URL; concurrency control to prevent resource exhaustion
|
|
28
|
-
- ⚡
|
|
28
|
+
- ⚡ Smart video sending strategy: priority to send URL directly for common platforms, auto downgrade to local file for special platforms
|
|
29
29
|
- 🛡️ Optional video size limit to prevent oversized files from filling up server disk; automatic cleanup of all temporary files
|
|
30
30
|
|
|
31
31
|
## 项目仓库 (Repository)
|
|
@@ -62,6 +62,7 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
|
|
|
62
62
|
| `videoDownloadTimeout` | number | 120000 | 视频下载超时(毫秒) |
|
|
63
63
|
| `tempDir` | string | `./temp_videos` | 临时视频存储目录 |
|
|
64
64
|
| `maxVideoSize` | number | 0 | 最大下载视频大小(MB),0 为不限制大小 |
|
|
65
|
+
| `forceDownloadVideo` | boolean | true | 强制下载视频后发送(解决B站、小红书等平台URL无法直接发送的问题) |
|
|
65
66
|
|
|
66
67
|
### 网络与 API 设置
|
|
67
68
|
| 配置项 | 类型 | 默认值 | 说明 |
|
|
@@ -80,7 +81,7 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
|
|
|
80
81
|
### 发送方式设置
|
|
81
82
|
| 配置项 | 类型 | 默认值 | 说明 |
|
|
82
83
|
|--------|------|--------|------|
|
|
83
|
-
| `enableForward` | boolean | false | 是否启用合并转发(仅 OneBot
|
|
84
|
+
| `enableForward` | boolean | false | 是否启用合并转发(仅 OneBot 平台),视频会单独发送 |
|
|
84
85
|
|
|
85
86
|
### 界面文字设置
|
|
86
87
|
| 配置项 | 类型 | 默认值 | 说明 |
|