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

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 +27 -25
  2. package/lib/index.js +413 -124
  3. package/package.json +1 -1
package/lib/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { Schema } 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;
5
6
  autoParse?: boolean | null | undefined;
6
7
  enableBvAvParse?: boolean | null | undefined;
7
8
  botName?: string | null | undefined;
@@ -48,23 +49,24 @@ export declare const Config: Schema<{
48
49
  } & ({
49
50
  autoClearCacheInterval?: number | null | undefined;
50
51
  } & (({
52
+ enableApiSelection?: false | null | undefined;
53
+ } & import("cosmokit").Dict) | ({
51
54
  enableApiSelection?: true | null | undefined;
52
55
  preferredApi?: ({
53
- 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;
54
- douyin?: "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/douyin/" | "https://api.bugpk.com/api/douyin" | null | undefined;
55
- kuaishou?: "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/kuaishou/" | "https://api.bugpk.com/api/ksjx" | 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.xingzhige.com/API/b_video/" | "https://api.bilibili.com/x/web-interface/view" | null | undefined;
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;
56
59
  xigua?: "https://api.bugpk.com/api/short_videos" | "https://api.xingzhige.com/API/xigua/" | "https://api.bugpk.com/api/toutiao" | null | undefined;
57
- xiaohongshu?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/xhsjx" | null | undefined;
58
- weibo?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo" | null | undefined;
60
+ 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
+ weibo?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo" | "https://api.bugpk.com/api/weibo_v" | null | undefined;
59
62
  toutiao?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/toutiao" | null | undefined;
60
- pipigx?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipigx" | null | undefined;
63
+ pipigx?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipigx" | "https://api.suyanw.cn/api/pipigx.php" | null | undefined;
61
64
  pipixia?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipixia" | null | undefined;
62
- zuiyou?: "https://api.bugpk.com/api/short_videos" | "https://api.suyanw.cn/api/zuiyou.php" | null | undefined;
65
+ zuiyou?: "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/zuiyou" | "https://api.suyanw.cn/api/zuiyou.php" | null | undefined;
63
66
  } & import("cosmokit").Dict) | null | undefined;
64
- } & import("cosmokit").Dict) | ({
65
- enableApiSelection?: false | null | undefined;
66
67
  } & import("cosmokit").Dict))))), {
67
68
  enable: boolean;
69
+ debug: boolean;
68
70
  autoParse: boolean;
69
71
  enableBvAvParse: boolean;
70
72
  botName: string;
@@ -111,31 +113,31 @@ export declare const Config: Schema<{
111
113
  } & ({
112
114
  autoClearCacheInterval: number;
113
115
  } & (Schemastery.ObjectT<{
116
+ enableApiSelection: Schema<false, false>;
117
+ }> | Schemastery.ObjectT<{
114
118
  enableApiSelection: Schema<true, true>;
115
119
  preferredApi: Schema<Schemastery.ObjectS<{
116
- 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">;
117
- 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/short_videos" | "https://api.xingzhige.com/API/douyin/" | "https://api.bugpk.com/api/douyin">;
118
- 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/short_videos" | "https://api.xingzhige.com/API/kuaishou/" | "https://api.bugpk.com/api/ksjx">;
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">;
121
+ 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">;
119
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">;
120
- xiaohongshu: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/xhsjx", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/xhsjx">;
121
- weibo: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo">;
124
+ 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
+ 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">;
122
126
  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">;
123
- pipigx: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipigx", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipigx">;
127
+ pipigx: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipigx" | "https://api.suyanw.cn/api/pipigx.php", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipigx" | "https://api.suyanw.cn/api/pipigx.php">;
124
128
  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">;
125
- zuiyou: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.suyanw.cn/api/zuiyou.php", "https://api.bugpk.com/api/short_videos" | "https://api.suyanw.cn/api/zuiyou.php">;
129
+ 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">;
126
130
  }>, Schemastery.ObjectT<{
127
- 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">;
128
- 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/short_videos" | "https://api.xingzhige.com/API/douyin/" | "https://api.bugpk.com/api/douyin">;
129
- 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/short_videos" | "https://api.xingzhige.com/API/kuaishou/" | "https://api.bugpk.com/api/ksjx">;
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">;
132
+ 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">;
130
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
- xiaohongshu: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/xhsjx", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/xhsjx">;
132
- weibo: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/weibo">;
135
+ 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
+ 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">;
133
137
  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">;
134
- pipigx: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipigx", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipigx">;
138
+ pipigx: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipigx" | "https://api.suyanw.cn/api/pipigx.php", "https://api.bugpk.com/api/short_videos" | "https://api.bugpk.com/api/pipigx" | "https://api.suyanw.cn/api/pipigx.php">;
135
139
  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">;
136
- zuiyou: Schema<"https://api.bugpk.com/api/short_videos" | "https://api.suyanw.cn/api/zuiyou.php", "https://api.bugpk.com/api/short_videos" | "https://api.suyanw.cn/api/zuiyou.php">;
140
+ 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">;
137
141
  }>>;
138
- }> | Schemastery.ObjectT<{
139
- enableApiSelection: Schema<false, false>;
140
142
  }>))))>;
141
143
  export declare function apply(ctx: any, config: any): void;
