koishi-plugin-video-parser-all 0.6.7 → 0.6.9
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.js +103 -72
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -15,12 +15,12 @@ const worker_threads_1 = require("worker_threads");
|
|
|
15
15
|
exports.name = 'video-parser-all';
|
|
16
16
|
exports.Config = koishi_1.Schema.intersect([
|
|
17
17
|
koishi_1.Schema.object({
|
|
18
|
-
enable: koishi_1.Schema.boolean().default(true)
|
|
19
|
-
botName: koishi_1.Schema.string().default('视频解析机器人')
|
|
20
|
-
showWaitingTip: koishi_1.Schema.boolean().default(true)
|
|
21
|
-
waitingTipText: koishi_1.Schema.string().default('正在解析视频,请稍候...')
|
|
22
|
-
sameLinkInterval: koishi_1.Schema.number().min(0).default(180)
|
|
23
|
-
})
|
|
18
|
+
enable: koishi_1.Schema.boolean().default(true),
|
|
19
|
+
botName: koishi_1.Schema.string().default('视频解析机器人'),
|
|
20
|
+
showWaitingTip: koishi_1.Schema.boolean().default(true),
|
|
21
|
+
waitingTipText: koishi_1.Schema.string().default('正在解析视频,请稍候...'),
|
|
22
|
+
sameLinkInterval: koishi_1.Schema.number().min(0).default(180),
|
|
23
|
+
}),
|
|
24
24
|
koishi_1.Schema.object({
|
|
25
25
|
unifiedMessageFormat: koishi_1.Schema.string().role('textarea').default(`标题:${'${标题}'}
|
|
26
26
|
作者:${'${作者}'}
|
|
@@ -42,38 +42,37 @@ IP属地:${'${IP属地}'}
|
|
|
42
42
|
直播间ID:${'${直播间ID}'}
|
|
43
43
|
直播间状态:${'${直播间状态}'}
|
|
44
44
|
图片数量:${'${图片数量}'}
|
|
45
|
-
作者ID:${'${作者ID}'}
|
|
46
|
-
|
|
47
|
-
}).description('统一消息格式'),
|
|
45
|
+
作者ID:${'${作者ID}'}`),
|
|
46
|
+
}),
|
|
48
47
|
koishi_1.Schema.object({
|
|
49
|
-
showImageText: koishi_1.Schema.boolean().default(true)
|
|
50
|
-
showVideoFile: koishi_1.Schema.boolean().default(true)
|
|
51
|
-
})
|
|
48
|
+
showImageText: koishi_1.Schema.boolean().default(true),
|
|
49
|
+
showVideoFile: koishi_1.Schema.boolean().default(true),
|
|
50
|
+
}),
|
|
52
51
|
koishi_1.Schema.object({
|
|
53
|
-
maxDescLength: koishi_1.Schema.number().default(200)
|
|
54
|
-
})
|
|
52
|
+
maxDescLength: koishi_1.Schema.number().default(200),
|
|
53
|
+
}),
|
|
55
54
|
koishi_1.Schema.object({
|
|
56
|
-
timeout: koishi_1.Schema.number().min(0).default(180000)
|
|
57
|
-
videoSendTimeout: koishi_1.Schema.number().min(0).default(0)
|
|
58
|
-
userAgent: koishi_1.Schema.string().default('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36')
|
|
59
|
-
})
|
|
55
|
+
timeout: koishi_1.Schema.number().min(0).default(180000),
|
|
56
|
+
videoSendTimeout: koishi_1.Schema.number().min(0).default(0),
|
|
57
|
+
userAgent: koishi_1.Schema.string().default('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'),
|
|
58
|
+
}),
|
|
60
59
|
koishi_1.Schema.object({
|
|
61
|
-
ignoreSendError: koishi_1.Schema.boolean().default(true)
|
|
62
|
-
retryTimes: koishi_1.Schema.number().min(0).default(3)
|
|
63
|
-
retryInterval: koishi_1.Schema.number().min(0).default(1000)
|
|
64
|
-
})
|
|
60
|
+
ignoreSendError: koishi_1.Schema.boolean().default(true),
|
|
61
|
+
retryTimes: koishi_1.Schema.number().min(0).default(3),
|
|
62
|
+
retryInterval: koishi_1.Schema.number().min(0).default(1000),
|
|
63
|
+
}),
|
|
65
64
|
koishi_1.Schema.object({
|
|
66
|
-
enableForward: koishi_1.Schema.boolean().default(false)
|
|
67
|
-
downloadVideoBeforeSend: koishi_1.Schema.boolean().default(false)
|
|
68
|
-
maxVideoSize: koishi_1.Schema.number().min(0).default(0)
|
|
69
|
-
downloadThreads: koishi_1.Schema.number().min(0).max(10).default(0)
|
|
70
|
-
})
|
|
65
|
+
enableForward: koishi_1.Schema.boolean().default(false),
|
|
66
|
+
downloadVideoBeforeSend: koishi_1.Schema.boolean().default(false),
|
|
67
|
+
maxVideoSize: koishi_1.Schema.number().min(0).default(0),
|
|
68
|
+
downloadThreads: koishi_1.Schema.number().min(0).max(10).default(0),
|
|
69
|
+
}),
|
|
71
70
|
koishi_1.Schema.object({
|
|
72
|
-
messageBufferDelay: koishi_1.Schema.number().min(0).default(0)
|
|
73
|
-
})
|
|
71
|
+
messageBufferDelay: koishi_1.Schema.number().min(0).default(0),
|
|
72
|
+
}),
|
|
74
73
|
koishi_1.Schema.object({
|
|
75
|
-
autoClearCacheInterval: koishi_1.Schema.number().min(0).default(0)
|
|
76
|
-
})
|
|
74
|
+
autoClearCacheInterval: koishi_1.Schema.number().min(0).default(0),
|
|
75
|
+
}),
|
|
77
76
|
]);
|
|
78
77
|
var ErrorCode;
|
|
79
78
|
(function (ErrorCode) {
|
|
@@ -166,8 +165,7 @@ const VARIABLE_MAPPING = {
|
|
|
166
165
|
'直播间ID': ['room_id', 'live.room_id', 'data.room_id', 'live.room_id', 'data.live.room_id'],
|
|
167
166
|
'直播间状态': ['status', 'live.status', 'data.status', 'room.status', 'data.live.status'],
|
|
168
167
|
'图片数量': ['count', 'data.count', 'item.count', 'images.length', 'data.images.length', 'data.item.count'],
|
|
169
|
-
'作者ID': ['userId', 'userID', 'author_id', 'data.userId', 'item.userID', 'author.mid', 'user.mid', 'data.item.userID', 'data.author_id', 'data.user.mid', 'author.id', 'uid', 'short_id', 'data.author.id']
|
|
170
|
-
'视频备用链接': ['data.video_backup', 'video_backup']
|
|
168
|
+
'作者ID': ['userId', 'userID', 'author_id', 'data.userId', 'item.userID', 'author.mid', 'user.mid', 'data.item.userID', 'data.author_id', 'data.user.mid', 'author.id', 'uid', 'short_id', 'data.author.id']
|
|
171
169
|
};
|
|
172
170
|
function getErrorInfo(code, detail) {
|
|
173
171
|
const baseMsg = exports.ErrorMessageMap[code] || exports.ErrorMessageMap[ErrorCode.UNKNOWN_ERROR];
|
|
@@ -391,7 +389,6 @@ function formatPublishTime(value) {
|
|
|
391
389
|
if (!value)
|
|
392
390
|
return '';
|
|
393
391
|
const str = String(value).trim();
|
|
394
|
-
// 适配B站的 ctime 时间戳字段名(避免直接传入字符串"ctime")
|
|
395
392
|
if (value === 'ctime')
|
|
396
393
|
return '';
|
|
397
394
|
if (/^\d{10}$/.test(str)) {
|
|
@@ -469,11 +466,24 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
469
466
|
Object.entries(VARIABLE_MAPPING).forEach(([varName, keys]) => {
|
|
470
467
|
let value = findValueInObject(data, keys) || findValueInObject(root, keys);
|
|
471
468
|
if (varName === '图片数量' && value === undefined) {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
469
|
+
let imgCount = 0;
|
|
470
|
+
const imgSources = [
|
|
471
|
+
data.images, data.pics, data.pic_urls, data.image_list, data.imgurl,
|
|
472
|
+
root.images, root.pics, root.pic_urls, root.image_list, root.imgurl,
|
|
473
|
+
data.item?.images
|
|
474
|
+
];
|
|
475
|
+
for (const source of imgSources) {
|
|
476
|
+
if (Array.isArray(source) && source.length > 0) {
|
|
477
|
+
imgCount = source.filter(i => i && typeof i === 'string').length;
|
|
478
|
+
break;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
const cover = data.cover || data.video?.fm || data.imgurl || data.pic || data.thumbnail || data.cover_url ||
|
|
482
|
+
data.item?.cover || root.cover || data.live?.cover || data.live?.keyframe || '';
|
|
483
|
+
if (cover && imgCount > 0) {
|
|
484
|
+
imgCount = imgSources.find(source => Array.isArray(source))?.filter(i => i && typeof i === 'string' && i !== cover).length || 0;
|
|
485
|
+
}
|
|
486
|
+
value = imgCount;
|
|
477
487
|
}
|
|
478
488
|
if (value !== undefined && value !== null && value !== '' && value !== 0) {
|
|
479
489
|
stat[varName] = value;
|
|
@@ -494,9 +504,13 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
494
504
|
const title = stat['标题'] || data.note_title || data.title || data.content_title || data.video?.title ||
|
|
495
505
|
data.item?.title || root.title || data.live?.title || '无标题';
|
|
496
506
|
let author = stat['作者'] || data.author?.name || data.nickname || data.user_name || data.owner?.name ||
|
|
497
|
-
data.item?.author || root.author || data.user?.name || data.live?.author || '
|
|
498
|
-
if (typeof author === 'object'
|
|
499
|
-
author =
|
|
507
|
+
data.item?.author || root.author || data.user?.name || data.live?.author || '';
|
|
508
|
+
if (typeof author === 'object') {
|
|
509
|
+
author = '';
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
author = author || '未知作者';
|
|
513
|
+
}
|
|
500
514
|
const rawDesc = stat['简介'] || data.note_desc || data.content || data.text || data.description ||
|
|
501
515
|
data.video?.desc || data.item?.description || root.desc || root.description ||
|
|
502
516
|
data.live?.desc || (title !== '无标题' ? title : '') || '暂无简介';
|
|
@@ -514,7 +528,7 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
514
528
|
];
|
|
515
529
|
for (const source of imgSources) {
|
|
516
530
|
if (Array.isArray(source) && source.length > 0) {
|
|
517
|
-
images = source.filter(i => i && typeof i === 'string');
|
|
531
|
+
images = source.filter(i => i && typeof i === 'string' && i !== cover);
|
|
518
532
|
break;
|
|
519
533
|
}
|
|
520
534
|
}
|
|
@@ -529,11 +543,15 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
529
543
|
stat['发布时间'] = pubTime;
|
|
530
544
|
else
|
|
531
545
|
delete stat['发布时间'];
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
else
|
|
546
|
+
if (durationFormatted !== '00:00:00') {
|
|
547
|
+
stat['视频时长'] = durationFormatted;
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
536
550
|
delete stat['视频时长'];
|
|
551
|
+
}
|
|
552
|
+
if (stat['图片数量'] === 0) {
|
|
553
|
+
delete stat['图片数量'];
|
|
554
|
+
}
|
|
537
555
|
const sizeVal = stat['文件大小'];
|
|
538
556
|
if (sizeVal && !String(sizeVal).includes('MB')) {
|
|
539
557
|
const num = Number(sizeVal);
|
|
@@ -560,9 +578,6 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
560
578
|
stat['粉丝数'] = data.followers_count;
|
|
561
579
|
if (data.ip_info_str)
|
|
562
580
|
stat['IP属地'] = data.ip_info_str;
|
|
563
|
-
// 处理小红书视频备用链接
|
|
564
|
-
if (data.video_backup)
|
|
565
|
-
stat['视频备用链接'] = data.video_backup;
|
|
566
581
|
return {
|
|
567
582
|
type: type,
|
|
568
583
|
rawData: rawResponse,
|
|
@@ -599,8 +614,7 @@ function generateFormattedText(parseData, config) {
|
|
|
599
614
|
收藏:${'${收藏数}'}
|
|
600
615
|
转发:${'${转发数}'}
|
|
601
616
|
播放:${'${播放数}'}
|
|
602
|
-
评论:${'${评论数}'}
|
|
603
|
-
视频备用链接:${'${视频备用链接}'}`;
|
|
617
|
+
评论:${'${评论数}'}`;
|
|
604
618
|
}
|
|
605
619
|
let result = format;
|
|
606
620
|
const varMatches = result.match(/\$\{([^}]+)\}/g) || [];
|
|
@@ -666,14 +680,27 @@ function apply(ctx, config) {
|
|
|
666
680
|
for (let i = 0; i <= retryTimes; i++) {
|
|
667
681
|
try {
|
|
668
682
|
const params = { url, proxyurl: '' };
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
683
|
+
let res;
|
|
684
|
+
if (platform === 'xiaohongshu') {
|
|
685
|
+
res = await http.post(API_CONFIG[platform], new URLSearchParams(params), {
|
|
686
|
+
timeout: config.timeout,
|
|
687
|
+
headers: {
|
|
688
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
689
|
+
'Origin': 'https://api.bugpk.com',
|
|
690
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
else {
|
|
695
|
+
res = await http.get(API_CONFIG[platform], {
|
|
696
|
+
params,
|
|
697
|
+
timeout: config.timeout,
|
|
698
|
+
headers: {
|
|
699
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
700
|
+
'Origin': 'https://www.baidu.com'
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
}
|
|
677
704
|
return res.data;
|
|
678
705
|
}
|
|
679
706
|
catch (error) {
|
|
@@ -844,12 +871,8 @@ function apply(ctx, config) {
|
|
|
844
871
|
if (enableForward) {
|
|
845
872
|
if (item.text)
|
|
846
873
|
forwardMessages.push(buildForwardNode(session, item.text, botName));
|
|
847
|
-
if (item.cover)
|
|
874
|
+
if (item.cover && item.type !== '图集') {
|
|
848
875
|
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(item.cover), botName));
|
|
849
|
-
if ((item.type === '图集' || item.type === 'image') && item.images?.length) {
|
|
850
|
-
for (const img of item.images) {
|
|
851
|
-
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(img), botName));
|
|
852
|
-
}
|
|
853
876
|
}
|
|
854
877
|
if (item.video && config.showVideoFile) {
|
|
855
878
|
try {
|
|
@@ -871,22 +894,22 @@ function apply(ctx, config) {
|
|
|
871
894
|
forwardMessages.push(buildForwardNode(session, koishi_1.h.video(item.video), botName));
|
|
872
895
|
}
|
|
873
896
|
}
|
|
897
|
+
if ((item.type === '图集' || item.type === 'image') && item.images?.length) {
|
|
898
|
+
forwardMessages.push(buildForwardNode(session, `📸 图集内容(共${item.images.length}张)`, botName));
|
|
899
|
+
for (const img of item.images) {
|
|
900
|
+
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(img), botName));
|
|
901
|
+
}
|
|
902
|
+
}
|
|
874
903
|
}
|
|
875
904
|
else {
|
|
876
905
|
if (item.text) {
|
|
877
906
|
await sendTimeout(session, item.text);
|
|
878
907
|
await delay(300);
|
|
879
908
|
}
|
|
880
|
-
if (item.cover) {
|
|
909
|
+
if (item.cover && item.type !== '图集') {
|
|
881
910
|
await sendTimeout(session, koishi_1.h.image(item.cover));
|
|
882
911
|
await delay(300);
|
|
883
912
|
}
|
|
884
|
-
if ((item.type === '图集' || item.type === 'image') && item.images?.length) {
|
|
885
|
-
for (const img of item.images) {
|
|
886
|
-
await sendTimeout(session, koishi_1.h.image(img));
|
|
887
|
-
await delay(200);
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
913
|
if (item.video && config.showVideoFile) {
|
|
891
914
|
try {
|
|
892
915
|
await sendTimeout(session, koishi_1.h.video(item.video));
|
|
@@ -896,6 +919,14 @@ function apply(ctx, config) {
|
|
|
896
919
|
}
|
|
897
920
|
await delay(500);
|
|
898
921
|
}
|
|
922
|
+
if ((item.type === '图集' || item.type === 'image') && item.images?.length) {
|
|
923
|
+
await sendTimeout(session, `📸 图集内容(共${item.images.length}张)`);
|
|
924
|
+
await delay(300);
|
|
925
|
+
for (const img of item.images) {
|
|
926
|
+
await sendTimeout(session, koishi_1.h.image(img));
|
|
927
|
+
await delay(200);
|
|
928
|
+
}
|
|
929
|
+
}
|
|
899
930
|
}
|
|
900
931
|
}
|
|
901
932
|
catch (e) { }
|
package/package.json
CHANGED