koishi-plugin-video-parser-all 1.3.6 → 1.3.8
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 -12
- package/lib/index.js +9 -54
- package/package.json +5 -1
package/lib/index.d.ts
CHANGED
|
@@ -58,7 +58,7 @@ export declare const Config: Schema<{
|
|
|
58
58
|
downloadConcurrency?: number | null | undefined;
|
|
59
59
|
mediaDownloadTimeout?: number | null | undefined;
|
|
60
60
|
maxMediaSize?: number | null | undefined;
|
|
61
|
-
downloadEngine?: "internal" | "aria2" | null | undefined;
|
|
61
|
+
downloadEngine?: "internal" | "aria2" | "downloads" | null | undefined;
|
|
62
62
|
aria2Host?: string | null | undefined;
|
|
63
63
|
aria2Port?: number | null | undefined;
|
|
64
64
|
aria2Secret?: string | null | undefined;
|
|
@@ -93,11 +93,6 @@ export declare const Config: Schema<{
|
|
|
93
93
|
} & {
|
|
94
94
|
primaryApiUrl?: string | null | undefined;
|
|
95
95
|
backupApiUrl?: string | null | undefined;
|
|
96
|
-
apiKeys?: ({
|
|
97
|
-
key?: string | null | undefined;
|
|
98
|
-
weight?: number | null | undefined;
|
|
99
|
-
} & import("cosmokit").Dict)[] | null | undefined;
|
|
100
|
-
rotationMode?: "sequential" | "load_balance" | null | undefined;
|
|
101
96
|
platformDedicatedFirst?: ({
|
|
102
97
|
bilibili?: boolean | null | undefined;
|
|
103
98
|
douyin?: boolean | null | undefined;
|
|
@@ -210,7 +205,7 @@ export declare const Config: Schema<{
|
|
|
210
205
|
downloadConcurrency: number;
|
|
211
206
|
mediaDownloadTimeout: number;
|
|
212
207
|
maxMediaSize: number;
|
|
213
|
-
downloadEngine: "internal" | "aria2";
|
|
208
|
+
downloadEngine: "internal" | "aria2" | "downloads";
|
|
214
209
|
aria2Host: string;
|
|
215
210
|
aria2Port: number;
|
|
216
211
|
aria2Secret: string;
|
|
@@ -248,11 +243,6 @@ export declare const Config: Schema<{
|
|
|
248
243
|
} & {
|
|
249
244
|
primaryApiUrl: string;
|
|
250
245
|
backupApiUrl: string;
|
|
251
|
-
apiKeys: Schemastery.ObjectT<{
|
|
252
|
-
key: Schema<string, string>;
|
|
253
|
-
weight: Schema<number, number>;
|
|
254
|
-
}>[];
|
|
255
|
-
rotationMode: "sequential" | "load_balance";
|
|
256
246
|
platformDedicatedFirst: Schemastery.ObjectT<{
|
|
257
247
|
bilibili: Schema<boolean, boolean>;
|
|
258
248
|
douyin: Schema<boolean, boolean>;
|
package/lib/index.js
CHANGED
|
@@ -115,7 +115,7 @@ exports.Config = koishi_1.Schema.intersect([
|
|
|
115
115
|
}).description('媒体发送'),
|
|
116
116
|
koishi_1.Schema.object({
|
|
117
117
|
showMusicVoice: koishi_1.Schema.boolean().default(false).description('音乐链接以语音形式发送'),
|
|
118
|
-
showMusicVoiceFile: koishi_1.Schema.boolean().default(true).description('
|
|
118
|
+
showMusicVoiceFile: koishi_1.Schema.boolean().default(true).description('音乐链接是否以语音形式发送(关闭则只发送链接)'),
|
|
119
119
|
forceDownloadMusicVoice: koishi_1.Schema.boolean().default(false).description('强制下载音乐语音'),
|
|
120
120
|
}).description('音乐语音(需 silk 和 ffmpeg)'),
|
|
121
121
|
koishi_1.Schema.object({
|
|
@@ -127,6 +127,7 @@ exports.Config = koishi_1.Schema.intersect([
|
|
|
127
127
|
downloadEngine: koishi_1.Schema.union([
|
|
128
128
|
koishi_1.Schema.const('internal').description('内置下载'),
|
|
129
129
|
koishi_1.Schema.const('aria2').description('aria2 下载'),
|
|
130
|
+
koishi_1.Schema.const('downloads').description('downloads 服务下载'),
|
|
130
131
|
]).default('internal').description('下载引擎'),
|
|
131
132
|
aria2Host: koishi_1.Schema.string().default('127.0.0.1').description('aria2 RPC 地址'),
|
|
132
133
|
aria2Port: koishi_1.Schema.number().default(6800).description('aria2 RPC 端口'),
|
|
@@ -169,14 +170,6 @@ exports.Config = koishi_1.Schema.intersect([
|
|
|
169
170
|
koishi_1.Schema.object({
|
|
170
171
|
primaryApiUrl: koishi_1.Schema.string().default('https://api.bugpk.com/api/short_videos').hidden(),
|
|
171
172
|
backupApiUrl: koishi_1.Schema.string().default('https://api.bugpk.com/api/svparse').hidden(),
|
|
172
|
-
apiKeys: koishi_1.Schema.array(koishi_1.Schema.object({
|
|
173
|
-
key: koishi_1.Schema.string().required().description('API Key'),
|
|
174
|
-
weight: koishi_1.Schema.number().min(1).default(1).description('权重(负载均衡模式)'),
|
|
175
|
-
})).default([]).description('多 API 密钥(轮换使用)'),
|
|
176
|
-
rotationMode: koishi_1.Schema.union([
|
|
177
|
-
koishi_1.Schema.const('sequential').description('顺序模式(无效时切换)'),
|
|
178
|
-
koishi_1.Schema.const('load_balance').description('负载均衡模式(轮询)'),
|
|
179
|
-
]).default('sequential').description('密钥轮换模式'),
|
|
180
173
|
platformDedicatedFirst: koishi_1.Schema.object({
|
|
181
174
|
bilibili: koishi_1.Schema.boolean().default(false).description('哔哩哔哩'),
|
|
182
175
|
douyin: koishi_1.Schema.boolean().default(false).description('抖音'),
|
|
@@ -693,8 +686,6 @@ function parseFieldMapping(mappingStr) {
|
|
|
693
686
|
}
|
|
694
687
|
}
|
|
695
688
|
function apply(ctx, config) {
|
|
696
|
-
// @ts-expect-error koishi runtime supports optional service dependencies
|
|
697
|
-
ctx.using(['downloads', 'silk', 'ffmpeg'], { optional: true });
|
|
698
689
|
debugEnabled = config.debug || false;
|
|
699
690
|
debugLog('INFO', 'plugin start');
|
|
700
691
|
const dedupCache = new SimpleLRUCache(1000, config.deduplicationInterval * 1000);
|
|
@@ -740,38 +731,6 @@ function apply(ctx, config) {
|
|
|
740
731
|
logger.warn('aria2 连接失败,回退到内置下载');
|
|
741
732
|
}
|
|
742
733
|
}
|
|
743
|
-
const apiKeyList = (config.apiKeys || []).map((k) => ({
|
|
744
|
-
key: k.key,
|
|
745
|
-
weight: k.weight || 1,
|
|
746
|
-
lastUsed: 0
|
|
747
|
-
}));
|
|
748
|
-
let keyIndex = 0;
|
|
749
|
-
function getNextApiKey() {
|
|
750
|
-
if (apiKeyList.length === 0)
|
|
751
|
-
return '';
|
|
752
|
-
if (config.rotationMode === 'load_balance') {
|
|
753
|
-
const totalWeight = apiKeyList.reduce((sum, k) => sum + k.weight, 0);
|
|
754
|
-
let rand = Math.random() * totalWeight;
|
|
755
|
-
for (const k of apiKeyList) {
|
|
756
|
-
rand -= k.weight;
|
|
757
|
-
if (rand <= 0)
|
|
758
|
-
return k.key;
|
|
759
|
-
}
|
|
760
|
-
return apiKeyList[0].key;
|
|
761
|
-
}
|
|
762
|
-
else {
|
|
763
|
-
const current = apiKeyList[keyIndex % apiKeyList.length];
|
|
764
|
-
keyIndex++;
|
|
765
|
-
return current.key;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
function markApiKeyInvalid(key) {
|
|
769
|
-
if (config.rotationMode === 'sequential') {
|
|
770
|
-
const idx = apiKeyList.findIndex(k => k.key === key);
|
|
771
|
-
if (idx !== -1)
|
|
772
|
-
apiKeyList.splice(idx, 1);
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
734
|
function getPlatformConfig(type) {
|
|
776
735
|
if (type.startsWith('custom_')) {
|
|
777
736
|
const name = type.slice(7);
|
|
@@ -780,7 +739,7 @@ function apply(ctx, config) {
|
|
|
780
739
|
return {
|
|
781
740
|
apiUrl: custom.apiUrl,
|
|
782
741
|
dedicatedFirst: true,
|
|
783
|
-
apiKey: custom.apiKey ||
|
|
742
|
+
apiKey: custom.apiKey || '',
|
|
784
743
|
authHeaderType: custom.authHeaderType,
|
|
785
744
|
customHeaderName: custom.customHeaderName,
|
|
786
745
|
fieldMapping: custom.fieldMapping,
|
|
@@ -812,13 +771,13 @@ function apply(ctx, config) {
|
|
|
812
771
|
let fieldMapping = undefined;
|
|
813
772
|
if (custom && custom.apiUrl) {
|
|
814
773
|
apiUrl = custom.apiUrl;
|
|
815
|
-
apiKey = custom.apiKey ||
|
|
774
|
+
apiKey = custom.apiKey || '';
|
|
816
775
|
authHeaderType = custom.authHeaderType || 'Bearer';
|
|
817
776
|
customHeaderName = custom.customHeaderName || 'X-API-Key';
|
|
818
777
|
fieldMapping = parseFieldMapping(custom.fieldMapping);
|
|
819
778
|
}
|
|
820
779
|
else {
|
|
821
|
-
apiKey =
|
|
780
|
+
apiKey = '';
|
|
822
781
|
}
|
|
823
782
|
const dedicatedFirst = config.platformDedicatedFirst?.[type] ?? false;
|
|
824
783
|
if (!fieldMapping) {
|
|
@@ -852,18 +811,18 @@ function apply(ctx, config) {
|
|
|
852
811
|
return cleanUrl(url);
|
|
853
812
|
}
|
|
854
813
|
}
|
|
814
|
+
const extRegexCache = {};
|
|
855
815
|
async function downloadFile(url, timeout, maxSize, filePrefix, fileExts) {
|
|
856
816
|
if (!url)
|
|
857
817
|
throw new Error('链接为空');
|
|
858
818
|
await promises_1.default.mkdir(cacheDir, { recursive: true });
|
|
859
|
-
const extRegexCache = {};
|
|
860
819
|
const ext = fileExts.find(e => {
|
|
861
820
|
const r = extRegexCache[e] || (extRegexCache[e] = new RegExp('\\.' + e + '(\\?|$)', 'i'));
|
|
862
821
|
return r.test(url);
|
|
863
822
|
}) || fileExts[0];
|
|
864
823
|
const fileName = `${filePrefix}_${Date.now()}_${(0, crypto_1.randomBytes)(4).toString('hex')}.${ext}`;
|
|
865
824
|
const filePath = path_1.default.resolve(cacheDir, fileName);
|
|
866
|
-
if (ctx.downloads) {
|
|
825
|
+
if (downloadEngine === 'downloads' && ctx.downloads) {
|
|
867
826
|
try {
|
|
868
827
|
const dest = await ctx.downloads.download(url, path_1.default.join(cacheDir, fileName), {
|
|
869
828
|
headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' },
|
|
@@ -877,10 +836,10 @@ function apply(ctx, config) {
|
|
|
877
836
|
return dest;
|
|
878
837
|
}
|
|
879
838
|
catch (e) {
|
|
880
|
-
debugLog('ERROR', `downloads
|
|
839
|
+
debugLog('ERROR', `downloads 服务下载失败,回退内置下载: ${getErrorMessage(e)}`);
|
|
881
840
|
}
|
|
882
841
|
}
|
|
883
|
-
if (aria2 && config.resumeDownload) {
|
|
842
|
+
else if (downloadEngine === 'aria2' && aria2 && config.resumeDownload) {
|
|
884
843
|
try {
|
|
885
844
|
const gid = await aria2.call('aria2.addUri', [url], {
|
|
886
845
|
dir: cacheDir,
|
|
@@ -1199,10 +1158,6 @@ function apply(ctx, config) {
|
|
|
1199
1158
|
urlCacheLocal.set(cacheKey, { data: parsed, expire: Date.now() + cacheTTL });
|
|
1200
1159
|
return parsed;
|
|
1201
1160
|
}
|
|
1202
|
-
if (res.data?.code === 403 || res.data?.code === 401) {
|
|
1203
|
-
if (api.apiKey)
|
|
1204
|
-
markApiKeyInvalid(api.apiKey);
|
|
1205
|
-
}
|
|
1206
1161
|
throw new Error(res.data?.msg || `API返回错误码: ${res.data?.code}`);
|
|
1207
1162
|
}
|
|
1208
1163
|
catch (error) {
|
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.3.
|
|
4
|
+
"version": "1.3.8",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -98,11 +98,15 @@
|
|
|
98
98
|
"peerDependencies": {
|
|
99
99
|
"@koishijs/plugin-console": "^5.30.4",
|
|
100
100
|
"koishi": "^4.18.7",
|
|
101
|
+
"@koishijs/plugin-downloads": "^5.30.4",
|
|
101
102
|
"koishi-plugin-silk": "^1.0.0",
|
|
102
103
|
"koishi-plugin-ffmpeg": "^1.0.0",
|
|
103
104
|
"aria2": "^4.1.2"
|
|
104
105
|
},
|
|
105
106
|
"peerDependenciesMeta": {
|
|
107
|
+
"@koishijs/plugin-downloads": {
|
|
108
|
+
"optional": true
|
|
109
|
+
},
|
|
106
110
|
"koishi-plugin-silk": {
|
|
107
111
|
"optional": true
|
|
108
112
|
},
|