package/lib/index.js CHANGED
@@ -12,6 +12,7 @@ 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
+ const logger = new koishi_1.Logger('video-parser');
15
16
  const API_CONFIG = {
16
17
  universal: 'https://api.bugpk.com/api/short_videos',
17
18
  xingzhige: {
@@ -21,22 +22,23 @@ const API_CONFIG = {
21
22
  xigua: 'https://api.xingzhige.com/API/xigua/'
22
23
  },
23
24
  platform: {
24
- bilibili: ['https://api.bugpk.com/api/bilibili'],
25
- 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'],
26
- xiaohongshu: ['https://api.bugpk.com/api/xhsjx', 'https://api.bugpk.com/api/xhsimg', 'https://api.bugpk.com/api/xhslive'],
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/'],
27
+ 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'],
27
28
  weibo: ['https://api.bugpk.com/api/weibo', 'https://api.bugpk.com/api/weibo_v'],
28
29
  toutiao: ['https://api.bugpk.com/api/toutiao'],
29
30
  pipigx: ['https://api.bugpk.com/api/pipigx', 'https://api.suyanw.cn/api/pipigx.php'],
30
31
  pipixia: ['https://api.bugpk.com/api/pipixia'],
31
- douyin: ['https://api.bugpk.com/api/douyin', 'https://api.bugpk.com/api/dyjx', 'https://api.bugpk.com/api/dylive'],
32
- zuiyou: ['https://api.suyanw.cn/api/zuiyou.php'],
33
- xigua: ['https://api.bugpk.com/api/toutiao']
32
+ 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/']
34
35
  }
35
36
  };
36
37
  exports.name = 'video-parser-all';
37
38
  exports.Config = koishi_1.Schema.intersect([
38
39
  koishi_1.Schema.object({
39
40
  enable: koishi_1.Schema.boolean().default(true).description('是否启用视频解析插件'),
41
+ debug: koishi_1.Schema.boolean().default(false).description('开启调试模式,输出详细日志'),
40
42
  autoParse: koishi_1.Schema.boolean().default(true).description('是否自动解析消息中的视频链接'),
41
43
  enableBvAvParse: koishi_1.Schema.boolean().default(true).description('是否解析独立的BV/AV号(如:BV1xx411c7mD)'),
42
44
  botName: koishi_1.Schema.string().default('视频解析机器人').description('机器人显示名称'),
@@ -62,7 +64,7 @@ exports.Config = koishi_1.Schema.intersect([
62
64
  }).description('平台开关')
63
65
  }).description('平台开关'),
64
66
  koishi_1.Schema.object({
65
- messageFormat: koishi_1.Schema.string().role('textarea').default('标题:${标题}\n作者:${作者}\n简介:${简介}\n时长:${视频时长}\n点赞:${点赞数}\n投币:${投币数}\n收藏:${收藏数}\n转发:${转发数}\n播放:${播放数}\n视频大小:${视频大小}MB').description('统一消息格式(支持${变量}占位符,投币仅B站有效,其他平台自动隐藏)'),
67
+ messageFormat: koishi_1.Schema.string().role('textarea').default('标题:${标题}\n作者:${作者}\n简介:${简介}\n时长:${视频时长}\n点赞:${点赞数}\n投币:${投币数}\n收藏:${收藏数}\n转发:${转发数}\n播放:${播放数}\n视频大小:${视频大小}MB').description('消息格式,可用变量:${标题}、${作者}、${简介}、${视频时长}、${点赞数}、${投币数}、${收藏数}、${转发数}、${播放数}、${视频大小}'),
66
68
  }).description('消息格式'),
67
69
  koishi_1.Schema.object({
68
70
  showImageText: koishi_1.Schema.boolean().default(true).description('显示图文内容'),
@@ -95,7 +97,7 @@ exports.Config = koishi_1.Schema.intersect([
95
97
  koishi_1.Schema.union([
96
98
  koishi_1.Schema.object({
97
99
  enableApiSelection: koishi_1.Schema.const(false).required(),
98
- }),
100
+ }).description('关闭API选择设置'),
99
101
  koishi_1.Schema.object({
100
102
  enableApiSelection: koishi_1.Schema.const(true),
101
103
  preferredApi: koishi_1.Schema.object({
@@ -103,17 +105,23 @@ exports.Config = koishi_1.Schema.intersect([
103
105
  'https://api.xingzhige.com/API/b_parse/',
104
106
  'https://api.bugpk.com/api/short_videos',
105
107
  'https://api.bugpk.com/api/bilibili',
108
+ 'https://api.xingzhige.com/API/b_video/',
106
109
  'https://api.bilibili.com/x/web-interface/view'
107
110
  ]).default('https://api.xingzhige.com/API/b_parse/').description('B站首选解析源'),
108
111
  douyin: koishi_1.Schema.union([
109
112
  'https://api.xingzhige.com/API/douyin/',
110
113
  'https://api.bugpk.com/api/short_videos',
111
- 'https://api.bugpk.com/api/douyin'
114
+ 'https://api.bugpk.com/api/douyin',
115
+ 'https://api.bugpk.com/api/dyjx',
116
+ 'https://api.bugpk.com/api/dylive'
112
117
  ]).default('https://api.xingzhige.com/API/douyin/').description('抖音首选解析源'),
113
118
  kuaishou: koishi_1.Schema.union([
114
119
  'https://api.xingzhige.com/API/kuaishou/',
115
120
  'https://api.bugpk.com/api/short_videos',
116
- 'https://api.bugpk.com/api/ksjx'
121
+ 'https://api.bugpk.com/api/ksjx',
122
+ 'https://api.bugpk.com/api/kuaishou',
123
+ 'https://api.bugpk.com/api/ksimg',
124
+ 'https://api.suyanw.cn/api/kuaishou.php'
117
125
  ]).default('https://api.xingzhige.com/API/kuaishou/').description('快手首选解析源'),
118
126
  xigua: koishi_1.Schema.union([
119
127
  'https://api.xingzhige.com/API/xigua/',
@@ -122,11 +130,15 @@ exports.Config = koishi_1.Schema.intersect([
122
130
  ]).default('https://api.xingzhige.com/API/xigua/').description('西瓜视频首选解析源'),
123
131
  xiaohongshu: koishi_1.Schema.union([
124
132
  'https://api.bugpk.com/api/short_videos',
125
- 'https://api.bugpk.com/api/xhsjx'
133
+ 'https://api.bugpk.com/api/xhsjx',
134
+ 'https://api.bugpk.com/api/xhsimg',
135
+ 'https://api.bugpk.com/api/xhslive',
136
+ 'https://api.bugpk.com/api/xhs'
126
137
  ]).default('https://api.bugpk.com/api/short_videos').description('小红书首选解析源'),
127
138
  weibo: koishi_1.Schema.union([
128
139
  'https://api.bugpk.com/api/short_videos',
129
- 'https://api.bugpk.com/api/weibo'
140
+ 'https://api.bugpk.com/api/weibo',
141
+ 'https://api.bugpk.com/api/weibo_v'
130
142
  ]).default('https://api.bugpk.com/api/short_videos').description('微博首选解析源'),
131
143
  toutiao: koishi_1.Schema.union([
132
144
  'https://api.bugpk.com/api/short_videos',
@@ -134,7 +146,8 @@ exports.Config = koishi_1.Schema.intersect([
134
146
  ]).default('https://api.bugpk.com/api/short_videos').description('今日头条首选解析源'),
135
147
  pipigx: koishi_1.Schema.union([
136
148
  'https://api.bugpk.com/api/short_videos',
137
- 'https://api.bugpk.com/api/pipigx'
149
+ 'https://api.bugpk.com/api/pipigx',
150
+ 'https://api.suyanw.cn/api/pipigx.php'
138
151
  ]).default('https://api.bugpk.com/api/short_videos').description('皮皮搞笑首选解析源'),
139
152
  pipixia: koishi_1.Schema.union([
140
153
  'https://api.bugpk.com/api/short_videos',
@@ -142,10 +155,11 @@ exports.Config = koishi_1.Schema.intersect([
142
155
  ]).default('https://api.bugpk.com/api/short_videos').description('皮皮虾首选解析源'),
143
156
  zuiyou: koishi_1.Schema.union([
144
157
  'https://api.bugpk.com/api/short_videos',
158
+ 'https://api.bugpk.com/api/zuiyou',
145
159
  'https://api.suyanw.cn/api/zuiyou.php'
146
160
  ]).default('https://api.bugpk.com/api/short_videos').description('最右首选解析源'),
147
161
  }).description('首选解析源设置(将优先尝试用户选择的API,失败后自动尝试其他)')
148
- }).description('API选择设置'),
162
+ }).description('API选择设置(启用后显示)'),
149
163
  ]),
150
164
  ]);
151
165
  function getErrorMessage(error) {
@@ -306,29 +320,87 @@ function formatDuration(seconds) {
306
320
  return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
307
321
  }
308
322
  function parseData(data, maxDescLength, platform) {
309
- const type = data.images?.length && !data.video ? 'image' : 'video';
323
+ let type = 'unknown';
324
+ if (data.type) {
325
+ type = data.type;
326
+ }
327
+ else if (data.images?.length && !data.url) {
328
+ type = 'image';
329
+ }
330
+ else if (data.live_photo?.length) {
331
+ type = 'live';
332
+ }
333
+ else if (data.url || data.video) {
334
+ type = 'video';
335
+ }
310
336
  const title = data.title || data.desc || '无标题';
311
337
  let author = data.author || data.name || '未知作者';
312
338
  if (author && typeof author === 'object') {
313
339
  author = author.name || author.nickname || author.username || '未知作者';
314
340
  }
341
+ let video = data.url || data.video || '';
342
+ if (data.video_backup) {
343
+ if (Array.isArray(data.video_backup)) {
344
+ video = video || data.video_backup[0]?.url || '';
345
+ }
346
+ else if (typeof data.video_backup === 'string') {
347
+ video = video || data.video_backup;
348
+ }
349
+ }
350
+ let like = 0;
351
+ if (data.stat?.like !== undefined)
352
+ like = data.stat.like;
353
+ else if (data.like !== undefined)
354
+ like = data.like;
355
+ else if (data.likes !== undefined)
356
+ like = data.likes;
357
+ let view = 0;
358
+ if (data.stat?.view !== undefined)
359
+ view = data.stat.view;
360
+ else if (data.view !== undefined)
361
+ view = data.view;
362
+ else if (data.views !== undefined)
363
+ view = data.views;
364
+ else if (data.play_count !== undefined)
365
+ view = data.play_count;
366
+ let share = 0;
367
+ if (data.stat?.share !== undefined)
368
+ share = data.stat.share;
369
+ else if (data.share !== undefined)
370
+ share = data.share;
371
+ else if (data.shares !== undefined)
372
+ share = data.shares;
373
+ let favorite = 0;
374
+ if (data.stat?.favorite !== undefined)
375
+ favorite = data.stat.favorite;
376
+ else if (data.favorite !== undefined)
377
+ favorite = data.favorite;
378
+ else if (data.collect !== undefined)
379
+ 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;
315
384
  return {
316
385
  type,
317
386
  title,
318
387
  author,
319
- desc: (data.desc || data.description || title).slice(0, maxDescLength),
388
+ desc: (data.desc || data.description || data.title || '').slice(0, maxDescLength),
320
389
  cover: data.cover || data.imgurl || data.pic || '',
321
390
  images: data.images || [],
322
- video: data.video || data.url || '',
391
+ 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,
323
394
  duration: data.duration || 0,
324
395
  durationFormatted: formatDuration(data.duration || 0),
396
+ music: data.music,
325
397
  stat: {
326
- like: data.stat?.like || 0,
327
- coin: data.stat?.coin || 0,
328
- favorite: data.stat?.favorite || 0,
329
- share: data.stat?.share || 0,
330
- view: data.stat?.view || 0,
331
- size: data.stat?.size || 0,
398
+ like,
399
+ coin,
400
+ favorite,
401
+ share,
402
+ view,
403
+ size,
332
404
  duration: formatDuration(data.duration || 0)
333
405
  }
334
406
  };
@@ -340,7 +412,7 @@ function parse_xingzhige_data(resData, platform) {
340
412
  title: d.video?.title || d.title || '',
341
413
  author: d.owner?.name || d.name || '未知UP主',
342
414
  desc: d.video?.desc || d.desc || '',
343
- cover: d.video?.fm || d.fm || '',
415
+ cover: d.video?.fm || d.fm || d.cover || '',
344
416
  video: d.video?.url || d.url || '',
345
417
  images: [],
346
418
  stat: {
@@ -349,7 +421,8 @@ function parse_xingzhige_data(resData, platform) {
349
421
  coin: d.stat?.coin || 0,
350
422
  favorite: d.stat?.favorite || 0,
351
423
  share: d.stat?.share || 0,
352
- duration: d.duration || 0
424
+ duration: d.duration || 0,
425
+ size: d.size || 0
353
426
  },
354
427
  duration: d.duration || 0,
355
428
  type: 'video'
@@ -357,17 +430,38 @@ function parse_xingzhige_data(resData, platform) {
357
430
  }
358
431
  const item = resData.jx?.[0] || {};
359
432
  return {
360
- title: item.title || '',
361
- author: resData.stat?.author || '',
362
- cover: item.cover || '',
363
- video: item.url || item.video || '',
364
- images: item.images || [],
433
+ title: item.title || resData.title || '',
434
+ author: resData.stat?.author || resData.author || '',
435
+ cover: item.cover || resData.cover || '',
436
+ video: item.url || item.video || resData.url || '',
437
+ images: item.images || resData.images || [],
438
+ music: item.music || resData.music,
365
439
  stat: {
366
440
  like: resData.stat?.like || 0,
367
441
  view: resData.stat?.view || 0,
368
- share: resData.stat?.share || 0
442
+ share: resData.stat?.share || 0,
443
+ comment: resData.stat?.comment || 0,
444
+ collect: resData.stat?.collect || 0,
445
+ size: item.size || 0
369
446
  },
370
- type: item.images?.length ? 'image' : 'video'
447
+ type: item.images?.length ? 'image' : (resData.type || 'video')
448
+ };
449
+ }
450
+ function parse_suyanw_data(resData) {
451
+ return {
452
+ title: resData.data?.title || '',
453
+ author: resData.data?.author || '',
454
+ cover: resData.data?.cover || '',
455
+ video: resData.data?.video || resData.data?.url || '',
456
+ images: resData.image || [],
457
+ music: resData.music,
458
+ stat: {
459
+ like: resData.data?.likes || 0,
460
+ view: resData.data?.views || 0,
461
+ comment: resData.data?.comments || 0,
462
+ size: 0
463
+ },
464
+ type: resData.image?.length ? 'image' : 'video'
371
465
  };
372
466
  }
373
467
  function generateFormattedText(platform, parseData, config) {
@@ -445,182 +539,330 @@ function apply(ctx, config) {
445
539
  if (!worker_threads_1.isMainThread)
446
540
  return;
447
541
  clearAllCache();
542
+ if (config.debug) {
543
+ logger.info('视频解析插件已加载,调试模式已开启');
544
+ }
448
545
  const http = axios_1.default.create({
449
546
  timeout: config.timeout,
450
547
  headers: { 'User-Agent': config.userAgent }
451
548
  });
452
- async function tryAPI(apiFunc) {
549
+ async function tryAPI(apiFunc, apiName) {
453
550
  try {
454
- return await apiFunc();
551
+ if (config.debug) {
552
+ logger.debug(`尝试调用API: ${apiName}`);
553
+ }
554
+ const result = await apiFunc();
555
+ if (config.debug && result) {
556
+ logger.debug(`API ${apiName} 调用成功`);
557
+ }
558
+ return result;
455
559
  }
456
- catch {
560
+ catch (error) {
561
+ if (config.debug) {
562
+ logger.debug(`API ${apiName} 调用失败: ${getErrorMessage(error)}`);
563
+ }
457
564
  return null;
458
565
  }
459
566
  }
567
+ async function requestAPI(apiUrl, params, method = 'GET') {
568
+ try {
569
+ if (config.debug) {
570
+ logger.debug(`请求API: ${apiUrl}, 方法: ${method}, 参数:`, params);
571
+ }
572
+ let response;
573
+ if (method.toUpperCase() === 'GET') {
574
+ response = await http.get(apiUrl, { params });
575
+ }
576
+ else {
577
+ response = await http.post(apiUrl, params);
578
+ }
579
+ if (config.debug) {
580
+ logger.debug(`API响应: ${apiUrl}, 状态码: ${response.status}`);
581
+ }
582
+ return response.data;
583
+ }
584
+ catch (error) {
585
+ if (config.debug) {
586
+ logger.debug(`API请求失败 ${apiUrl}: ${getErrorMessage(error)}`);
587
+ }
588
+ throw error;
589
+ }
590
+ }
460
591
  async function parseBilibili(realUrl) {
592
+ if (config.debug) {
593
+ logger.debug(`开始解析B站链接: ${realUrl}`);
594
+ }
461
595
  const preferred = config.enableApiSelection ? config.preferredApi?.bilibili : 'https://api.xingzhige.com/API/b_parse/';
462
596
  const apis = [preferred];
463
597
  if (config.bilibiliAccessKey && preferred.includes('xingzhige')) {
464
598
  const vipResult = await tryAPI(async () => {
465
- const res = await http.get(preferred, {
466
- params: { url: realUrl, access_key: config.bilibiliAccessKey }
467
- });
468
- if (res.data?.data || res.data?.title) {
469
- return { data: parseData(parse_xingzhige_data(res.data, 'bilibili'), config.maxDescLength, 'bilibili'), msg: 'B站解析成功' };
599
+ const data = await requestAPI(preferred, {
600
+ url: realUrl,
601
+ access_key: config.bilibiliAccessKey
602
+ }, 'GET');
603
+ if (data?.data || data?.title) {
604
+ return { data: parseData(parse_xingzhige_data(data, 'bilibili'), config.maxDescLength, 'bilibili'), msg: 'B站解析成功' };
470
605
  }
471
606
  return null;
472
- });
607
+ }, `${preferred} (大会员)`);
473
608
  if (vipResult)
474
609
  return vipResult;
475
610
  }
476
611
  const otherApis = [
477
- 'https://api.xingzhige.com/API/b_parse/',
478
- 'https://api.bugpk.com/api/short_videos',
479
- 'https://api.bugpk.com/api/bilibili',
480
- 'https://api.bilibili.com/x/web-interface/view'
481
- ].filter(api => api !== preferred);
482
- apis.push(...otherApis);
483
- for (const apiUrl of apis) {
612
+ { 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
+ { url: 'https://api.bugpk.com/api/bilibili', method: 'GET' },
616
+ { url: 'https://api.bilibili.com/x/web-interface/view', method: 'GET' }
617
+ ].filter(api => api.url !== preferred);
618
+ for (const apiInfo of otherApis) {
484
619
  const result = await tryAPI(async () => {
485
620
  const params = { url: realUrl };
486
- if (config.bilibiliAccessKey && apiUrl.includes('xingzhige')) {
621
+ if (apiInfo.url.includes('xingzhige.com/API/b_video/')) {
622
+ const vid = vid_type_parse(realUrl);
623
+ if (vid.type === 'bv') {
624
+ params.bvid = vid.id;
625
+ }
626
+ else if (vid.type === 'av') {
627
+ params.aid = vid.id;
628
+ }
629
+ }
630
+ if (config.bilibiliAccessKey && apiInfo.url.includes('xingzhige')) {
487
631
  params.access_key = config.bilibiliAccessKey;
488
632
  }
489
- const res = await http.get(apiUrl, { params });
490
- if (apiUrl.includes('xingzhige') && (res.data?.data || res.data?.title)) {
491
- return { data: parseData(parse_xingzhige_data(res.data, 'bilibili'), config.maxDescLength, 'bilibili'), msg: 'B站解析成功' };
633
+ const data = await requestAPI(apiInfo.url, params, apiInfo.method);
634
+ if (apiInfo.url.includes('xingzhige')) {
635
+ if (data?.data || data?.title) {
636
+ return { data: parseData(parse_xingzhige_data(data, 'bilibili'), config.maxDescLength, 'bilibili'), msg: 'B站解析成功' };
637
+ }
492
638
  }
493
- if ((res.data?.code === 200 || res.data?.code === 0) && res.data?.data) {
494
- return { data: parseData(res.data.data, config.maxDescLength, 'bilibili'), msg: 'B站解析成功' };
639
+ else if (apiInfo.url.includes('bugpk.com')) {
640
+ if ((data?.code === 200 || data?.code === 0) && data?.data) {
641
+ return { data: parseData(data.data, config.maxDescLength, 'bilibili'), msg: 'B站解析成功' };
642
+ }
495
643
  }
496
- if (apiUrl.includes('bilibili.com') && res.data?.code === 0 && res.data?.data) {
497
- const { bvid, cid } = res.data.data;
644
+ else if (apiInfo.url.includes('bilibili.com') && data?.code === 0 && data?.data) {
645
+ const { bvid, cid } = data.data;
498
646
  const playInfo = await get_bilibili_play_url(bvid, cid, config.userAgent);
499
647
  if (playInfo) {
500
648
  return {
501
- data: parseData({ ...res.data, playUrl: playInfo.url, duration: playInfo.duration }, config.maxDescLength, 'bilibili'),
649
+ data: parseData({ ...data.data, playUrl: playInfo.url, duration: playInfo.duration }, config.maxDescLength, 'bilibili'),
502
650
  msg: 'B站解析成功'
503
651
  };
504
652
  }
505
653
  }
506
654
  return null;
507
- });
655
+ }, apiInfo.url);
508
656
  if (result)
509
657
  return result;
510
658
  }
511
- ctx.logger.error(`B站解析失败 - URL: ${realUrl}, 错误码: 2001`);
659
+ logger.error(`B站解析失败 - URL: ${realUrl}, 错误码: 2001`);
512
660
  return { data: null, msg: 'B站解析失败' };
513
661
  }
514
662
  async function parseKuaishou(realUrl) {
663
+ if (config.debug) {
664
+ logger.debug(`开始解析快手链接: ${realUrl}`);
665
+ }
515
666
  const preferred = config.enableApiSelection ? config.preferredApi?.kuaishou : 'https://api.xingzhige.com/API/kuaishou/';
516
- const apis = [preferred];
667
+ const apis = [{ url: preferred, method: 'GET' }];
517
668
  const otherApis = [
518
- 'https://api.xingzhige.com/API/kuaishou/',
519
- 'https://api.bugpk.com/api/short_videos',
520
- 'https://api.bugpk.com/api/ksjx'
521
- ].filter(api => api !== preferred);
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
+ { url: 'https://api.bugpk.com/api/kuaishou', method: 'GET' },
673
+ { url: 'https://api.bugpk.com/api/ksimg', method: 'GET' },
674
+ { url: 'https://api.suyanw.cn/api/kuaishou.php', method: 'GET' }
675
+ ].filter(api => api.url !== preferred);
522
676
  apis.push(...otherApis);
523
- for (const apiUrl of apis) {
677
+ for (const apiInfo of apis) {
524
678
  const result = await tryAPI(async () => {
525
- const res = await http.get(apiUrl, { params: { url: realUrl } });
526
- if (apiUrl.includes('xingzhige') && res.data?.jx?.length) {
527
- return { data: parseData(parse_xingzhige_data(res.data, 'kuaishou'), config.maxDescLength, 'kuaishou'), msg: '快手解析成功' };
679
+ 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: '快手解析成功' };
683
+ }
684
+ }
685
+ else if (apiInfo.url.includes('bugpk.com')) {
686
+ if ((data?.code === 200 || data?.code === 0)) {
687
+ if (data.data) {
688
+ return { data: parseData(data.data, config.maxDescLength, 'kuaishou'), msg: '快手解析成功' };
689
+ }
690
+ else if (data.images) {
691
+ return {
692
+ data: parseData({
693
+ images: data.images,
694
+ title: '快手图集',
695
+ author: data.author || '未知作者',
696
+ type: 'image'
697
+ }, config.maxDescLength, 'kuaishou'),
698
+ msg: '快手图集解析成功'
699
+ };
700
+ }
701
+ }
528
702
  }
529
- if ((res.data?.code === 200 || res.data?.code === 0) && (res.data?.data || res.data?.image)) {
530
- return { data: parseData(res.data.data || res.data, config.maxDescLength, 'kuaishou'), msg: '快手解析成功' };
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
+ }
531
707
  }
532
708
  return null;
533
- });
709
+ }, apiInfo.url);
534
710
  if (result)
535
711
  return result;
536
712
  }
537
- ctx.logger.error(`快手解析失败 - URL: ${realUrl}, 错误码: 2002`);
713
+ logger.error(`快手解析失败 - URL: ${realUrl}, 错误码: 2002`);
538
714
  return { data: null, msg: '快手解析失败' };
539
715
  }
540
716
  async function parseDouyin(realUrl) {
717
+ if (config.debug) {
718
+ logger.debug(`开始解析抖音链接: ${realUrl}`);
719
+ }
541
720
  const preferred = config.enableApiSelection ? config.preferredApi?.douyin : 'https://api.xingzhige.com/API/douyin/';
542
- const apis = [preferred];
721
+ const apis = [{ url: preferred, method: 'GET' }];
543
722
  const otherApis = [
544
- 'https://api.xingzhige.com/API/douyin/',
545
- 'https://api.bugpk.com/api/short_videos',
546
- 'https://api.bugpk.com/api/douyin'
547
- ].filter(api => api !== preferred);
723
+ { url: 'https://api.xingzhige.com/API/douyin/', method: 'GET' },
724
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
725
+ { url: 'https://api.bugpk.com/api/douyin', method: 'GET' },
726
+ { url: 'https://api.bugpk.com/api/dyjx', method: 'GET' },
727
+ { url: 'https://api.bugpk.com/api/dylive', method: 'GET' }
728
+ ].filter(api => api.url !== preferred);
548
729
  apis.push(...otherApis);
549
- for (const apiUrl of apis) {
730
+ for (const apiInfo of apis) {
550
731
  const result = await tryAPI(async () => {
551
- const res = await http.get(apiUrl, { params: { url: realUrl } });
552
- if (apiUrl.includes('xingzhige') && res.data?.jx?.length) {
553
- return { data: parseData(parse_xingzhige_data(res.data, 'douyin'), config.maxDescLength, 'douyin'), msg: '抖音解析成功' };
732
+ const data = await requestAPI(apiInfo.url, { url: realUrl }, apiInfo.method);
733
+ if (apiInfo.url.includes('xingzhige')) {
734
+ if (data?.jx?.length) {
735
+ return { data: parseData(parse_xingzhige_data(data, 'douyin'), config.maxDescLength, 'douyin'), msg: '抖音解析成功' };
736
+ }
554
737
  }
555
- if ((res.data?.code === 200 || res.data?.code === 0) && res.data?.data) {
556
- return { data: parseData(res.data.data, config.maxDescLength, 'douyin'), msg: '抖音解析成功' };
738
+ else if (apiInfo.url.includes('bugpk.com')) {
739
+ if ((data?.code === 200 || data?.code === 0)) {
740
+ if (data.data) {
741
+ return { data: parseData(data.data, config.maxDescLength, 'douyin'), msg: '抖音解析成功' };
742
+ }
743
+ }
557
744
  }
558
745
  return null;
559
- });
746
+ }, apiInfo.url);
560
747
  if (result)
561
748
  return result;
562
749
  }
563
- ctx.logger.error(`抖音解析失败 - URL: ${realUrl}, 错误码: 2003`);
750
+ logger.error(`抖音解析失败 - URL: ${realUrl}, 错误码: 2003`);
564
751
  return { data: null, msg: '抖音解析失败' };
565
752
  }
566
753
  async function parseXigua(realUrl) {
754
+ if (config.debug) {
755
+ logger.debug(`开始解析西瓜视频链接: ${realUrl}`);
756
+ }
567
757
  const preferred = config.enableApiSelection ? config.preferredApi?.xigua : 'https://api.xingzhige.com/API/xigua/';
568
- const apis = [preferred];
758
+ const apis = [{ url: preferred, method: 'GET' }];
569
759
  const otherApis = [
570
- 'https://api.xingzhige.com/API/xigua/',
571
- 'https://api.bugpk.com/api/short_videos',
572
- 'https://api.bugpk.com/api/toutiao'
573
- ].filter(api => api !== preferred);
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);
574
764
  apis.push(...otherApis);
575
- for (const apiUrl of apis) {
765
+ for (const apiInfo of apis) {
576
766
  const result = await tryAPI(async () => {
577
- const res = await http.get(apiUrl, { params: { url: realUrl } });
578
- if (apiUrl.includes('xingzhige') && res.data?.jx?.length) {
579
- return { data: parseData(parse_xingzhige_data(res.data, 'xigua'), config.maxDescLength, 'xigua'), msg: '西瓜视频解析成功' };
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
+ }
580
772
  }
581
- if ((res.data?.code === 200 || res.data?.code === 0) && res.data?.data) {
582
- return { data: parseData(res.data.data, config.maxDescLength, 'xigua'), msg: '西瓜视频解析成功' };
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
+ }
583
777
  }
584
778
  return null;
585
- });
779
+ }, apiInfo.url);
586
780
  if (result)
587
781
  return result;
588
782
  }
589
- ctx.logger.error(`西瓜视频解析失败 - URL: ${realUrl}, 错误码: 2004`);
783
+ logger.error(`西瓜视频解析失败 - URL: ${realUrl}, 错误码: 2004`);
590
784
  return { data: null, msg: '西瓜视频解析失败' };
591
785
  }
592
786
  async function parseOther(realUrl, platform) {
787
+ if (config.debug) {
788
+ logger.debug(`开始解析${platform}链接: ${realUrl}`);
789
+ }
593
790
  const preferred = config.enableApiSelection ? config.preferredApi?.[platform] : 'https://api.bugpk.com/api/short_videos';
594
- const apis = [preferred];
791
+ const apis = [{ url: preferred, method: 'GET' }];
595
792
  const platformApis = {
596
- xiaohongshu: ['https://api.bugpk.com/api/short_videos', 'https://api.bugpk.com/api/xhsjx'],
597
- weibo: ['https://api.bugpk.com/api/short_videos', 'https://api.bugpk.com/api/weibo'],
598
- toutiao: ['https://api.bugpk.com/api/short_videos', 'https://api.bugpk.com/api/toutiao'],
599
- pipigx: ['https://api.bugpk.com/api/short_videos', 'https://api.bugpk.com/api/pipigx'],
600
- pipixia: ['https://api.bugpk.com/api/short_videos', 'https://api.bugpk.com/api/pipixia'],
601
- zuiyou: ['https://api.bugpk.com/api/short_videos', 'https://api.suyanw.cn/api/zuiyou.php']
793
+ xiaohongshu: [
794
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
795
+ { url: 'https://api.bugpk.com/api/xhsjx', method: 'GET' },
796
+ { url: 'https://api.bugpk.com/api/xhsimg', method: 'GET' },
797
+ { url: 'https://api.bugpk.com/api/xhslive', method: 'GET' },
798
+ { url: 'https://api.bugpk.com/api/xhs', method: 'GET' }
799
+ ],
800
+ weibo: [
801
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
802
+ { url: 'https://api.bugpk.com/api/weibo', method: 'GET' },
803
+ { url: 'https://api.bugpk.com/api/weibo_v', method: 'GET' }
804
+ ],
805
+ toutiao: [
806
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
807
+ { url: 'https://api.bugpk.com/api/toutiao', method: 'GET' }
808
+ ],
809
+ pipigx: [
810
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
811
+ { url: 'https://api.bugpk.com/api/pipigx', method: 'GET' },
812
+ { url: 'https://api.suyanw.cn/api/pipigx.php', method: 'GET' }
813
+ ],
814
+ pipixia: [
815
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
816
+ { url: 'https://api.bugpk.com/api/pipixia', method: 'GET' }
817
+ ],
818
+ zuiyou: [
819
+ { url: 'https://api.bugpk.com/api/short_videos', method: 'GET' },
820
+ { url: 'https://api.bugpk.com/api/zuiyou', method: 'GET' },
821
+ { url: 'https://api.suyanw.cn/api/zuiyou.php', method: 'GET' }
822
+ ]
602
823
  };
603
- const otherApis = (platformApis[platform] || []).filter(api => api !== preferred);
824
+ const otherApis = (platformApis[platform] || []).filter(api => api.url !== preferred);
604
825
  apis.push(...otherApis);
605
- for (const apiUrl of apis) {
826
+ for (const apiInfo of apis) {
606
827
  const result = await tryAPI(async () => {
607
- const res = await http.get(apiUrl, { params: { url: realUrl } });
608
- if ((res.data?.code === 200 || res.data?.code === 0) && res.data?.data) {
609
- return { data: parseData(res.data.data, config.maxDescLength, platform), msg: '解析成功' };
828
+ const data = await requestAPI(apiInfo.url, { url: realUrl }, apiInfo.method);
829
+ if (apiInfo.url.includes('bugpk.com') || apiInfo.url.includes('suyanw.cn')) {
830
+ if (data?.code === 200 || data?.code === 0) {
831
+ if (data.data) {
832
+ return { data: parseData(data.data, config.maxDescLength, platform), msg: '解析成功' };
833
+ }
834
+ else if (data.images) {
835
+ return {
836
+ data: parseData({
837
+ images: data.images,
838
+ title: data.title || `${platform}图集`,
839
+ author: data.author || '未知作者',
840
+ type: 'image'
841
+ }, config.maxDescLength, platform),
842
+ msg: '图集解析成功'
843
+ };
844
+ }
845
+ }
610
846
  }
611
847
  return null;
612
- });
848
+ }, apiInfo.url);
613
849
  if (result)
614
850
  return result;
615
851
  }
616
- ctx.logger.error(`${platform}解析失败 - URL: ${realUrl}, 错误码: 2005`);
852
+ logger.error(`${platform}解析失败 - URL: ${realUrl}, 错误码: 2005`);
617
853
  return { data: null, msg: '解析失败,请稍后重试' };
618
854
  }
619
855
  async function parse(url) {
856
+ if (config.debug) {
857
+ logger.debug(`开始解析URL: ${url}`);
858
+ }
620
859
  const realUrl = await resolveShortUrl(url);
860
+ if (config.debug) {
861
+ logger.debug(`解析后URL: ${realUrl}`);
862
+ }
621
863
  const platform = getPlatformType(realUrl);
622
864
  if (!platform || !config.platformEnable[platform]) {
623
- ctx.logger.error(`解析失败 - 平台: ${platform || '未知'}, URL: ${url}, 错误码: 1001`);
865
+ logger.error(`解析失败 - 平台: ${platform || '未知'}, URL: ${url}, 错误码: 1001`);
624
866
  return { data: null, msg: platform ? '该平台解析已关闭' : '不支持该平台链接' };
625
867
  }
626
868
  const parsers = {
@@ -638,16 +880,29 @@ function apply(ctx, config) {
638
880
  const hash = crypto_1.default.createHash('md5').update(url).digest('hex');
639
881
  const now = Date.now();
640
882
  if (processed.get(hash) && now - processed.get(hash) < config.sameLinkInterval * 1000) {
883
+ if (config.debug) {
884
+ logger.debug(`重复解析,跳过: ${url}`);
885
+ }
641
886
  return { data: null, msg: '请勿重复解析' };
642
887
  }
643
888
  processed.set(hash, now);
889
+ if (config.debug) {
890
+ logger.debug(`开始处理URL: ${url}`);
891
+ }
644
892
  const result = await parse(url);
645
- if (!result.data)
893
+ if (!result.data) {
894
+ if (config.debug) {
895
+ logger.debug(`解析失败: ${url}, 原因: ${result.msg}`);
896
+ }
646
897
  return { data: null, msg: result.msg };
898
+ }
647
899
  const platform = getPlatformType(url);
648
900
  const text = generateFormattedText(platform || 'bilibili', result.data, config);
901
+ if (config.debug) {
902
+ logger.debug(`解析成功: ${url}, 标题: ${result.data.title}`);
903
+ }
649
904
  return {
650
- data: { text, cover: result.data.cover, images: result.data.images, video: result.data.video, type: result.data.type },
905
+ data: { text, cover: result.data.cover, images: result.data.images, video: result.data.video, type: result.data.type, live_photo: result.data.live_photo },
651
906
  msg: 'ok'
652
907
  };
653
908
  }
@@ -655,7 +910,7 @@ function apply(ctx, config) {
655
910
  if (config.videoSendTimeout <= 0) {
656
911
  return session.send(content).catch((err) => {
657
912
  if (!config.ignoreSendError)
658
- ctx.logger.error('发送消息失败:', err.message);
913
+ logger.error('发送消息失败:', err.message);
659
914
  return null;
660
915
  });
661
916
  }
@@ -664,7 +919,7 @@ function apply(ctx, config) {
664
919
  new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), config.videoSendTimeout))
665
920
  ]).catch((err) => {
666
921
  if (!config.ignoreSendError)
667
- ctx.logger.error('发送消息超时:', err.message);
922
+ logger.error('发送消息超时:', err.message);
668
923
  return null;
669
924
  });
670
925
  }
@@ -676,6 +931,9 @@ function apply(ctx, config) {
676
931
  clearTimeout(buffer.timer);
677
932
  linkBuffer.delete(key);
678
933
  }
934
+ if (config.debug) {
935
+ logger.debug(`开始处理批量URL: ${urls.length}个`);
936
+ }
679
937
  const items = [];
680
938
  const errs = [];
681
939
  for (const url of urls) {
@@ -685,7 +943,7 @@ function apply(ctx, config) {
685
943
  }
686
944
  else if (result.msg !== '请勿重复解析') {
687
945
  errs.push(`【${url.slice(0, 22)}...】:${result.msg}`);
688
- ctx.logger.error(`解析失败: ${url}, 原因: ${result.msg}`);
946
+ logger.error(`解析失败: ${url}, 原因: ${result.msg}`);
689
947
  }
690
948
  }
691
949
  const enableForward = config.enableForward && session.platform === 'onebot';
@@ -711,6 +969,9 @@ function apply(ctx, config) {
711
969
  }
712
970
  return;
713
971
  }
972
+ if (config.debug) {
973
+ logger.debug(`成功解析: ${items.length}个`);
974
+ }
714
975
  for (const item of items) {
715
976
  try {
716
977
  if (enableForward) {
@@ -723,6 +984,15 @@ function apply(ctx, config) {
723
984
  forwardMessages.push(buildForwardNode(session, koishi_1.h.image(item.images[i]), botName));
724
985
  }
725
986
  }
987
+ if (item.live_photo?.length && forwardMessages.length < 100) {
988
+ for (let i = 0; i < item.live_photo.length && forwardMessages.length < 100; i++) {
989
+ const live = item.live_photo[i];
990
+ forwardMessages.push(buildForwardNode(session, koishi_1.h.image(live.image), botName));
991
+ if (live.video && forwardMessages.length < 100) {
992
+ forwardMessages.push(buildForwardNode(session, koishi_1.h.video(live.video), botName));
993
+ }
994
+ }
995
+ }
726
996
  if (item.video && config.showVideoFile && forwardMessages.length < 100) {
727
997
  let videoElem;
728
998
  if (config.downloadVideoBeforeSend) {
@@ -732,7 +1002,7 @@ function apply(ctx, config) {
732
1002
  videoElem = koishi_1.h.file(filePath);
733
1003
  }
734
1004
  catch (error) {
735
- ctx.logger.error(`视频下载失败: ${getErrorMessage(error)}`);
1005
+ logger.error(`视频下载失败: ${getErrorMessage(error)}`);
736
1006
  videoElem = koishi_1.h.video(item.video);
737
1007
  }
738
1008
  }
@@ -752,6 +1022,16 @@ function apply(ctx, config) {
752
1022
  if (item.type === 'image' && item.images?.length) {
753
1023
  await sendTimeout(session, (0, koishi_1.h)('message', ...item.images.map((url) => koishi_1.h.image(url))));
754
1024
  }
1025
+ else if (item.live_photo?.length) {
1026
+ for (const live of item.live_photo) {
1027
+ await sendTimeout(session, koishi_1.h.image(live.image));
1028
+ await delay(300);
1029
+ if (live.video) {
1030
+ await sendTimeout(session, koishi_1.h.video(live.video));
1031
+ await delay(300);
1032
+ }
1033
+ }
1034
+ }
755
1035
  else {
756
1036
  if (item.cover) {
757
1037
  await sendTimeout(session, koishi_1.h.image(item.cover));
@@ -766,7 +1046,7 @@ function apply(ctx, config) {
766
1046
  videoElem = koishi_1.h.file(filePath);
767
1047
  }
768
1048
  catch (error) {
769
- ctx.logger.error(`视频下载失败: ${getErrorMessage(error)}`);
1049
+ logger.error(`视频下载失败: ${getErrorMessage(error)}`);
770
1050
  videoElem = koishi_1.h.video(item.video);
771
1051
  }
772
1052
  }
@@ -780,7 +1060,7 @@ function apply(ctx, config) {
780
1060
  }
781
1061
  }
782
1062
  catch (error) {
783
- ctx.logger.error(`处理内容失败: ${getErrorMessage(error)}`);
1063
+ logger.error(`处理内容失败: ${getErrorMessage(error)}`);
784
1064
  await sendTimeout(session, `❌ 处理${item.type}内容失败: ${getErrorMessage(error)}`);
785
1065
  }
786
1066
  }
@@ -789,7 +1069,7 @@ function apply(ctx, config) {
789
1069
  await sendTimeout(session, (0, koishi_1.h)('message', { forward: true }, forwardMessages.slice(0, 100)));
790
1070
  }
791
1071
  catch (error) {
792
- ctx.logger.error(`合并转发失败: ${getErrorMessage(error)}`);
1072
+ logger.error(`合并转发失败: ${getErrorMessage(error)}`);
793
1073
  for (const node of forwardMessages) {
794
1074
  await sendTimeout(session, node.data.content);
795
1075
  await delay(500);
@@ -803,6 +1083,9 @@ function apply(ctx, config) {
803
1083
  const urls = extractUrl(session.content.trim(), config.enableBvAvParse);
804
1084
  if (!urls.length)
805
1085
  return;
1086
+ if (config.debug) {
1087
+ logger.debug(`收到消息,提取到URL: ${urls.length}个`);
1088
+ }
806
1089
  const key = `${session.platform}:${session.userId}:${session.channelId}`;
807
1090
  const uniqueUrls = [...new Set(urls)];
808
1091
  if (linkBuffer.has(key)) {
@@ -812,6 +1095,9 @@ function apply(ctx, config) {
812
1095
  buffer.urls.push(...newUrls);
813
1096
  clearTimeout(buffer.timer);
814
1097
  buffer.timer = setTimeout(() => flush(session), config.messageBufferDelay * 1000);
1098
+ if (config.debug) {
1099
+ logger.debug(`缓冲中添加新URL: ${newUrls.length}个`);
1100
+ }
815
1101
  }
816
1102
  return;
817
1103
  }
@@ -825,6 +1111,9 @@ function apply(ctx, config) {
825
1111
  timer: setTimeout(() => flush(session), config.messageBufferDelay * 1000),
826
1112
  tipMsgId
827
1113
  });
1114
+ if (config.debug) {
1115
+ logger.debug(`创建新缓冲,等待处理: ${uniqueUrls.length}个`);
1116
+ }
828
1117
  });
829
1118
  ctx.command('parse <url>', '手动解析视频链接')
830
1119
  .action(async ({ session }, url) => {
@@ -859,7 +1148,7 @@ function apply(ctx, config) {
859
1148
  fs_1.default.unlinkSync(path_1.default.join(tempDir, file));
860
1149
  }
861
1150
  catch (error) {
862
- ctx.logger.error(`清理临时文件失败: ${file}, ${getErrorMessage(error)}`);
1151
+ logger.error(`清理临时文件失败: ${file}, ${getErrorMessage(error)}`);
863
1152
  }
864
1153
  });
865
1154
  }, 1800000);
@@ -867,7 +1156,7 @@ function apply(ctx, config) {
867
1156
  setInterval(clearAllCache, config.autoClearCacheInterval * 60000);
868
1157
  }
869
1158
  process.on('exit', clearAllCache);
870
- ctx.logger.info('视频解析插件已加载');
1159
+ logger.info('视频解析插件已加载');
871
1160
  }
872
1161
  module.exports = {
873
1162
  name: exports.name,
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.6",
4
+ "version": "0.4.7",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [