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 +2 -2
- package/lib/index.js +53 -21
- package/package.json +1 -1
- package/readme.md +2 -1
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
|
-
|
|
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-
|
|
113
|
-
{ pattern: /bili(?:22|23|33)\.cn\/([0-9a-zA-
|
|
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-
|
|
117
|
-
{ pattern: /kuaishou\.com\/short-video\/([0-9a-zA-
|
|
118
|
-
{ pattern: /v\.kuaishou\.com\/([0-9a-zA-
|
|
119
|
-
{ pattern: /xiaohongshu\.com\/discovery\/item\/([0-9a-zA-
|
|
120
|
-
{ pattern: /xhslink\.com\/([0-9a-zA-
|
|
121
|
-
{ pattern: /weibo\.com\/\d+\/([0-9a-zA-
|
|
122
|
-
{ pattern: /video\.weibo\.com\/show\?fid=([0-9a-zA-
|
|
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-
|
|
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-
|
|
131
|
-
{ pattern: /huya\.com\/video\/([0-9a-zA-
|
|
132
|
-
{ pattern: /haokan\.baidu\.com\/v\?vid=([0-9a-zA-
|
|
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 (
|
|
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
|
-
|
|
561
|
+
apiUrl = custom.apiUrl;
|
|
530
562
|
}
|
|
531
|
-
const
|
|
532
|
-
return { apiUrl
|
|
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
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
|
-
| `
|
|
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
|
| 配置项 | 类型 | 默认值 | 说明 |
|