koishi-plugin-video-parser-all 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +38 -4
- package/lib/index.js +56 -49
- package/package.json +1 -1
- package/readme.md +2 -2
package/lib/index.d.ts
CHANGED
|
@@ -28,11 +28,28 @@ export declare const Config: Schema<{
|
|
|
28
28
|
} & {
|
|
29
29
|
primaryApiUrl?: string | null | undefined;
|
|
30
30
|
backupApiUrl?: string | null | undefined;
|
|
31
|
-
|
|
31
|
+
platformDedicatedFirst?: ({
|
|
32
|
+
bilibili?: boolean | null | undefined;
|
|
33
|
+
douyin?: boolean | null | undefined;
|
|
34
|
+
kuaishou?: boolean | null | undefined;
|
|
35
|
+
xiaohongshu?: boolean | null | undefined;
|
|
36
|
+
weibo?: boolean | null | undefined;
|
|
37
|
+
xigua?: boolean | null | undefined;
|
|
38
|
+
youtube?: boolean | null | undefined;
|
|
39
|
+
tiktok?: boolean | null | undefined;
|
|
40
|
+
acfun?: boolean | null | undefined;
|
|
41
|
+
zhihu?: boolean | null | undefined;
|
|
42
|
+
weishi?: boolean | null | undefined;
|
|
43
|
+
huya?: boolean | null | undefined;
|
|
44
|
+
haokan?: boolean | null | undefined;
|
|
45
|
+
meipai?: boolean | null | undefined;
|
|
46
|
+
twitter?: boolean | null | undefined;
|
|
47
|
+
instagram?: boolean | null | undefined;
|
|
48
|
+
doubao?: boolean | null | undefined;
|
|
49
|
+
} & import("cosmokit").Dict) | null | undefined;
|
|
32
50
|
customApis?: ({
|
|
33
51
|
platform?: "bilibili" | "douyin" | "kuaishou" | "xiaohongshu" | "weibo" | "xigua" | "youtube" | "tiktok" | "acfun" | "zhihu" | "weishi" | "huya" | "haokan" | "meipai" | "twitter" | "instagram" | "doubao" | null | undefined;
|
|
34
52
|
apiUrl?: string | null | undefined;
|
|
35
|
-
useDedicatedFirst?: boolean | null | undefined;
|
|
36
53
|
} & import("cosmokit").Dict)[] | null | undefined;
|
|
37
54
|
} & {
|
|
38
55
|
waitingTipText?: string | null | undefined;
|
|
@@ -68,11 +85,28 @@ export declare const Config: Schema<{
|
|
|
68
85
|
} & {
|
|
69
86
|
primaryApiUrl: string;
|
|
70
87
|
backupApiUrl: string;
|
|
71
|
-
|
|
88
|
+
platformDedicatedFirst: Schemastery.ObjectT<{
|
|
89
|
+
bilibili: Schema<boolean, boolean>;
|
|
90
|
+
douyin: Schema<boolean, boolean>;
|
|
91
|
+
kuaishou: Schema<boolean, boolean>;
|
|
92
|
+
xiaohongshu: Schema<boolean, boolean>;
|
|
93
|
+
weibo: Schema<boolean, boolean>;
|
|
94
|
+
xigua: Schema<boolean, boolean>;
|
|
95
|
+
youtube: Schema<boolean, boolean>;
|
|
96
|
+
tiktok: Schema<boolean, boolean>;
|
|
97
|
+
acfun: Schema<boolean, boolean>;
|
|
98
|
+
zhihu: Schema<boolean, boolean>;
|
|
99
|
+
weishi: Schema<boolean, boolean>;
|
|
100
|
+
huya: Schema<boolean, boolean>;
|
|
101
|
+
haokan: Schema<boolean, boolean>;
|
|
102
|
+
meipai: Schema<boolean, boolean>;
|
|
103
|
+
twitter: Schema<boolean, boolean>;
|
|
104
|
+
instagram: Schema<boolean, boolean>;
|
|
105
|
+
doubao: Schema<boolean, boolean>;
|
|
106
|
+
}>;
|
|
72
107
|
customApis: Schemastery.ObjectT<{
|
|
73
108
|
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
109
|
apiUrl: Schema<string, string>;
|
|
75
|
-
useDedicatedFirst: Schema<boolean, boolean>;
|
|
76
110
|
}>[];
|
|
77
111
|
} & {
|
|
78
112
|
waitingTipText: string;
|
package/lib/index.js
CHANGED
|
@@ -48,7 +48,25 @@ exports.Config = koishi_1.Schema.intersect([
|
|
|
48
48
|
koishi_1.Schema.object({
|
|
49
49
|
primaryApiUrl: koishi_1.Schema.string().default('https://api.bugpk.com/api/short_videos').description('主 API 地址'),
|
|
50
50
|
backupApiUrl: koishi_1.Schema.string().default('https://api.bugpk.com/api/svparse').description('备用主 API 地址(仅支持抖音/小红书/ins/即梦)'),
|
|
51
|
-
|
|
51
|
+
platformDedicatedFirst: koishi_1.Schema.object({
|
|
52
|
+
bilibili: koishi_1.Schema.boolean().default(false).description('哔哩哔哩'),
|
|
53
|
+
douyin: koishi_1.Schema.boolean().default(false).description('抖音'),
|
|
54
|
+
kuaishou: koishi_1.Schema.boolean().default(false).description('快手'),
|
|
55
|
+
xiaohongshu: koishi_1.Schema.boolean().default(false).description('小红书'),
|
|
56
|
+
weibo: koishi_1.Schema.boolean().default(false).description('微博'),
|
|
57
|
+
xigua: koishi_1.Schema.boolean().default(false).description('西瓜视频'),
|
|
58
|
+
youtube: koishi_1.Schema.boolean().default(false).description('YouTube'),
|
|
59
|
+
tiktok: koishi_1.Schema.boolean().default(false).description('TikTok'),
|
|
60
|
+
acfun: koishi_1.Schema.boolean().default(false).description('AcFun'),
|
|
61
|
+
zhihu: koishi_1.Schema.boolean().default(false).description('知乎'),
|
|
62
|
+
weishi: koishi_1.Schema.boolean().default(false).description('微视'),
|
|
63
|
+
huya: koishi_1.Schema.boolean().default(false).description('虎牙'),
|
|
64
|
+
haokan: koishi_1.Schema.boolean().default(false).description('好看视频'),
|
|
65
|
+
meipai: koishi_1.Schema.boolean().default(false).description('美拍'),
|
|
66
|
+
twitter: koishi_1.Schema.boolean().default(false).description('Twitter/X'),
|
|
67
|
+
instagram: koishi_1.Schema.boolean().default(false).description('Instagram'),
|
|
68
|
+
doubao: koishi_1.Schema.boolean().default(false).description('豆包'),
|
|
69
|
+
}).description('各平台独立开关:是否优先使用专属 API'),
|
|
52
70
|
customApis: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
53
71
|
platform: koishi_1.Schema.union([
|
|
54
72
|
koishi_1.Schema.const('bilibili').description('哔哩哔哩'),
|
|
@@ -70,8 +88,7 @@ exports.Config = koishi_1.Schema.intersect([
|
|
|
70
88
|
koishi_1.Schema.const('doubao').description('豆包'),
|
|
71
89
|
]).description('选择平台'),
|
|
72
90
|
apiUrl: koishi_1.Schema.string().description('API 地址'),
|
|
73
|
-
|
|
74
|
-
})).default([]).description('自定义平台专属 API,可覆盖默认专属 API,并可单独设定优先策略'),
|
|
91
|
+
})).default([]).description('自定义平台专属 API 地址,留空则使用内置默认专属 API'),
|
|
75
92
|
}).description('API 选择设置'),
|
|
76
93
|
koishi_1.Schema.object({
|
|
77
94
|
waitingTipText: koishi_1.Schema.string().default('正在解析视频,请稍候...').description('解析等待提示'),
|
|
@@ -108,45 +125,44 @@ const urlCache = new lru_cache_1.LRUCache({
|
|
|
108
125
|
function linkTypeParser(content) {
|
|
109
126
|
content = content.replace(/\\\//g, '/');
|
|
110
127
|
const rules = [
|
|
111
|
-
{ pattern: /bilibili\.com\/video\/([ab]v[0-9a-zA-
|
|
112
|
-
{ pattern: /b23\.tv\/
|
|
113
|
-
{ pattern: /bili
|
|
114
|
-
{ pattern: /
|
|
115
|
-
{ pattern: /douyin\.com\/
|
|
116
|
-
{ pattern: /
|
|
117
|
-
{ pattern: /kuaishou\.com\/
|
|
118
|
-
{ pattern: /
|
|
119
|
-
{ pattern: /
|
|
120
|
-
{ pattern: /
|
|
121
|
-
{ pattern: /weibo\.com
|
|
122
|
-
{ pattern: /
|
|
123
|
-
{ pattern: /
|
|
124
|
-
{ pattern: /
|
|
125
|
-
{ pattern: /
|
|
126
|
-
{ pattern: /tiktok\.com
|
|
127
|
-
{ pattern: /
|
|
128
|
-
{ pattern: /
|
|
129
|
-
{ pattern: /
|
|
130
|
-
{ pattern: /
|
|
131
|
-
{ pattern: /
|
|
132
|
-
{ pattern: /
|
|
133
|
-
{ pattern: /
|
|
134
|
-
{ pattern: /
|
|
135
|
-
{ pattern: /
|
|
136
|
-
{ pattern: /
|
|
137
|
-
{ pattern: /doubao\.com\/video\/(\d{10,})/gi, type: 'doubao', buildUrl: (id) => `https://www.doubao.com/video/${id}` },
|
|
128
|
+
{ pattern: /https?:\/\/(?:www\.)?bilibili\.com\/video\/([ab]v[0-9a-zA-Z_-]+)/gi, type: 'bilibili' },
|
|
129
|
+
{ pattern: /https?:\/\/b23\.tv\/[0-9a-zA-Z_-]{5,}/gi, type: 'bilibili' },
|
|
130
|
+
{ pattern: /https?:\/\/bili\d+\.cn\/[0-9a-zA-Z_-]{5,}/gi, type: 'bilibili' },
|
|
131
|
+
{ pattern: /https?:\/\/(?:www\.)?douyin\.com\/video\/\d{10,}/gi, type: 'douyin' },
|
|
132
|
+
{ pattern: /https?:\/\/v\.douyin\.com\/[0-9a-zA-Z_-]{8,}/gi, type: 'douyin' },
|
|
133
|
+
{ pattern: /https?:\/\/(?:www\.)?kuaishou\.com\/short-video\/[0-9a-zA-Z_-]{10,}/gi, type: 'kuaishou' },
|
|
134
|
+
{ pattern: /https?:\/\/v\.kuaishou\.com\/[0-9a-zA-Z_-]{8,}/gi, type: 'kuaishou' },
|
|
135
|
+
{ pattern: /https?:\/\/(?:www\.)?xiaohongshu\.com\/discovery\/item\/[0-9a-zA-Z_-]{10,}/gi, type: 'xiaohongshu' },
|
|
136
|
+
{ pattern: /https?:\/\/xhslink\.com\/[0-9a-zA-Z_-]{8,}/gi, type: 'xiaohongshu' },
|
|
137
|
+
{ pattern: /https?:\/\/weibo\.com\/\d+\/[0-9a-zA-Z_-]{10,}/gi, type: 'weibo' },
|
|
138
|
+
{ pattern: /https?:\/\/video\.weibo\.com\/show\?fid=[0-9a-zA-Z_-]{10,}/gi, type: 'weibo' },
|
|
139
|
+
{ pattern: /https?:\/\/(?:www\.)?ixigua\.com\/\d{10,}/gi, type: 'xigua' },
|
|
140
|
+
{ pattern: /https?:\/\/(?:www\.)?youtube\.com\/watch\?v=[a-zA-Z0-9_-]{11}/gi, type: 'youtube' },
|
|
141
|
+
{ pattern: /https?:\/\/youtu\.be\/[a-zA-Z0-9_-]{11}/gi, type: 'youtube' },
|
|
142
|
+
{ pattern: /https?:\/\/(?:www\.)?tiktok\.com\/@[\w.]+\/video\/\d{10,}/gi, type: 'tiktok' },
|
|
143
|
+
{ pattern: /https?:\/\/vm\.tiktok\.com\/[0-9a-zA-Z_-]{8,}/gi, type: 'tiktok' },
|
|
144
|
+
{ pattern: /https?:\/\/(?:www\.)?acfun\.cn\/v\/ac\d{10,}/gi, type: 'acfun' },
|
|
145
|
+
{ pattern: /https?:\/\/(?:www\.)?zhihu\.com\/video\/\d{10,}/gi, type: 'zhihu' },
|
|
146
|
+
{ pattern: /https?:\/\/weishi\.qq\.com\/weishi\/feed\/[0-9a-zA-Z_-]{10,}/gi, type: 'weishi' },
|
|
147
|
+
{ pattern: /https?:\/\/(?:www\.)?huya\.com\/video\/[0-9a-zA-Z_-]{10,}/gi, type: 'huya' },
|
|
148
|
+
{ pattern: /https?:\/\/haokan\.baidu\.com\/v\?vid=[0-9a-zA-Z_-]{10,}/gi, type: 'haokan' },
|
|
149
|
+
{ pattern: /https?:\/\/(?:www\.)?meipai\.com\/media\/\d{10,}/gi, type: 'meipai' },
|
|
150
|
+
{ pattern: /https?:\/\/twitter\.com\/\w+\/status\/\d{10,}/gi, type: 'twitter' },
|
|
151
|
+
{ pattern: /https?:\/\/x\.com\/\w+\/status\/\d{10,}/gi, type: 'twitter' },
|
|
152
|
+
{ pattern: /https?:\/\/(?:www\.)?instagram\.com\/p\/[0-9a-zA-Z_-]{10,}/gi, type: 'instagram' },
|
|
153
|
+
{ pattern: /https?:\/\/(?:www\.)?doubao\.com\/video\/\d{10,}/gi, type: 'doubao' },
|
|
138
154
|
];
|
|
139
155
|
const matches = [];
|
|
140
156
|
const seen = new Set();
|
|
141
157
|
for (const rule of rules) {
|
|
142
158
|
let match;
|
|
159
|
+
rule.pattern.lastIndex = 0;
|
|
143
160
|
while ((match = rule.pattern.exec(content)) !== null) {
|
|
144
|
-
const
|
|
145
|
-
if (seen.has(
|
|
161
|
+
const url = match[0];
|
|
162
|
+
if (seen.has(url))
|
|
146
163
|
continue;
|
|
147
|
-
seen.add(
|
|
148
|
-
|
|
149
|
-
matches.push({ type: rule.type, url, id });
|
|
164
|
+
seen.add(url);
|
|
165
|
+
matches.push({ type: rule.type, url, id: match[1] || url });
|
|
150
166
|
}
|
|
151
167
|
}
|
|
152
168
|
return matches;
|
|
@@ -465,19 +481,9 @@ async function downloadVideoFile(videoUrl, tempDir, timeout, maxSizeMB) {
|
|
|
465
481
|
await promises_1.default.unlink(filePath).catch(() => { });
|
|
466
482
|
throw new Error(`视频文件过大(${Math.round(contentLength / 1024 / 1024)}MB),超过限制(${maxSizeMB}MB)`);
|
|
467
483
|
}
|
|
468
|
-
let downloadedSize = 0;
|
|
469
|
-
response.data.on('data', (chunk) => {
|
|
470
|
-
downloadedSize += chunk.length;
|
|
471
|
-
if (maxSizeMB > 0 && downloadedSize > maxSizeBytes) {
|
|
472
|
-
response.data.destroy();
|
|
473
|
-
writer.destroy();
|
|
474
|
-
promises_1.default.unlink(filePath).catch(() => { });
|
|
475
|
-
throw new Error(`视频文件过大,超过限制(${maxSizeMB}MB)`);
|
|
476
|
-
}
|
|
477
|
-
});
|
|
478
484
|
try {
|
|
479
485
|
await (0, promises_2.pipeline)(response.data, writer);
|
|
480
|
-
debugLog('INFO',
|
|
486
|
+
debugLog('INFO', `视频下载完成`);
|
|
481
487
|
return filePath;
|
|
482
488
|
}
|
|
483
489
|
catch (e) {
|
|
@@ -525,11 +531,12 @@ function apply(ctx, config) {
|
|
|
525
531
|
const backupSupportedPlatforms = new Set(['douyin', 'xiaohongshu', 'instagram', 'jimeng']);
|
|
526
532
|
function getPlatformConfig(type) {
|
|
527
533
|
const custom = config.customApis?.find((item) => item.platform === type);
|
|
534
|
+
let apiUrl = defaultDedicatedApis[type] || null;
|
|
528
535
|
if (custom && custom.apiUrl) {
|
|
529
|
-
|
|
536
|
+
apiUrl = custom.apiUrl;
|
|
530
537
|
}
|
|
531
|
-
const
|
|
532
|
-
return { apiUrl
|
|
538
|
+
const dedicatedFirst = config.platformDedicatedFirst?.[type] ?? false;
|
|
539
|
+
return { apiUrl, dedicatedFirst };
|
|
533
540
|
}
|
|
534
541
|
async function fetchApi(url, type) {
|
|
535
542
|
const cacheKey = url;
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -56,8 +56,8 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
|
|
|
56
56
|
|--------|------|--------|------|
|
|
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
|
-
| `
|
|
60
|
-
| `customApis` | array | [] | 自定义平台专属 API 列表。每项包含:`platform`(平台类型)、`apiUrl`(API
|
|
59
|
+
| `platformDedicatedFirst` | object | 各平台均为 `false` | 各平台独立开关:是否优先使用平台专属 API。对象键为平台标识(英文),值为布尔值。支持的键:`bilibili`(哔哩哔哩)、`douyin`(抖音)、`kuaishou`(快手)、`xiaohongshu`(小红书)、`weibo`(微博)、`xigua`(西瓜视频)、`youtube`(YouTube)、`tiktok`(TikTok)、`acfun`(AcFun)、`zhihu`(知乎)、`weishi`(微视)、`huya`(虎牙)、`haokan`(好看视频)、`meipai`(美拍)、`twitter`(Twitter/X)、`instagram`(Instagram)、`doubao`(豆包) |
|
|
60
|
+
| `customApis` | array | [] | 自定义平台专属 API 列表。每项包含:`platform`(平台类型)、`apiUrl`(API 地址)。可覆盖内置默认专属 API |
|
|
61
61
|
|
|
62
62
|
### 错误与重试设置
|
|
63
63
|
| 配置项 | 类型 | 默认值 | 说明 |
|