koishi-plugin-video-parser-all 0.4.7 → 0.4.9

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.
Files changed (3) hide show
  1. package/lib/index.d.ts +12 -15
  2. package/lib/index.js +210 -212
  3. package/package.json +2 -2
package/lib/index.d.ts CHANGED
@@ -1,8 +1,7 @@
1
- import { Schema } from 'koishi';
1
+ import { Schema, Context } 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
- debug?: boolean | null | undefined;
6
5
  autoParse?: boolean | null | undefined;
7
6
  enableBvAvParse?: boolean | null | undefined;
8
7
  botName?: string | null | undefined;
@@ -12,12 +11,13 @@ export declare const Config: Schema<{
12
11
  maxVideoSize?: number | null | undefined;
13
12
  downloadThreads?: number | null | undefined;
14
13
  enableApiSelection?: boolean | null | undefined;
14
+ debugMode?: boolean | null | undefined;
15
+ logLevel?: "info" | "warn" | "error" | "debug" | null | undefined;
15
16
  } & import("cosmokit").Dict & {
16
17
  platformEnable?: ({
17
18
  bilibili?: boolean | null | undefined;
18
19
  douyin?: boolean | null | undefined;
19
20
  kuaishou?: boolean | null | undefined;
20
- xigua?: boolean | null | undefined;
21
21
  xiaohongshu?: boolean | null | undefined;
22
22
  weibo?: boolean | null | undefined;
23
23
  toutiao?: boolean | null | undefined;
@@ -53,10 +53,9 @@ export declare const Config: Schema<{
53
53
  } & import("cosmokit").Dict) | ({
54
54
  enableApiSelection?: true | null | undefined;
55
55
  preferredApi?: ({
56
- bilibili?: "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/b_parse/" | "https://api.bugpk.com/api/bilibili" | "https://api.xingzhige.com/API/b_video/" | "https://api.bilibili.com/x/web-interface/view" | null | undefined;
56
+ bilibili?: "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/b_parse/" | "https://api.bugpk.com/api/bilibili" | "https://api.bilibili.com/x/web-interface/view" | null | undefined;
57
57
  douyin?: "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/douyin/" | "https://api.bugpk.com/api/douyin" | "https://api.bugpk.com/api/dyjx" | "https://api.bugpk.com/api/dylive" | null | undefined;
58
- kuaishou?: "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/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" | null | undefined;
59
- xigua?: "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/xigua/" | "https://api.bugpk.com/api/toutiao" | null | undefined;
58
+ kuaishou?: "https://api.bugpk.com/api/short_videos" | "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" | null | undefined;
60
59
  xiaohongshu?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/xhsjx" | "https://api.bugpk.com/api/xhsimg" | "https://api.bugpk.com/api/xhslive" | "https://api.bugpk.com/api/xhs" | null | undefined;
61
60
  weibo?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo" | "https://api.bugpk.com/api/weibo_v" | null | undefined;
62
61
  toutiao?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/toutiao" | null | undefined;
@@ -66,7 +65,6 @@ export declare const Config: Schema<{
66
65
  } & import("cosmokit").Dict) | null | undefined;
67
66
  } & import("cosmokit").Dict))))), {
68
67
  enable: boolean;
69
- debug: boolean;
70
68
  autoParse: boolean;
71
69
  enableBvAvParse: boolean;
72
70
  botName: string;
@@ -76,12 +74,13 @@ export declare const Config: Schema<{
76
74
  maxVideoSize: number;
77
75
  downloadThreads: number;
78
76
  enableApiSelection: boolean;
77
+ debugMode: boolean;
78
+ logLevel: "info" | "warn" | "error" | "debug";
79
79
  } & import("cosmokit").Dict & {
80
80
  platformEnable: Schemastery.ObjectT<{
81
81
  bilibili: Schema<boolean, boolean>;
82
82
  douyin: Schema<boolean, boolean>;
83
83
  kuaishou: Schema<boolean, boolean>;
84
- xigua: Schema<boolean, boolean>;
85
84
  xiaohongshu: Schema<boolean, boolean>;
86
85
  weibo: Schema<boolean, boolean>;
87
86
  toutiao: Schema<boolean, boolean>;
@@ -117,10 +116,9 @@ export declare const Config: Schema<{
117
116
  }> | Schemastery.ObjectT<{
118
117
  enableApiSelection: Schema<true, true>;
119
118
  preferredApi: Schema<Schemastery.ObjectS<{
120
- bilibili: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/b_parse/" | "https://api.bugpk.com/api/bilibili" | "https://api.xingzhige.com/API/b_video/" | "https://api.bilibili.com/x/web-interface/view", "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/b_parse/" | "https://api.bugpk.com/api/bilibili" | "https://api.xingzhige.com/API/b_video/" | "https://api.bilibili.com/x/web-interface/view">;
119
+ bilibili: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/b_parse/" | "https://api.bugpk.com/api/bilibili" | "https://api.bilibili.com/x/web-interface/view", "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/b_parse/" | "https://api.bugpk.com/api/bilibili" | "https://api.bilibili.com/x/web-interface/view">;
121
120
  douyin: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/douyin/" | "https://api.bugpk.com/api/douyin" | "https://api.bugpk.com/api/dyjx" | "https://api.bugpk.com/api/dylive", "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/douyin/" | "https://api.bugpk.com/api/douyin" | "https://api.bugpk.com/api/dyjx" | "https://api.bugpk.com/api/dylive">;
122
- kuaishou: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/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", "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/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">;
123
- xigua: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/xigua/" | "https://api.bugpk.com/api/toutiao", "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/xigua/" | "https://api.bugpk.com/api/toutiao">;
121
+ kuaishou: Schema<"https://api.bugpk.com/api/short_videos" | "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", "https://api.bugpk.com/api/short_videos" | "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">;
124
122
  xiaohongshu: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/xhsjx" | "https://api.bugpk.com/api/xhsimg" | "https://api.bugpk.com/api/xhslive" | "https://api.bugpk.com/api/xhs", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/xhsjx" | "https://api.bugpk.com/api/xhsimg" | "https://api.bugpk.com/api/xhslive" | "https://api.bugpk.com/api/xhs">;
125
123
  weibo: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo" | "https://api.bugpk.com/api/weibo_v", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo" | "https://api.bugpk.com/api/weibo_v">;
126
124
  toutiao: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/toutiao", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/toutiao">;
@@ -128,10 +126,9 @@ export declare const Config: Schema<{
128
126
  pipixia: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipixia", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipixia">;
129
127
  zuiyou: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/zuiyou" | "https://api.suyanw.cn/api/zuiyou.php", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/zuiyou" | "https://api.suyanw.cn/api/zuiyou.php">;
130
128
  }>, Schemastery.ObjectT<{
131
- bilibili: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/b_parse/" | "https://api.bugpk.com/api/bilibili" | "https://api.xingzhige.com/API/b_video/" | "https://api.bilibili.com/x/web-interface/view", "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/b_parse/" | "https://api.bugpk.com/api/bilibili" | "https://api.xingzhige.com/API/b_video/" | "https://api.bilibili.com/x/web-interface/view">;
129
+ bilibili: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/b_parse/" | "https://api.bugpk.com/api/bilibili" | "https://api.bilibili.com/x/web-interface/view", "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/b_parse/" | "https://api.bugpk.com/api/bilibili" | "https://api.bilibili.com/x/web-interface/view">;
132
130
  douyin: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/douyin/" | "https://api.bugpk.com/api/douyin" | "https://api.bugpk.com/api/dyjx" | "https://api.bugpk.com/api/dylive", "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/douyin/" | "https://api.bugpk.com/api/douyin" | "https://api.bugpk.com/api/dyjx" | "https://api.bugpk.com/api/dylive">;
133
- kuaishou: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/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", "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/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">;
134
- xigua: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/xigua/" | "https://api.bugpk.com/api/toutiao", "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/xigua/" | "https://api.bugpk.com/api/toutiao">;
131
+ kuaishou: Schema<"https://api.bugpk.com/api/short_videos" | "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", "https://api.bugpk.com/api/short_videos" | "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">;
135
132
  xiaohongshu: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/xhsjx" | "https://api.bugpk.com/api/xhsimg" | "https://api.bugpk.com/api/xhslive" | "https://api.bugpk.com/api/xhs", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/xhsjx" | "https://api.bugpk.com/api/xhsimg" | "https://api.bugpk.com/api/xhslive" | "https://api.bugpk.com/api/xhs">;
136
133
  weibo: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo" | "https://api.bugpk.com/api/weibo_v", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo" | "https://api.bugpk.com/api/weibo_v">;
137
134
  toutiao: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/toutiao", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/toutiao">;
@@ -140,4 +137,4 @@ export declare const Config: Schema<{
140
137
  zuiyou: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/zuiyou" | "https://api.suyanw.cn/api/zuiyou.php", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/zuiyou" | "https://api.suyanw.cn/api/zuiyou.php">;
141
138
  }>>;
142
139
  }>))))>;
143
- export declare function apply(ctx: any, config: any): void;
140
+ export declare function apply(ctx: Context, config: any): void;
package/lib/index.js CHANGED
@@ -17,28 +17,24 @@ const API_CONFIG = {
17
17
  universal: 'https://api.bugpk.com/api/short_videos',
18
18
  xingzhige: {
19
19
  bilibili: 'https://api.xingzhige.com/API/b_parse/',
20
- kuaishou: 'https://api.xingzhige.com/API/kuaishou/',
21
- douyin: 'https://api.xingzhige.com/API/douyin/',
22
- xigua: 'https://api.xingzhige.com/API/xigua/'
20
+ douyin: 'https://api.xingzhige.com/API/douyin/'
23
21
  },
24
22
  platform: {
25
- bilibili: ['https://api.bugpk.com/api/bilibili', 'https://api.xingzhige.com/API/b_parse/', 'https://api.xingzhige.com/API/b_video/'],
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', 'https://api.xingzhige.com/API/kuaishou/'],
23
+ bilibili: ['https://api.bugpk.com/api/bilibili', 'https://api.xingzhige.com/API/b_parse/'],
24
+ 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
25
  xiaohongshu: ['https://api.bugpk.com/api/xhsjx', 'https://api.bugpk.com/api/xhsimg', 'https://api.bugpk.com/api/xhslive', 'https://api.bugpk.com/api/xhs'],
28
26
  weibo: ['https://api.bugpk.com/api/weibo', 'https://api.bugpk.com/api/weibo_v'],
29
27
  toutiao: ['https://api.bugpk.com/api/toutiao'],
30
28
  pipigx: ['https://api.bugpk.com/api/pipigx', 'https://api.suyanw.cn/api/pipigx.php'],
31
29
  pipixia: ['https://api.bugpk.com/api/pipixia'],
32
30
  douyin: ['https://api.bugpk.com/api/douyin', 'https://api.bugpk.com/api/dyjx', 'https://api.bugpk.com/api/dylive', 'https://api.xingzhige.com/API/douyin/'],
33
- zuiyou: ['https://api.bugpk.com/api/zuiyou', 'https://api.suyanw.cn/api/zuiyou.php'],
34
- xigua: ['https://api.bugpk.com/api/toutiao', 'https://api.xingzhige.com/API/xigua/']
31
+ zuiyou: ['https://api.bugpk.com/api/zuiyou', 'https://api.suyanw.cn/api/zuiyou.php']
35
32
  }
36
33
  };
37
34
  exports.name = 'video-parser-all';
38
35
  exports.Config = koishi_1.Schema.intersect([
39
36
  koishi_1.Schema.object({
40
37
  enable: koishi_1.Schema.boolean().default(true).description('是否启用视频解析插件'),
41
- debug: koishi_1.Schema.boolean().default(false).description('开启调试模式,输出详细日志'),
42
38
  autoParse: koishi_1.Schema.boolean().default(true).description('是否自动解析消息中的视频链接'),
43
39
  enableBvAvParse: koishi_1.Schema.boolean().default(true).description('是否解析独立的BV/AV号(如:BV1xx411c7mD)'),
44
40
  botName: koishi_1.Schema.string().default('视频解析机器人').description('机器人显示名称'),
@@ -48,13 +44,14 @@ exports.Config = koishi_1.Schema.intersect([
48
44
  maxVideoSize: koishi_1.Schema.number().min(0).default(50).description('允许发送的最大视频大小(MB)'),
49
45
  downloadThreads: koishi_1.Schema.number().min(0).default(4).description('视频下载线程数'),
50
46
  enableApiSelection: koishi_1.Schema.boolean().default(false).description('是否启用API选择设置(开启后可选择首选解析源)'),
47
+ debugMode: koishi_1.Schema.boolean().default(false).description('调试模式(输出详细日志)'),
48
+ logLevel: koishi_1.Schema.union(['info', 'warn', 'error', 'debug']).default('info').description('日志级别'),
51
49
  }).description('基础设置'),
52
50
  koishi_1.Schema.object({
53
51
  platformEnable: koishi_1.Schema.object({
54
52
  bilibili: koishi_1.Schema.boolean().default(true).description('B站'),
55
53
  douyin: koishi_1.Schema.boolean().default(true).description('抖音'),
56
54
  kuaishou: koishi_1.Schema.boolean().default(true).description('快手'),
57
- xigua: koishi_1.Schema.boolean().default(true).description('西瓜视频'),
58
55
  xiaohongshu: koishi_1.Schema.boolean().default(true).description('小红书'),
59
56
  weibo: koishi_1.Schema.boolean().default(true).description('微博'),
60
57
  toutiao: koishi_1.Schema.boolean().default(true).description('今日头条'),
@@ -64,7 +61,18 @@ exports.Config = koishi_1.Schema.intersect([
64
61
  }).description('平台开关')
65
62
  }).description('平台开关'),
66
63
  koishi_1.Schema.object({
67
- messageFormat: koishi_1.Schema.string().role('textarea').default('标题:${标题}\n作者:${作者}\n简介:${简介}\n时长:${视频时长}\n点赞:${点赞数}\n投币:${投币数}\n收藏:${收藏数}\n转发:${转发数}\n播放:${播放数}\n视频大小:${视频大小}MB').description('消息格式,可用变量:${标题}、${作者}、${简介}、${视频时长}、${点赞数}、${投币数}、${收藏数}、${转发数}、${播放数}、${视频大小}'),
64
+ messageFormat: koishi_1.Schema.string().role('textarea').default('标题:${标题}\n作者:${作者}\n简介:${简介}\n时长:${视频时长}\n点赞:${点赞数}\n投币:${投币数}\n收藏:${收藏数}\n转发:${转发数}\n播放:${播放数}\n视频大小:${视频大小}MB').description(`消息格式,可用变量:
65
+ ${'${标题}'} - 视频/图文标题
66
+ ${'${作者}'} - 作者名称
67
+ ${'${简介}'} - 作品简介/描述
68
+ ${'${视频时长}'} - 视频时长(格式化)
69
+ ${'${点赞数}'} - 点赞数量
70
+ ${'${投币数}'} - 投币数量(仅B站有效)
71
+ ${'${收藏数}'} - 收藏数量
72
+ ${'${转发数}'} - 转发/分享数量
73
+ ${'${播放数}'} - 播放/浏览数量
74
+ ${'${视频大小}'} - 视频文件大小(MB)
75
+ 注:非B站平台会自动隐藏投币字段`),
68
76
  }).description('消息格式'),
69
77
  koishi_1.Schema.object({
70
78
  showImageText: koishi_1.Schema.boolean().default(true).description('显示图文内容'),
@@ -99,13 +107,12 @@ exports.Config = koishi_1.Schema.intersect([
99
107
  enableApiSelection: koishi_1.Schema.const(false).required(),
100
108
  }).description('关闭API选择设置'),
101
109
  koishi_1.Schema.object({
102
- enableApiSelection: koishi_1.Schema.const(true),
110
+ enableApiSelection: koishi_1.Schema.const(true).required(),
103
111
  preferredApi: koishi_1.Schema.object({
104
112
  bilibili: koishi_1.Schema.union([
105
113
  'https://api.xingzhige.com/API/b_parse/',
106
114
  'https://api.bugpk.com/api/short_videos',
107
115
  'https://api.bugpk.com/api/bilibili',
108
- 'https://api.xingzhige.com/API/b_video/',
109
116
  'https://api.bilibili.com/x/web-interface/view'
110
117
  ]).default('https://api.xingzhige.com/API/b_parse/').description('B站首选解析源'),
111
118
  douyin: koishi_1.Schema.union([
@@ -116,18 +123,12 @@ exports.Config = koishi_1.Schema.intersect([
116
123
  'https://api.bugpk.com/api/dylive'
117
124
  ]).default('https://api.xingzhige.com/API/douyin/').description('抖音首选解析源'),
118
125
  kuaishou: koishi_1.Schema.union([
119
- 'https://api.xingzhige.com/API/kuaishou/',
120
126
  'https://api.bugpk.com/api/short_videos',
121
127
  'https://api.bugpk.com/api/ksjx',
122
128
  'https://api.bugpk.com/api/kuaishou',
123
129
  'https://api.bugpk.com/api/ksimg',
124
130
  'https://api.suyanw.cn/api/kuaishou.php'
125
- ]).default('https://api.xingzhige.com/API/kuaishou/').description('快手首选解析源'),
126
- xigua: koishi_1.Schema.union([
127
- 'https://api.xingzhige.com/API/xigua/',
128
- 'https://api.bugpk.com/api/short_videos',
129
- 'https://api.bugpk.com/api/toutiao'
130
- ]).default('https://api.xingzhige.com/API/xigua/').description('西瓜视频首选解析源'),
131
+ ]).default('https://api.bugpk.com/api/short_videos').description('快手首选解析源'),
131
132
  xiaohongshu: koishi_1.Schema.union([
132
133
  'https://api.bugpk.com/api/short_videos',
133
134
  'https://api.bugpk.com/api/xhsjx',
@@ -171,7 +172,7 @@ if (!worker_threads_1.isMainThread) {
171
172
  (async () => {
172
173
  try {
173
174
  if (url.endsWith('.m4a') || url.endsWith('.mp3')) {
174
- worker_threads_1.parentPort?.postMessage({ success: false, error: '不支持音频' });
175
+ worker_threads_1.parentPort?.postMessage({ success: false, error: '不支持音频', code: 3001 });
175
176
  return;
176
177
  }
177
178
  const maxSizeBytes = maxSize * 1024 * 1024;
@@ -184,8 +185,12 @@ if (!worker_threads_1.isMainThread) {
184
185
  });
185
186
  if (maxSize > 0 && response.headers['content-length']) {
186
187
  const contentLength = parseInt(response.headers['content-length']);
188
+ if (isNaN(contentLength)) {
189
+ worker_threads_1.parentPort?.postMessage({ success: false, error: '无法获取视频大小', code: 3002 });
190
+ return;
191
+ }
187
192
  if (contentLength > maxSizeBytes) {
188
- worker_threads_1.parentPort?.postMessage({ success: false, error: `视频大小超过限制(${maxSize}MB)` });
193
+ worker_threads_1.parentPort?.postMessage({ success: false, error: `视频大小超过限制(${maxSize}MB)`, code: 3003 });
189
194
  return;
190
195
  }
191
196
  }
@@ -196,15 +201,20 @@ if (!worker_threads_1.isMainThread) {
196
201
  if (maxSize > 0 && downloadedSize > maxSizeBytes) {
197
202
  response.data.destroy();
198
203
  writeStream.destroy();
199
- fs_1.default.unlinkSync(filePath);
200
- worker_threads_1.parentPort?.postMessage({ success: false, error: `视频大小超过限制(${maxSize}MB)` });
204
+ try {
205
+ fs_1.default.unlinkSync(filePath);
206
+ }
207
+ catch (err) {
208
+ logger.error(`删除文件失败: ${getErrorMessage(err)}`);
209
+ }
210
+ worker_threads_1.parentPort?.postMessage({ success: false, error: `视频大小超过限制(${maxSize}MB)`, code: 3003 });
201
211
  }
202
212
  });
203
213
  await (0, promises_1.pipeline)(response.data, writeStream);
204
214
  worker_threads_1.parentPort?.postMessage({ success: true, filePath });
205
215
  }
206
216
  catch (error) {
207
- worker_threads_1.parentPort?.postMessage({ success: false, error: getErrorMessage(error) });
217
+ worker_threads_1.parentPort?.postMessage({ success: false, error: getErrorMessage(error), code: 3004 });
208
218
  }
209
219
  })();
210
220
  }
@@ -220,7 +230,6 @@ const PLATFORM_KEYWORDS = {
220
230
  pipixia: ['pipixia', '皮皮虾', 'h5.pipix.com', 'pipix.com'],
221
231
  douyin: ['douyin', '抖音', 'v.douyin.com', 'douyin.com', 'tiktok.com'],
222
232
  zuiyou: ['zuiyou', '最右', 'xiaochuankeji.cn', 'izuiyou.com'],
223
- xigua: ['ixigua', '西瓜视频', 'xigua.com', 'ixigua.com']
224
233
  };
225
234
  function extractUrl(content, enableBvAvParse) {
226
235
  const urls = content.match(/https?:\/\/[^\s"'>]+/gi) || [];
@@ -322,29 +331,49 @@ function formatDuration(seconds) {
322
331
  function parseData(data, maxDescLength, platform) {
323
332
  let type = 'unknown';
324
333
  if (data.type) {
325
- type = data.type;
334
+ type = data.type.toLowerCase();
335
+ }
336
+ else if (data.data?.type) {
337
+ type = data.data.type.toLowerCase();
326
338
  }
327
- else if (data.images?.length && !data.url) {
339
+ else if (data.images?.length && !data.url && !data.data?.url) {
328
340
  type = 'image';
329
341
  }
330
- else if (data.live_photo?.length) {
342
+ else if (data.live_photo?.length || data.data?.live_photo?.length) {
331
343
  type = 'live';
332
344
  }
333
- else if (data.url || data.video) {
345
+ else if (data.url || data.video || data.data?.url || data.data?.video) {
334
346
  type = 'video';
335
347
  }
336
- const title = data.title || data.desc || '无标题';
337
- let author = data.author || data.name || '未知作者';
348
+ let title = data.title || data.data?.title || data.desc || data.data?.desc || '无标题';
349
+ let author = data.author || data.data?.author || data.name || data.data?.name || '未知作者';
338
350
  if (author && typeof author === 'object') {
339
- author = author.name || author.nickname || author.username || '未知作者';
351
+ author = author.name || author.nickname || author.username || author.uid || '未知作者';
352
+ }
353
+ let video = '';
354
+ const videoUrls = [];
355
+ if (data.url)
356
+ videoUrls.push(data.url);
357
+ if (data.video)
358
+ videoUrls.push(data.video);
359
+ if (data.data?.url)
360
+ videoUrls.push(data.data.url);
361
+ if (data.data?.video)
362
+ videoUrls.push(data.data.video);
363
+ if (data.data?.videos && Array.isArray(data.data.videos) && data.data.videos.length > 0) {
364
+ videoUrls.push(data.data.videos[0].url);
365
+ }
366
+ if (data.data?.live_photo && Array.isArray(data.data.live_photo) && data.data.live_photo.length > 0) {
367
+ videoUrls.push(data.data.live_photo[0].video);
340
368
  }
341
- let video = data.url || data.video || '';
369
+ video = videoUrls.find(url => url && typeof url === 'string' && url.startsWith('http')) || '';
370
+ let video_backup;
342
371
  if (data.video_backup) {
343
372
  if (Array.isArray(data.video_backup)) {
344
- video = video || data.video_backup[0]?.url || '';
373
+ video_backup = data.video_backup.map((item) => typeof item === 'object' ? item.url : item).filter(Boolean);
345
374
  }
346
375
  else if (typeof data.video_backup === 'string') {
347
- video = video || data.video_backup;
376
+ video_backup = [data.video_backup];
348
377
  }
349
378
  }
350
379
  let like = 0;
@@ -354,6 +383,10 @@ function parseData(data, maxDescLength, platform) {
354
383
  like = data.like;
355
384
  else if (data.likes !== undefined)
356
385
  like = data.likes;
386
+ else if (data.data?.stat?.like !== undefined)
387
+ like = data.data.stat.like;
388
+ else if (data.data?.like !== undefined)
389
+ like = data.data.like;
357
390
  let view = 0;
358
391
  if (data.stat?.view !== undefined)
359
392
  view = data.stat.view;
@@ -363,6 +396,10 @@ function parseData(data, maxDescLength, platform) {
363
396
  view = data.views;
364
397
  else if (data.play_count !== undefined)
365
398
  view = data.play_count;
399
+ else if (data.data?.stat?.view !== undefined)
400
+ view = data.data.stat.view;
401
+ else if (data.data?.play_count !== undefined)
402
+ view = data.data.play_count;
366
403
  let share = 0;
367
404
  if (data.stat?.share !== undefined)
368
405
  share = data.stat.share;
@@ -370,6 +407,8 @@ function parseData(data, maxDescLength, platform) {
370
407
  share = data.share;
371
408
  else if (data.shares !== undefined)
372
409
  share = data.shares;
410
+ else if (data.data?.stat?.share !== undefined)
411
+ share = data.data.stat.share;
373
412
  let favorite = 0;
374
413
  if (data.stat?.favorite !== undefined)
375
414
  favorite = data.stat.favorite;
@@ -377,23 +416,38 @@ function parseData(data, maxDescLength, platform) {
377
416
  favorite = data.favorite;
378
417
  else if (data.collect !== undefined)
379
418
  favorite = data.collect;
380
- let coin = data.stat?.coin || 0;
381
- let size = data.stat?.size || 0;
382
- if (data.size)
383
- size = data.size;
419
+ else if (data.data?.stat?.favorite !== undefined)
420
+ favorite = data.data.stat.favorite;
421
+ let coin = data.stat?.coin || data.data?.stat?.coin || 0;
422
+ let size = data.stat?.size || data.size || data.data?.stat?.size || data.data?.size || 0;
423
+ if (size && typeof size === 'string' && size.endsWith('MB')) {
424
+ size = parseFloat(size);
425
+ }
426
+ let duration = data.duration || data.data?.duration || 0;
427
+ if (typeof duration === 'string') {
428
+ duration = parseFloat(duration);
429
+ }
430
+ let cover = data.cover || data.imgurl || data.pic || data.data?.cover || data.data?.imgurl || '';
431
+ let images = data.images || data.data?.images || [];
432
+ if (data.imgurl && Array.isArray(data.imgurl)) {
433
+ images = [...images, ...data.imgurl];
434
+ }
435
+ let live_photo = data.live_photo || data.data?.live_photo;
436
+ let desc = (data.desc || data.description || data.data?.desc || data.data?.description || title || '').slice(0, maxDescLength);
437
+ let music = data.music || data.data?.music;
384
438
  return {
385
439
  type,
386
440
  title,
387
441
  author,
388
- desc: (data.desc || data.description || data.title || '').slice(0, maxDescLength),
389
- cover: data.cover || data.imgurl || data.pic || '',
390
- images: data.images || [],
442
+ desc,
443
+ cover,
444
+ images: Array.isArray(images) ? images : [],
391
445
  video,
392
- video_backup: Array.isArray(data.video_backup) ? data.video_backup : (data.video_backup ? [data.video_backup] : undefined),
393
- live_photo: data.live_photo,
394
- duration: data.duration || 0,
395
- durationFormatted: formatDuration(data.duration || 0),
396
- music: data.music,
446
+ video_backup: video_backup?.filter(url => url !== video),
447
+ live_photo: Array.isArray(live_photo) ? live_photo : undefined,
448
+ duration,
449
+ durationFormatted: formatDuration(duration),
450
+ music,
397
451
  stat: {
398
452
  like,
399
453
  coin,
@@ -401,7 +455,7 @@ function parseData(data, maxDescLength, platform) {
401
455
  share,
402
456
  view,
403
457
  size,
404
- duration: formatDuration(data.duration || 0)
458
+ duration: formatDuration(duration)
405
459
  }
406
460
  };
407
461
  }
@@ -478,7 +532,7 @@ function generateFormattedText(platform, parseData, config) {
478
532
  .replace(/\${播放数}/g, String(parseData.stat.view))
479
533
  .replace(/\${视频大小}/g, String(parseData.stat.size));
480
534
  if (platform !== 'bilibili') {
481
- text = text.replace(/\n投币:[0-9]+/g, '');
535
+ text = text.replace(/投币:[0-9]+\n?/g, '');
482
536
  }
483
537
  return text;
484
538
  }
@@ -495,12 +549,12 @@ async function downloadVideoWithThreads(url, filename, maxSize, threads, userAge
495
549
  if (result.success && result.filePath)
496
550
  resolve(result.filePath);
497
551
  else
498
- reject(new Error(result.error || '下载失败'));
552
+ reject(new Error(`${result.error || '下载失败'} (错误码: ${result.code || 3000})`));
499
553
  });
500
554
  worker.on('error', reject);
501
555
  worker.on('exit', (code) => {
502
556
  if (code !== 0)
503
- reject(new Error('视频下载线程异常'));
557
+ reject(new Error(`视频下载线程异常 (错误码: 3005)`));
504
558
  });
505
559
  });
506
560
  }
@@ -512,7 +566,8 @@ function clearAllCache() {
512
566
  if (fs_1.default.existsSync(tempDir)) {
513
567
  fs_1.default.readdirSync(tempDir).forEach(file => {
514
568
  try {
515
- fs_1.default.unlinkSync(path_1.default.join(tempDir, file));
569
+ const filePath = path_1.default.join(tempDir, file);
570
+ fs_1.default.unlinkSync(filePath);
516
571
  }
517
572
  catch { }
518
573
  });
@@ -539,35 +594,41 @@ function apply(ctx, config) {
539
594
  if (!worker_threads_1.isMainThread)
540
595
  return;
541
596
  clearAllCache();
542
- if (config.debug) {
543
- logger.info('视频解析插件已加载,调试模式已开启');
597
+ const logLevelMap = {
598
+ 'debug': 0,
599
+ 'info': 1,
600
+ 'warn': 2,
601
+ 'error': 3
602
+ };
603
+ if (config.debugMode) {
604
+ logger.level = logLevelMap['debug'];
605
+ }
606
+ else if (config.logLevel && logLevelMap[config.logLevel]) {
607
+ logger.level = logLevelMap[config.logLevel];
544
608
  }
609
+ logger.info('视频解析插件已加载');
545
610
  const http = axios_1.default.create({
546
611
  timeout: config.timeout,
547
- headers: { 'User-Agent': config.userAgent }
612
+ headers: { 'User-Agent': config.userAgent },
613
+ maxRedirects: 5,
614
+ validateStatus: (status) => status >= 200 && status < 500
548
615
  });
549
616
  async function tryAPI(apiFunc, apiName) {
550
617
  try {
551
- if (config.debug) {
552
- logger.debug(`尝试调用API: ${apiName}`);
553
- }
554
618
  const result = await apiFunc();
555
- if (config.debug && result) {
556
- logger.debug(`API ${apiName} 调用成功`);
557
- }
558
619
  return result;
559
620
  }
560
621
  catch (error) {
561
- if (config.debug) {
562
- logger.debug(`API ${apiName} 调用失败: ${getErrorMessage(error)}`);
622
+ if (config.debugMode) {
623
+ logger.debug(`API调用失败 ${apiName}: ${getErrorMessage(error)}`);
563
624
  }
564
625
  return null;
565
626
  }
566
627
  }
567
628
  async function requestAPI(apiUrl, params, method = 'GET') {
568
629
  try {
569
- if (config.debug) {
570
- logger.debug(`请求API: ${apiUrl}, 方法: ${method}, 参数:`, params);
630
+ if (config.debugMode) {
631
+ logger.debug(`请求API: ${apiUrl}, 参数: ${JSON.stringify(params)}, 方法: ${method}`);
571
632
  }
572
633
  let response;
573
634
  if (method.toUpperCase() === 'GET') {
@@ -576,22 +637,19 @@ function apply(ctx, config) {
576
637
  else {
577
638
  response = await http.post(apiUrl, params);
578
639
  }
579
- if (config.debug) {
580
- logger.debug(`API响应: ${apiUrl}, 状态码: ${response.status}`);
640
+ if (config.debugMode) {
641
+ logger.debug(`API响应: ${apiUrl}, 状态码: ${response.status}, 数据: ${JSON.stringify(response.data).substring(0, 500)}`);
581
642
  }
582
643
  return response.data;
583
644
  }
584
645
  catch (error) {
585
- if (config.debug) {
586
- logger.debug(`API请求失败 ${apiUrl}: ${getErrorMessage(error)}`);
646
+ if (config.debugMode) {
647
+ logger.debug(`API请求失败: ${apiUrl}, 错误: ${getErrorMessage(error)}`);
587
648
  }
588
649
  throw error;
589
650
  }
590
651
  }
591
652
  async function parseBilibili(realUrl) {
592
- if (config.debug) {
593
- logger.debug(`开始解析B站链接: ${realUrl}`);
594
- }
595
653
  const preferred = config.enableApiSelection ? config.preferredApi?.bilibili : 'https://api.xingzhige.com/API/b_parse/';
596
654
  const apis = [preferred];
597
655
  if (config.bilibiliAccessKey && preferred.includes('xingzhige')) {
@@ -610,15 +668,14 @@ function apply(ctx, config) {
610
668
  }
611
669
  const otherApis = [
612
670
  { url: 'https://api.xingzhige.com/API/b_parse/', method: 'GET' },
613
- { url: 'https://api.xingzhige.com/API/b_video/', method: 'GET' },
614
- { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
615
671
  { url: 'https://api.bugpk.com/api/bilibili', method: 'GET' },
672
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
616
673
  { url: 'https://api.bilibili.com/x/web-interface/view', method: 'GET' }
617
674
  ].filter(api => api.url !== preferred);
618
675
  for (const apiInfo of otherApis) {
619
676
  const result = await tryAPI(async () => {
620
677
  const params = { url: realUrl };
621
- if (apiInfo.url.includes('xingzhige.com/API/b_video/')) {
678
+ if (apiInfo.url.includes('bilibili.com/x/web-interface/view')) {
622
679
  const vid = vid_type_parse(realUrl);
623
680
  if (vid.type === 'bv') {
624
681
  params.bvid = vid.id;
@@ -638,7 +695,7 @@ function apply(ctx, config) {
638
695
  }
639
696
  else if (apiInfo.url.includes('bugpk.com')) {
640
697
  if ((data?.code === 200 || data?.code === 0) && data?.data) {
641
- return { data: parseData(data.data, config.maxDescLength, 'bilibili'), msg: 'B站解析成功' };
698
+ return { data: parseData(data, config.maxDescLength, 'bilibili'), msg: 'B站解析成功' };
642
699
  }
643
700
  }
644
701
  else if (apiInfo.url.includes('bilibili.com') && data?.code === 0 && data?.data) {
@@ -657,35 +714,31 @@ function apply(ctx, config) {
657
714
  return result;
658
715
  }
659
716
  logger.error(`B站解析失败 - URL: ${realUrl}, 错误码: 2001`);
660
- return { data: null, msg: 'B站解析失败' };
717
+ return { data: null, msg: 'B站解析失败 (错误码: 2001)' };
661
718
  }
662
719
  async function parseKuaishou(realUrl) {
663
- if (config.debug) {
664
- logger.debug(`开始解析快手链接: ${realUrl}`);
665
- }
666
- const preferred = config.enableApiSelection ? config.preferredApi?.kuaishou : 'https://api.xingzhige.com/API/kuaishou/';
720
+ const preferred = config.enableApiSelection ? config.preferredApi?.kuaishou : 'https://api.bugpk.com/api/short_videos';
667
721
  const apis = [{ url: preferred, method: 'GET' }];
668
722
  const otherApis = [
669
- { url: 'https://api.xingzhige.com/API/kuaishou/', method: 'GET' },
670
- { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
671
- { url: 'https://api.bugpk.com/api/ksjx', method: 'GET' },
672
723
  { url: 'https://api.bugpk.com/api/kuaishou', method: 'GET' },
724
+ { url: 'https://api.bugpk.com/api/ksjx', method: 'GET' },
673
725
  { url: 'https://api.bugpk.com/api/ksimg', method: 'GET' },
674
- { url: 'https://api.suyanw.cn/api/kuaishou.php', method: 'GET' }
726
+ { url: 'https://api.suyanw.cn/api/kuaishou.php', method: 'GET' },
727
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' }
675
728
  ].filter(api => api.url !== preferred);
676
729
  apis.push(...otherApis);
677
730
  for (const apiInfo of apis) {
678
731
  const result = await tryAPI(async () => {
679
732
  const data = await requestAPI(apiInfo.url, { url: realUrl }, apiInfo.method);
680
- if (apiInfo.url.includes('xingzhige')) {
681
- if (data?.jx?.length) {
682
- return { data: parseData(parse_xingzhige_data(data, 'kuaishou'), config.maxDescLength, 'kuaishou'), msg: '快手解析成功' };
733
+ if (apiInfo.url.includes('suyanw.cn')) {
734
+ if (data?.code === 200) {
735
+ return { data: parseData(parse_suyanw_data(data), config.maxDescLength, 'kuaishou'), msg: '快手解析成功' };
683
736
  }
684
737
  }
685
738
  else if (apiInfo.url.includes('bugpk.com')) {
686
739
  if ((data?.code === 200 || data?.code === 0)) {
687
740
  if (data.data) {
688
- return { data: parseData(data.data, config.maxDescLength, 'kuaishou'), msg: '快手解析成功' };
741
+ return { data: parseData(data, config.maxDescLength, 'kuaishou'), msg: '快手解析成功' };
689
742
  }
690
743
  else if (data.images) {
691
744
  return {
@@ -700,45 +753,38 @@ function apply(ctx, config) {
700
753
  }
701
754
  }
702
755
  }
703
- else if (apiInfo.url.includes('suyanw.cn')) {
704
- if (data?.code === 200) {
705
- return { data: parseData(parse_suyanw_data(data), config.maxDescLength, 'kuaishou'), msg: '快手解析成功' };
706
- }
707
- }
708
756
  return null;
709
757
  }, apiInfo.url);
710
758
  if (result)
711
759
  return result;
712
760
  }
713
761
  logger.error(`快手解析失败 - URL: ${realUrl}, 错误码: 2002`);
714
- return { data: null, msg: '快手解析失败' };
762
+ return { data: null, msg: '快手解析失败 (错误码: 2002)' };
715
763
  }
716
764
  async function parseDouyin(realUrl) {
717
- if (config.debug) {
718
- logger.debug(`开始解析抖音链接: ${realUrl}`);
719
- }
720
765
  const preferred = config.enableApiSelection ? config.preferredApi?.douyin : 'https://api.xingzhige.com/API/douyin/';
721
766
  const apis = [{ url: preferred, method: 'GET' }];
722
767
  const otherApis = [
723
768
  { url: 'https://api.xingzhige.com/API/douyin/', method: 'GET' },
724
- { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
725
769
  { url: 'https://api.bugpk.com/api/douyin', method: 'GET' },
726
770
  { url: 'https://api.bugpk.com/api/dyjx', method: 'GET' },
727
- { url: 'https://api.bugpk.com/api/dylive', method: 'GET' }
771
+ { url: 'https://api.bugpk.com/api/dylive', method: 'GET' },
772
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' }
728
773
  ].filter(api => api.url !== preferred);
729
774
  apis.push(...otherApis);
730
775
  for (const apiInfo of apis) {
731
776
  const result = await tryAPI(async () => {
732
- const data = await requestAPI(apiInfo.url, { url: realUrl }, apiInfo.method);
777
+ const method = apiInfo.url.includes('bugpk.com') ? 'POST' : 'GET';
778
+ const data = await requestAPI(apiInfo.url, { url: realUrl }, method);
733
779
  if (apiInfo.url.includes('xingzhige')) {
734
- if (data?.jx?.length) {
780
+ if (data?.jx?.length || data?.data) {
735
781
  return { data: parseData(parse_xingzhige_data(data, 'douyin'), config.maxDescLength, 'douyin'), msg: '抖音解析成功' };
736
782
  }
737
783
  }
738
784
  else if (apiInfo.url.includes('bugpk.com')) {
739
785
  if ((data?.code === 200 || data?.code === 0)) {
740
786
  if (data.data) {
741
- return { data: parseData(data.data, config.maxDescLength, 'douyin'), msg: '抖音解析成功' };
787
+ return { data: parseData(data, config.maxDescLength, 'douyin'), msg: '抖音解析成功' };
742
788
  }
743
789
  }
744
790
  }
@@ -748,77 +794,41 @@ function apply(ctx, config) {
748
794
  return result;
749
795
  }
750
796
  logger.error(`抖音解析失败 - URL: ${realUrl}, 错误码: 2003`);
751
- return { data: null, msg: '抖音解析失败' };
752
- }
753
- async function parseXigua(realUrl) {
754
- if (config.debug) {
755
- logger.debug(`开始解析西瓜视频链接: ${realUrl}`);
756
- }
757
- const preferred = config.enableApiSelection ? config.preferredApi?.xigua : 'https://api.xingzhige.com/API/xigua/';
758
- const apis = [{ url: preferred, method: 'GET' }];
759
- const otherApis = [
760
- { url: 'https://api.xingzhige.com/API/xigua/', method: 'GET' },
761
- { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
762
- { url: 'https://api.bugpk.com/api/toutiao', method: 'GET' }
763
- ].filter(api => api.url !== preferred);
764
- apis.push(...otherApis);
765
- for (const apiInfo of apis) {
766
- const result = await tryAPI(async () => {
767
- const data = await requestAPI(apiInfo.url, { url: realUrl }, apiInfo.method);
768
- if (apiInfo.url.includes('xingzhige')) {
769
- if (data?.jx?.length) {
770
- return { data: parseData(parse_xingzhige_data(data, 'xigua'), config.maxDescLength, 'xigua'), msg: '西瓜视频解析成功' };
771
- }
772
- }
773
- else if (apiInfo.url.includes('bugpk.com')) {
774
- if ((data?.code === 200 || data?.code === 0) && data?.data) {
775
- return { data: parseData(data.data, config.maxDescLength, 'xigua'), msg: '西瓜视频解析成功' };
776
- }
777
- }
778
- return null;
779
- }, apiInfo.url);
780
- if (result)
781
- return result;
782
- }
783
- logger.error(`西瓜视频解析失败 - URL: ${realUrl}, 错误码: 2004`);
784
- return { data: null, msg: '西瓜视频解析失败' };
797
+ return { data: null, msg: '抖音解析失败 (错误码: 2003)' };
785
798
  }
786
799
  async function parseOther(realUrl, platform) {
787
- if (config.debug) {
788
- logger.debug(`开始解析${platform}链接: ${realUrl}`);
789
- }
790
800
  const preferred = config.enableApiSelection ? config.preferredApi?.[platform] : 'https://api.bugpk.com/api/short_videos';
791
801
  const apis = [{ url: preferred, method: 'GET' }];
792
802
  const platformApis = {
793
803
  xiaohongshu: [
794
- { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
795
804
  { url: 'https://api.bugpk.com/api/xhsjx', method: 'GET' },
796
805
  { url: 'https://api.bugpk.com/api/xhsimg', method: 'GET' },
797
806
  { url: 'https://api.bugpk.com/api/xhslive', method: 'GET' },
798
- { url: 'https://api.bugpk.com/api/xhs', method: 'GET' }
807
+ { url: 'https://api.bugpk.com/api/xhs', method: 'GET' },
808
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' }
799
809
  ],
800
810
  weibo: [
801
- { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
802
811
  { url: 'https://api.bugpk.com/api/weibo', method: 'GET' },
803
- { url: 'https://api.bugpk.com/api/weibo_v', method: 'GET' }
812
+ { url: 'https://api.bugpk.com/api/weibo_v', method: 'GET' },
813
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' }
804
814
  ],
805
815
  toutiao: [
806
- { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
807
- { url: 'https://api.bugpk.com/api/toutiao', method: 'GET' }
816
+ { url: 'https://api.bugpk.com/api/toutiao', method: 'GET' },
817
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' }
808
818
  ],
809
819
  pipigx: [
810
- { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
811
820
  { url: 'https://api.bugpk.com/api/pipigx', method: 'GET' },
812
- { url: 'https://api.suyanw.cn/api/pipigx.php', method: 'GET' }
821
+ { url: 'https://api.suyanw.cn/api/pipigx.php', method: 'GET' },
822
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' }
813
823
  ],
814
824
  pipixia: [
815
- { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
816
- { url: 'https://api.bugpk.com/api/pipixia', method: 'GET' }
825
+ { url: 'https://api.bugpk.com/api/pipixia', method: 'GET' },
826
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' }
817
827
  ],
818
828
  zuiyou: [
819
- { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
820
829
  { url: 'https://api.bugpk.com/api/zuiyou', method: 'GET' },
821
- { url: 'https://api.suyanw.cn/api/zuiyou.php', method: 'GET' }
830
+ { url: 'https://api.suyanw.cn/api/zuiyou.php', method: 'GET' },
831
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' }
822
832
  ]
823
833
  };
824
834
  const otherApis = (platformApis[platform] || []).filter(api => api.url !== preferred);
@@ -829,7 +839,7 @@ function apply(ctx, config) {
829
839
  if (apiInfo.url.includes('bugpk.com') || apiInfo.url.includes('suyanw.cn')) {
830
840
  if (data?.code === 200 || data?.code === 0) {
831
841
  if (data.data) {
832
- return { data: parseData(data.data, config.maxDescLength, platform), msg: '解析成功' };
842
+ return { data: parseData(data, config.maxDescLength, platform), msg: '解析成功' };
833
843
  }
834
844
  else if (data.images) {
835
845
  return {
@@ -850,26 +860,20 @@ function apply(ctx, config) {
850
860
  return result;
851
861
  }
852
862
  logger.error(`${platform}解析失败 - URL: ${realUrl}, 错误码: 2005`);
853
- return { data: null, msg: '解析失败,请稍后重试' };
863
+ return { data: null, msg: '解析失败,请稍后重试 (错误码: 2005)' };
854
864
  }
855
865
  async function parse(url) {
856
- if (config.debug) {
857
- logger.debug(`开始解析URL: ${url}`);
858
- }
859
866
  const realUrl = await resolveShortUrl(url);
860
- if (config.debug) {
861
- logger.debug(`解析后URL: ${realUrl}`);
862
- }
863
867
  const platform = getPlatformType(realUrl);
864
868
  if (!platform || !config.platformEnable[platform]) {
865
- logger.error(`解析失败 - 平台: ${platform || '未知'}, URL: ${url}, 错误码: 1001`);
866
- return { data: null, msg: platform ? '该平台解析已关闭' : '不支持该平台链接' };
869
+ const code = !platform ? 1001 : 1002;
870
+ logger.error(`解析失败 - 平台: ${platform || '未知'}, URL: ${url}, 错误码: ${code}`);
871
+ return { data: null, msg: platform ? `该平台解析已关闭 (错误码: ${code})` : `不支持该平台链接 (错误码: ${code})` };
867
872
  }
868
873
  const parsers = {
869
874
  bilibili: parseBilibili,
870
875
  kuaishou: parseKuaishou,
871
- douyin: parseDouyin,
872
- xigua: parseXigua
876
+ douyin: parseDouyin
873
877
  };
874
878
  if (parsers[platform]) {
875
879
  return parsers[platform](realUrl);
@@ -880,27 +884,15 @@ function apply(ctx, config) {
880
884
  const hash = crypto_1.default.createHash('md5').update(url).digest('hex');
881
885
  const now = Date.now();
882
886
  if (processed.get(hash) && now - processed.get(hash) < config.sameLinkInterval * 1000) {
883
- if (config.debug) {
884
- logger.debug(`重复解析,跳过: ${url}`);
885
- }
886
- return { data: null, msg: '请勿重复解析' };
887
+ return { data: null, msg: '请勿重复解析 (错误码: 1003)' };
887
888
  }
888
889
  processed.set(hash, now);
889
- if (config.debug) {
890
- logger.debug(`开始处理URL: ${url}`);
891
- }
892
890
  const result = await parse(url);
893
891
  if (!result.data) {
894
- if (config.debug) {
895
- logger.debug(`解析失败: ${url}, 原因: ${result.msg}`);
896
- }
897
892
  return { data: null, msg: result.msg };
898
893
  }
899
894
  const platform = getPlatformType(url);
900
895
  const text = generateFormattedText(platform || 'bilibili', result.data, config);
901
- if (config.debug) {
902
- logger.debug(`解析成功: ${url}, 标题: ${result.data.title}`);
903
- }
904
896
  return {
905
897
  data: { text, cover: result.data.cover, images: result.data.images, video: result.data.video, type: result.data.type, live_photo: result.data.live_photo },
906
898
  msg: 'ok'
@@ -910,7 +902,7 @@ function apply(ctx, config) {
910
902
  if (config.videoSendTimeout <= 0) {
911
903
  return session.send(content).catch((err) => {
912
904
  if (!config.ignoreSendError)
913
- logger.error('发送消息失败:', err.message);
905
+ logger.error(`发送消息失败 (错误码: 4001): ${err.message}`);
914
906
  return null;
915
907
  });
916
908
  }
@@ -919,7 +911,7 @@ function apply(ctx, config) {
919
911
  new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), config.videoSendTimeout))
920
912
  ]).catch((err) => {
921
913
  if (!config.ignoreSendError)
922
- logger.error('发送消息超时:', err.message);
914
+ logger.error(`发送消息超时 (错误码: 4002): ${err.message}`);
923
915
  return null;
924
916
  });
925
917
  }
@@ -931,9 +923,6 @@ function apply(ctx, config) {
931
923
  clearTimeout(buffer.timer);
932
924
  linkBuffer.delete(key);
933
925
  }
934
- if (config.debug) {
935
- logger.debug(`开始处理批量URL: ${urls.length}个`);
936
- }
937
926
  const items = [];
938
927
  const errs = [];
939
928
  for (const url of urls) {
@@ -941,7 +930,7 @@ function apply(ctx, config) {
941
930
  if (result.data) {
942
931
  items.push(result.data);
943
932
  }
944
- else if (result.msg !== '请勿重复解析') {
933
+ else if (result.msg !== '请勿重复解析 (错误码: 1003)') {
945
934
  errs.push(`【${url.slice(0, 22)}...】:${result.msg}`);
946
935
  logger.error(`解析失败: ${url}, 原因: ${result.msg}`);
947
936
  }
@@ -969,9 +958,6 @@ function apply(ctx, config) {
969
958
  }
970
959
  return;
971
960
  }
972
- if (config.debug) {
973
- logger.debug(`成功解析: ${items.length}个`);
974
- }
975
961
  for (const item of items) {
976
962
  try {
977
963
  if (enableForward) {
@@ -1002,7 +988,7 @@ function apply(ctx, config) {
1002
988
  videoElem = koishi_1.h.file(filePath);
1003
989
  }
1004
990
  catch (error) {
1005
- logger.error(`视频下载失败: ${getErrorMessage(error)}`);
991
+ logger.error(`视频下载失败 (错误码: 4003): ${getErrorMessage(error)}`);
1006
992
  videoElem = koishi_1.h.video(item.video);
1007
993
  }
1008
994
  }
@@ -1046,7 +1032,7 @@ function apply(ctx, config) {
1046
1032
  videoElem = koishi_1.h.file(filePath);
1047
1033
  }
1048
1034
  catch (error) {
1049
- logger.error(`视频下载失败: ${getErrorMessage(error)}`);
1035
+ logger.error(`视频下载失败 (错误码: 4003): ${getErrorMessage(error)}`);
1050
1036
  videoElem = koishi_1.h.video(item.video);
1051
1037
  }
1052
1038
  }
@@ -1060,8 +1046,8 @@ function apply(ctx, config) {
1060
1046
  }
1061
1047
  }
1062
1048
  catch (error) {
1063
- logger.error(`处理内容失败: ${getErrorMessage(error)}`);
1064
- await sendTimeout(session, `❌ 处理${item.type}内容失败: ${getErrorMessage(error)}`);
1049
+ logger.error(`处理内容失败 (错误码: 4004): ${getErrorMessage(error)}`);
1050
+ await sendTimeout(session, `❌ 处理${item.type}内容失败: ${getErrorMessage(error)} (错误码: 4004)`);
1065
1051
  }
1066
1052
  }
1067
1053
  if (enableForward && forwardMessages.length) {
@@ -1069,7 +1055,7 @@ function apply(ctx, config) {
1069
1055
  await sendTimeout(session, (0, koishi_1.h)('message', { forward: true }, forwardMessages.slice(0, 100)));
1070
1056
  }
1071
1057
  catch (error) {
1072
- logger.error(`合并转发失败: ${getErrorMessage(error)}`);
1058
+ logger.error(`合并转发失败 (错误码: 4005): ${getErrorMessage(error)}`);
1073
1059
  for (const node of forwardMessages) {
1074
1060
  await sendTimeout(session, node.data.content);
1075
1061
  await delay(500);
@@ -1077,14 +1063,27 @@ function apply(ctx, config) {
1077
1063
  }
1078
1064
  }
1079
1065
  }
1080
- ctx.on('message', async (session) => {
1081
- if (!config.enable || !config.autoParse)
1082
- return;
1083
- const urls = extractUrl(session.content.trim(), config.enableBvAvParse);
1084
- if (!urls.length)
1085
- return;
1086
- if (config.debug) {
1087
- logger.debug(`收到消息,提取到URL: ${urls.length}个`);
1066
+ // 修复 middleware next 参数类型
1067
+ ctx.middleware(async (session, next) => {
1068
+ if (!config.enable || !config.autoParse) {
1069
+ return next();
1070
+ }
1071
+ let textContent = session.content || '';
1072
+ if (Array.isArray(session.elements)) {
1073
+ textContent = session.elements
1074
+ .filter((element) => element.type === 'text')
1075
+ .map((element) => element.content)
1076
+ .join('');
1077
+ }
1078
+ if (!textContent.trim()) {
1079
+ return next();
1080
+ }
1081
+ const urls = extractUrl(textContent.trim(), config.enableBvAvParse);
1082
+ if (!urls.length) {
1083
+ return next();
1084
+ }
1085
+ if (config.debugMode) {
1086
+ logger.debug(`检测到链接: ${JSON.stringify(urls)}`);
1088
1087
  }
1089
1088
  const key = `${session.platform}:${session.userId}:${session.channelId}`;
1090
1089
  const uniqueUrls = [...new Set(urls)];
@@ -1095,9 +1094,6 @@ function apply(ctx, config) {
1095
1094
  buffer.urls.push(...newUrls);
1096
1095
  clearTimeout(buffer.timer);
1097
1096
  buffer.timer = setTimeout(() => flush(session), config.messageBufferDelay * 1000);
1098
- if (config.debug) {
1099
- logger.debug(`缓冲中添加新URL: ${newUrls.length}个`);
1100
- }
1101
1097
  }
1102
1098
  return;
1103
1099
  }
@@ -1111,17 +1107,18 @@ function apply(ctx, config) {
1111
1107
  timer: setTimeout(() => flush(session), config.messageBufferDelay * 1000),
1112
1108
  tipMsgId
1113
1109
  });
1114
- if (config.debug) {
1115
- logger.debug(`创建新缓冲,等待处理: ${uniqueUrls.length}个`);
1116
- }
1110
+ return next();
1117
1111
  });
1118
1112
  ctx.command('parse <url>', '手动解析视频链接')
1119
- .action(async ({ session }, url) => {
1113
+ .action(async (argv, url) => {
1114
+ const session = argv.session;
1115
+ if (!session)
1116
+ return '解析失败:未找到会话 (错误码: 5000)';
1120
1117
  if (!url)
1121
- return '请输入视频链接';
1118
+ return '请输入视频链接 (错误码: 5001)';
1122
1119
  const urls = extractUrl(url, config.enableBvAvParse);
1123
1120
  if (!urls.length)
1124
- return '不支持该链接';
1121
+ return '不支持该链接 (错误码: 1001)';
1125
1122
  await flush(session, [...new Set(urls)]);
1126
1123
  });
1127
1124
  ctx.command('clear-cache', '清空解析缓存与临时文件')
@@ -1143,12 +1140,13 @@ function apply(ctx, config) {
1143
1140
  const now = Date.now();
1144
1141
  fs_1.default.readdirSync(tempDir).forEach(file => {
1145
1142
  try {
1146
- const stat = fs_1.default.statSync(path_1.default.join(tempDir, file));
1143
+ const filePath = path_1.default.join(tempDir, file);
1144
+ const stat = fs_1.default.statSync(filePath);
1147
1145
  if (now - stat.mtimeMs > 3600000)
1148
- fs_1.default.unlinkSync(path_1.default.join(tempDir, file));
1146
+ fs_1.default.unlinkSync(filePath);
1149
1147
  }
1150
1148
  catch (error) {
1151
- logger.error(`清理临时文件失败: ${file}, ${getErrorMessage(error)}`);
1149
+ logger.error(`清理临时文件失败 (错误码: 4006): ${file}, ${getErrorMessage(error)}`);
1152
1150
  }
1153
1151
  });
1154
1152
  }, 1800000);
@@ -1156,7 +1154,7 @@ function apply(ctx, config) {
1156
1154
  setInterval(clearAllCache, config.autoClearCacheInterval * 60000);
1157
1155
  }
1158
1156
  process.on('exit', clearAllCache);
1159
- logger.info('视频解析插件已加载');
1157
+ logger.info('视频解析插件已加载完成');
1160
1158
  }
1161
1159
  module.exports = {
1162
1160
  name: exports.name,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-video-parser-all",
3
- "description": "Koishi 全平台视频解析插件,支持抖音/快手/B站/小红书/微博/今日头条/皮皮搞笑/皮皮虾/西瓜视频/最右视频链接解析",
4
- "version": "0.4.7",
3
+ "description": "Koishi 全平台视频解析插件,支持抖音/快手/B站/小红书/微博/今日头条/皮皮搞笑/皮皮虾/右视频链接解析",
4
+ "version": "0.4.9",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [