koishi-plugin-video-parser-all 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -29,10 +29,10 @@ export declare const Config: Schema<{
29
29
  primaryApiUrl?: string | null | undefined;
30
30
  backupApiUrl?: string | null | undefined;
31
31
  useDedicatedApiFirst?: boolean | null | undefined;
32
+ platformDedicatedFirst?: import("cosmokit").Dict<boolean, string> | null | undefined;
32
33
  customApis?: ({
33
34
  platform?: "bilibili" | "douyin" | "kuaishou" | "xiaohongshu" | "weibo" | "xigua" | "youtube" | "tiktok" | "acfun" | "zhihu" | "weishi" | "huya" | "haokan" | "meipai" | "twitter" | "instagram" | "doubao" | null | undefined;
34
35
  apiUrl?: string | null | undefined;
35
- useDedicatedFirst?: boolean | null | undefined;
36
36
  } & import("cosmokit").Dict)[] | null | undefined;
37
37
  } & {
38
38
  waitingTipText?: string | null | undefined;
@@ -69,10 +69,10 @@ export declare const Config: Schema<{
69
69
  primaryApiUrl: string;
70
70
  backupApiUrl: string;
71
71
  useDedicatedApiFirst: boolean;
72
+ platformDedicatedFirst: import("cosmokit").Dict<boolean, string>;
72
73
  customApis: Schemastery.ObjectT<{
73
74
  platform: Schema<"bilibili" | "douyin" | "kuaishou" | "xiaohongshu" | "weibo" | "xigua" | "youtube" | "tiktok" | "acfun" | "zhihu" | "weishi" | "huya" | "haokan" | "meipai" | "twitter" | "instagram" | "doubao", "bilibili" | "douyin" | "kuaishou" | "xiaohongshu" | "weibo" | "xigua" | "youtube" | "tiktok" | "acfun" | "zhihu" | "weishi" | "huya" | "haokan" | "meipai" | "twitter" | "instagram" | "doubao">;
74
75
  apiUrl: Schema<string, string>;
75
- useDedicatedFirst: Schema<boolean, boolean>;
76
76
  }>[];
77
77
  } & {
78
78
  waitingTipText: string;
package/lib/index.js CHANGED
@@ -10,7 +10,6 @@ const axios_1 = __importDefault(require("axios"));
10
10
  const promises_1 = __importDefault(require("fs/promises"));
11
11
  const path_1 = __importDefault(require("path"));
12
12
  const fs_1 = require("fs");
13
- const promises_2 = require("stream/promises");
14
13
  const lru_cache_1 = require("lru-cache");
15
14
  exports.name = 'video-parser-all';
16
15
  exports.Config = koishi_1.Schema.intersect([
@@ -49,6 +48,27 @@ exports.Config = koishi_1.Schema.intersect([
49
48
  primaryApiUrl: koishi_1.Schema.string().default('https://api.bugpk.com/api/short_videos').description('主 API 地址'),
50
49
  backupApiUrl: koishi_1.Schema.string().default('https://api.bugpk.com/api/svparse').description('备用主 API 地址(仅支持抖音/小红书/ins/即梦)'),
51
50
  useDedicatedApiFirst: koishi_1.Schema.boolean().default(false).description('全局默认:是否优先使用平台专属 API(各平台可单独覆盖)'),
51
+ platformDedicatedFirst: koishi_1.Schema.dict(koishi_1.Schema.boolean())
52
+ .default({
53
+ bilibili: false,
54
+ douyin: false,
55
+ kuaishou: false,
56
+ xiaohongshu: false,
57
+ weibo: false,
58
+ xigua: false,
59
+ youtube: false,
60
+ tiktok: false,
61
+ acfun: false,
62
+ zhihu: false,
63
+ weishi: false,
64
+ huya: false,
65
+ haokan: false,
66
+ meipai: false,
67
+ twitter: false,
68
+ instagram: false,
69
+ doubao: false,
70
+ })
71
+ .description('各平台独立开关:是否优先使用专属 API(key 为平台名)'),
52
72
  customApis: koishi_1.Schema.array(koishi_1.Schema.object({
53
73
  platform: koishi_1.Schema.union([
54
74
  koishi_1.Schema.const('bilibili').description('哔哩哔哩'),
@@ -70,8 +90,7 @@ exports.Config = koishi_1.Schema.intersect([
70
90
  koishi_1.Schema.const('doubao').description('豆包'),
71
91
  ]).description('选择平台'),
72
92
  apiUrl: koishi_1.Schema.string().description('API 地址'),
73
- useDedicatedFirst: koishi_1.Schema.boolean().default(false).description('该平台优先使用此专属 API'),
74
- })).default([]).description('自定义平台专属 API,可覆盖默认专属 API,并可单独设定优先策略'),
93
+ })).default([]).description('自定义平台专属 API 地址,留空则使用内置默认专属 API'),
75
94
  }).description('API 选择设置'),
76
95
  koishi_1.Schema.object({
77
96
  waitingTipText: koishi_1.Schema.string().default('正在解析视频,请稍候...').description('解析等待提示'),
@@ -109,27 +128,26 @@ function linkTypeParser(content) {
109
128
  content = content.replace(/\\\//g, '/');
110
129
  const rules = [
111
130
  { pattern: /bilibili\.com\/video\/([ab]v[0-9a-zA-Z]+)/gi, type: 'bilibili', buildUrl: (id) => `https://www.bilibili.com/video/${id}` },
112
- { pattern: /b23\.tv\/([0-9a-zA-Z]{5,})/gi, type: 'bilibili', buildUrl: (id) => `https://b23.tv/${id}` },
113
- { pattern: /bili(?:22|23|33)\.cn\/([0-9a-zA-Z]{5,})/gi, type: 'bilibili', buildUrl: (id) => `https://bili23.cn/${id}` },
114
- { pattern: /bili2233\.cn\/([0-9a-zA-Z]{5,})/gi, type: 'bilibili', buildUrl: (id) => `https://bili2233.cn/${id}` },
131
+ { pattern: /b23\.tv\/([0-9a-zA-Z_-]{5,})/gi, type: 'bilibili', buildUrl: (id) => `https://b23.tv/${id}` },
132
+ { pattern: /bili(?:22|23|33|2233)\.cn\/([0-9a-zA-Z_-]{5,})/gi, type: 'bilibili', buildUrl: (id) => `https://bili${RegExp.$1 || ''}.cn/${id}` },
115
133
  { pattern: /douyin\.com\/video\/(\d{10,})/gi, type: 'douyin', buildUrl: (id) => `https://www.douyin.com/video/${id}` },
116
- { pattern: /v\.douyin\.com\/([0-9a-zA-Z]{8,})/gi, type: 'douyin', buildUrl: (id) => `https://v.douyin.com/${id}/` },
117
- { pattern: /kuaishou\.com\/short-video\/([0-9a-zA-Z]{10,})/gi, type: 'kuaishou', buildUrl: (id) => `https://www.kuaishou.com/short-video/${id}` },
118
- { pattern: /v\.kuaishou\.com\/([0-9a-zA-Z]{8,})/gi, type: 'kuaishou', buildUrl: (id) => `https://v.kuaishou.com/${id}` },
119
- { pattern: /xiaohongshu\.com\/discovery\/item\/([0-9a-zA-Z]{10,})/gi, type: 'xiaohongshu', buildUrl: (id) => `https://www.xiaohongshu.com/discovery/item/${id}` },
120
- { pattern: /xhslink\.com\/([0-9a-zA-Z]{8,})/gi, type: 'xiaohongshu', buildUrl: (id) => `https://xhslink.com/${id}` },
121
- { pattern: /weibo\.com\/\d+\/([0-9a-zA-Z]{10,})/gi, type: 'weibo', buildUrl: (id) => `https://weibo.com/${id}` },
122
- { pattern: /video\.weibo\.com\/show\?fid=([0-9a-zA-Z]{10,})/gi, type: 'weibo', buildUrl: (id) => `https://video.weibo.com/show?fid=${id}` },
134
+ { pattern: /v\.douyin\.com\/([0-9a-zA-Z_-]{8,})/gi, type: 'douyin', buildUrl: (id) => `https://v.douyin.com/${id}/` },
135
+ { pattern: /kuaishou\.com\/short-video\/([0-9a-zA-Z_-]{10,})/gi, type: 'kuaishou', buildUrl: (id) => `https://www.kuaishou.com/short-video/${id}` },
136
+ { pattern: /v\.kuaishou\.com\/([0-9a-zA-Z_-]{8,})/gi, type: 'kuaishou', buildUrl: (id) => `https://v.kuaishou.com/${id}` },
137
+ { pattern: /xiaohongshu\.com\/discovery\/item\/([0-9a-zA-Z_-]{10,})/gi, type: 'xiaohongshu', buildUrl: (id) => `https://www.xiaohongshu.com/discovery/item/${id}` },
138
+ { pattern: /xhslink\.com\/([0-9a-zA-Z_-]{8,})/gi, type: 'xiaohongshu', buildUrl: (id) => `https://xhslink.com/${id}` },
139
+ { pattern: /weibo\.com\/\d+\/([0-9a-zA-Z_-]{10,})/gi, type: 'weibo', buildUrl: (id) => `https://weibo.com/${id}` },
140
+ { pattern: /video\.weibo\.com\/show\?fid=([0-9a-zA-Z_-]{10,})/gi, type: 'weibo', buildUrl: (id) => `https://video.weibo.com/show?fid=${id}` },
123
141
  { pattern: /ixigua\.com\/(\d{10,})/gi, type: 'xigua', buildUrl: (id) => `https://www.ixigua.com/${id}` },
124
142
  { pattern: /youtube\.com\/watch\?v=([a-zA-Z0-9_-]{11})/gi, type: 'youtube', buildUrl: (id) => `https://www.youtube.com/watch?v=${id}` },
125
143
  { pattern: /youtu\.be\/([a-zA-Z0-9_-]{11})/gi, type: 'youtube', buildUrl: (id) => `https://youtu.be/${id}` },
126
144
  { pattern: /tiktok\.com\/@[\w.]+\/video\/(\d{10,})/gi, type: 'tiktok', buildUrl: (id) => `https://www.tiktok.com/@user/video/${id}` },
127
- { pattern: /vm\.tiktok\.com\/([0-9a-zA-Z]{8,})/gi, type: 'tiktok', buildUrl: (id) => `https://vm.tiktok.com/${id}` },
145
+ { pattern: /vm\.tiktok\.com\/([0-9a-zA-Z_-]{8,})/gi, type: 'tiktok', buildUrl: (id) => `https://vm.tiktok.com/${id}` },
128
146
  { pattern: /acfun\.cn\/v\/(ac\d{10,})/gi, type: 'acfun', buildUrl: (id) => `https://www.acfun.cn/v/${id}` },
129
147
  { pattern: /zhihu\.com\/video\/(\d{10,})/gi, type: 'zhihu', buildUrl: (id) => `https://www.zhihu.com/video/${id}` },
130
- { pattern: /weishi\.qq\.com\/weishi\/feed\/([0-9a-zA-Z]{10,})/gi, type: 'weishi', buildUrl: (id) => `https://weishi.qq.com/weishi/feed/${id}` },
131
- { pattern: /huya\.com\/video\/([0-9a-zA-Z]{10,})/gi, type: 'huya', buildUrl: (id) => `https://www.huya.com/video/${id}` },
132
- { pattern: /haokan\.baidu\.com\/v\?vid=([0-9a-zA-Z]{10,})/gi, type: 'haokan', buildUrl: (id) => `https://haokan.baidu.com/v?vid=${id}` },
148
+ { pattern: /weishi\.qq\.com\/weishi\/feed\/([0-9a-zA-Z_-]{10,})/gi, type: 'weishi', buildUrl: (id) => `https://weishi.qq.com/weishi/feed/${id}` },
149
+ { pattern: /huya\.com\/video\/([0-9a-zA-Z_-]{10,})/gi, type: 'huya', buildUrl: (id) => `https://www.huya.com/video/${id}` },
150
+ { pattern: /haokan\.baidu\.com\/v\?vid=([0-9a-zA-Z_-]{10,})/gi, type: 'haokan', buildUrl: (id) => `https://haokan.baidu.com/v?vid=${id}` },
133
151
  { pattern: /meipai\.com\/media\/(\d{10,})/gi, type: 'meipai', buildUrl: (id) => `https://www.meipai.com/media/${id}` },
134
152
  { pattern: /twitter\.com\/\w+\/status\/(\d{10,})/gi, type: 'twitter', buildUrl: (id) => `https://twitter.com/i/status/${id}` },
135
153
  { pattern: /x\.com\/\w+\/status\/(\d{10,})/gi, type: 'twitter', buildUrl: (id) => `https://x.com/i/status/${id}` },
@@ -140,6 +158,7 @@ function linkTypeParser(content) {
140
158
  const seen = new Set();
141
159
  for (const rule of rules) {
142
160
  let match;
161
+ rule.pattern.lastIndex = 0;
143
162
  while ((match = rule.pattern.exec(content)) !== null) {
144
163
  const id = match[1];
145
164
  if (seen.has(id))
@@ -476,7 +495,19 @@ async function downloadVideoFile(videoUrl, tempDir, timeout, maxSizeMB) {
476
495
  }
477
496
  });
478
497
  try {
479
- await (0, promises_2.pipeline)(response.data, writer);
498
+ await new Promise((resolve, reject) => {
499
+ const stream = require('stream');
500
+ const pipeline = stream.promises?.pipeline || require('util').promisify(stream.pipeline);
501
+ if (typeof pipeline === 'function') {
502
+ pipeline(response.data, writer).then(resolve).catch(reject);
503
+ }
504
+ else {
505
+ response.data.pipe(writer);
506
+ writer.on('finish', resolve);
507
+ writer.on('error', reject);
508
+ response.data.on('error', reject);
509
+ }
510
+ });
480
511
  debugLog('INFO', `视频下载完成,大小: ${Math.round(downloadedSize / 1024 / 1024)}MB`);
481
512
  return filePath;
482
513
  }
@@ -525,11 +556,12 @@ function apply(ctx, config) {
525
556
  const backupSupportedPlatforms = new Set(['douyin', 'xiaohongshu', 'instagram', 'jimeng']);
526
557
  function getPlatformConfig(type) {
527
558
  const custom = config.customApis?.find((item) => item.platform === type);
559
+ let apiUrl = defaultDedicatedApis[type] || null;
528
560
  if (custom && custom.apiUrl) {
529
- return { apiUrl: custom.apiUrl, dedicatedFirst: custom.useDedicatedFirst ?? false };
561
+ apiUrl = custom.apiUrl;
530
562
  }
531
- const defaultUrl = defaultDedicatedApis[type] || null;
532
- return { apiUrl: defaultUrl, dedicatedFirst: config.useDedicatedApiFirst ?? false };
563
+ const dedicatedFirst = config.platformDedicatedFirst?.[type] ?? config.useDedicatedApiFirst ?? false;
564
+ return { apiUrl, dedicatedFirst };
533
565
  }
534
566
  async function fetchApi(url, type) {
535
567
  const cacheKey = url;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-video-parser-all",
3
3
  "description": "Koishi 全平台视频解析插件,支持抖音/快手/B站/微博/小红书/剪映/YouTube/TikTok等20+平台",
4
- "version": "1.1.0",
4
+ "version": "1.1.1",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
package/readme.md CHANGED
@@ -57,7 +57,8 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
57
57
  | `primaryApiUrl` | string | `https://api.bugpk.com/api/short_videos` | 主 API 地址,解析时优先使用 |
58
58
  | `backupApiUrl` | string | `https://api.bugpk.com/api/svparse` | 备用主 API 地址,仅支持抖音、小红书、Instagram、即梦平台解析 |
59
59
  | `useDedicatedApiFirst` | boolean | false | 全局默认值:是否优先使用平台专属 API,各平台可单独覆盖该行为 |
60
- | `customApis` | array | [] | 自定义平台专属 API 列表。每项包含:`platform`(平台类型)、`apiUrl`(API 地址)、`useDedicatedFirst`(该平台是否优先使用此专属 API)。可覆盖内置默认专属 API,并独立控制专属 API 的优先策略 |
60
+ | `platformDedicatedFirst` | object | 见下方说明 | 各平台独立开关:是否优先使用专属 API(key 为平台名)。支持的 key:bilibili、douyin、kuaishou、xiaohongshu、weibo、xigua、youtube、tiktok、acfun、zhihu、weishi、huya、haokan、meipai、twitter、instagram、doubao |
61
+ | `customApis` | array | [] | 自定义平台专属 API 列表。每项包含:`platform`(平台类型)、`apiUrl`(API 地址)。可覆盖内置默认专属 API |
61
62
 
62
63
  ### 错误与重试设置
63
64
  | 配置项 | 类型 | 默认值 | 说明 |