koishi-plugin-video-parser-all 0.6.0 → 0.6.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.js +58 -236
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -22,7 +22,7 @@ exports.Config = koishi_1.Schema.intersect([
|
|
|
22
22
|
sameLinkInterval: koishi_1.Schema.number().min(0).default(180).description('相同链接重复解析间隔(秒)'),
|
|
23
23
|
}).description('基础设置'),
|
|
24
24
|
koishi_1.Schema.object({
|
|
25
|
-
unifiedMessageFormat: koishi_1.Schema.string().role('textarea').default('标题:${标题}\n作者:${作者}\n简介:${简介}\n时长:${视频时长}\n点赞:${点赞数}\n投币:${投币数}\n收藏:${收藏数}\n转发:${转发数}\n播放:${播放数}\n评论:${评论数}\n音乐:${音乐名}').description('统一消息格式(无法获取的变量会自动隐藏)\n变量介绍:\n${标题} - 内容标题\n${作者} - 作者名称\n${简介} - 内容简介\n${视频时长} - 视频时长\n${点赞数} - 点赞数量\n${投币数} -
|
|
25
|
+
unifiedMessageFormat: koishi_1.Schema.string().role('textarea').default('标题:${标题}\n作者:${作者}\n简介:${简介}\n时长:${视频时长}\n点赞:${点赞数}\n投币:${投币数}\n收藏:${收藏数}\n转发:${转发数}\n播放:${播放数}\n评论:${评论数}\n音乐:${音乐名}').description('统一消息格式(无法获取的变量会自动隐藏)\n变量介绍:\n${标题} - 内容标题\n${作者} - 作者名称\n${简介} - 内容简介\n${视频时长} - 视频时长\n${点赞数} - 点赞数量\n${投币数} - 投币数(仅B站)\n收藏数 - 收藏数量\n${转发数} - 转发/分享数量\n${播放数} - 播放数量\n${评论数} - 评论数量\n${音乐名} - 背景音乐名称'),
|
|
26
26
|
}).description('统一消息格式'),
|
|
27
27
|
koishi_1.Schema.object({
|
|
28
28
|
showImageText: koishi_1.Schema.boolean().default(true).description('显示图文内容'),
|
|
@@ -394,17 +394,16 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
394
394
|
const stat = {};
|
|
395
395
|
Object.entries(VARIABLE_MAPPING).forEach(([varName, keys]) => {
|
|
396
396
|
const value = findValueInObject(data, keys) || findValueInObject(rootData, keys);
|
|
397
|
-
stat[varName] = value;
|
|
397
|
+
stat[varName] = value ?? '';
|
|
398
398
|
});
|
|
399
399
|
let type = 'video';
|
|
400
400
|
if (data.jx?.type)
|
|
401
401
|
type = data.jx.type;
|
|
402
402
|
else if (data.type)
|
|
403
403
|
type = data.type;
|
|
404
|
-
const title =
|
|
405
|
-
const author =
|
|
406
|
-
|
|
407
|
-
desc = desc.toString().slice(0, maxDescLength);
|
|
404
|
+
const title = stat['标题'] || '无标题';
|
|
405
|
+
const author = stat['作者'] || '未知作者';
|
|
406
|
+
const desc = (stat['简介'] || title).slice(0, maxDescLength);
|
|
408
407
|
const cover = data.cover ?? data.imgurl ?? data.pic ?? data.thumbnail ?? data.cover_url ?? '';
|
|
409
408
|
let images = [];
|
|
410
409
|
const imgRaw = data.images ?? data.pics ?? data.pic_urls ?? data.image_list ?? [];
|
|
@@ -412,21 +411,20 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
412
411
|
images = imgRaw.filter(i => i && typeof i === 'string');
|
|
413
412
|
else if (imgRaw)
|
|
414
413
|
images = [String(imgRaw)];
|
|
415
|
-
let video = '';
|
|
416
|
-
|
|
417
|
-
const durationValue = data.duration ?? stat['视频时长'] ?? 0;
|
|
414
|
+
let video = data.video?.url ?? data.item?.url ?? data.url ?? data.download_url ?? data.playUrl ?? data.video_url ?? '';
|
|
415
|
+
const durationValue = stat['视频时长'] || 0;
|
|
418
416
|
const duration = typeof durationValue === 'number' ? durationValue : parseInt(durationValue) || 0;
|
|
419
417
|
const durationFormatted = formatDuration(durationValue);
|
|
420
418
|
const live_photo = data.live_photo ?? [];
|
|
421
|
-
const music =
|
|
419
|
+
const music = stat['音乐名'] || '';
|
|
422
420
|
const h_w = data.item?.h_w ?? [];
|
|
423
421
|
const quality_urls = data.quality_urls ?? {};
|
|
424
422
|
const default_quality = data.default_quality ?? '';
|
|
425
423
|
const download_url = data.download_url ?? video;
|
|
426
424
|
const play_count = stat['播放数'] ?? '';
|
|
427
|
-
const reposts_count = stat['转发数']
|
|
428
|
-
const attitudes_count = stat['点赞数']
|
|
429
|
-
const comments_count = stat['评论数']
|
|
425
|
+
const reposts_count = Number(stat['转发数']) || 0;
|
|
426
|
+
const attitudes_count = Number(stat['点赞数']) || 0;
|
|
427
|
+
const comments_count = Number(stat['评论数']) || 0;
|
|
430
428
|
return {
|
|
431
429
|
type: type,
|
|
432
430
|
rawData: rawResponse,
|
|
@@ -453,9 +451,7 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
453
451
|
};
|
|
454
452
|
}
|
|
455
453
|
function generateFormattedText(parseData, config) {
|
|
456
|
-
let format = config.unifiedMessageFormat;
|
|
457
|
-
if (!format)
|
|
458
|
-
format = '标题:${标题}\n作者:${作者}\n简介:${简介}';
|
|
454
|
+
let format = config.unifiedMessageFormat || '标题:${标题}\n作者:${作者}\n简介:${简介}';
|
|
459
455
|
let result = format;
|
|
460
456
|
const varMatches = result.match(/\$\{([^}]+)\}/g) || [];
|
|
461
457
|
varMatches.forEach((varMatch) => {
|
|
@@ -571,13 +567,6 @@ function apply(ctx, config) {
|
|
|
571
567
|
}
|
|
572
568
|
try {
|
|
573
569
|
const parseResult = parseData(resData, config.maxDescLength);
|
|
574
|
-
const hasValidContent = true;
|
|
575
|
-
if (!hasValidContent) {
|
|
576
|
-
const code = ErrorCode.NO_VIDEO_FOUND;
|
|
577
|
-
const msg = getErrorInfo(code, '链接有效但未获取到有效视频/图片内容,可能是私密/需要登录/已删除内容');
|
|
578
|
-
logger.warn(`[${code}] 解析成功但无有效内容: ${url}`);
|
|
579
|
-
return { data: null, code, msg };
|
|
580
|
-
}
|
|
581
570
|
logger.info(`[${ErrorCode.SUCCESS}] 解析成功: ${url}`);
|
|
582
571
|
return {
|
|
583
572
|
data: parseResult,
|
|
@@ -680,20 +669,17 @@ function apply(ctx, config) {
|
|
|
680
669
|
items.push(result.data);
|
|
681
670
|
}
|
|
682
671
|
else {
|
|
683
|
-
errors.push({ url,
|
|
684
|
-
logger.error(`[${result.code}] 解析失败: ${url}, 原因: ${result.msg}`);
|
|
672
|
+
errors.push({ url, msg: result.msg });
|
|
685
673
|
}
|
|
686
674
|
}
|
|
687
675
|
if (errors.length > 0) {
|
|
688
676
|
const errorLines = errors.map(err => `【${err.url.slice(0, 50)}${err.url.length > 50 ? '...' : ''}】: ${err.msg}`);
|
|
689
|
-
const errorMsg = `❌
|
|
690
|
-
logger.error(`解析失败数量: ${errors.length}, 错误码列表: ${errors.map(e => e.code).join(', ')}`);
|
|
677
|
+
const errorMsg = `❌ 解析失败:\n${errorLines.join('\n')}`;
|
|
691
678
|
await sendTimeout(session, errorMsg);
|
|
692
679
|
await delay(500);
|
|
693
680
|
}
|
|
694
681
|
if (items.length === 0) {
|
|
695
|
-
|
|
696
|
-
await sendTimeout(session, `⚠ ${failMsg}`);
|
|
682
|
+
await sendTimeout(session, '⚠ 未解析到有效内容');
|
|
697
683
|
return;
|
|
698
684
|
}
|
|
699
685
|
const enableForward = config.enableForward && session.platform === 'onebot';
|
|
@@ -704,72 +690,31 @@ function apply(ctx, config) {
|
|
|
704
690
|
if (enableForward) {
|
|
705
691
|
if (item.text)
|
|
706
692
|
forwardMessages.push(buildForwardNode(session, item.text, botName));
|
|
707
|
-
if (item.cover
|
|
693
|
+
if (item.cover)
|
|
708
694
|
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(item.cover), botName));
|
|
709
|
-
if (item.type === '图集' && item.images?.length) {
|
|
710
|
-
for (
|
|
711
|
-
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
if (item.type === 'image' && item.images?.length) {
|
|
715
|
-
for (let i = 0; i < item.images.length && forwardMessages.length < 100; i++) {
|
|
716
|
-
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(item.images[i]), botName));
|
|
695
|
+
if ((item.type === '图集' || item.type === 'image') && item.images?.length) {
|
|
696
|
+
for (const img of item.images) {
|
|
697
|
+
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(img), botName));
|
|
717
698
|
}
|
|
718
699
|
}
|
|
719
|
-
if (item.
|
|
720
|
-
if (item.live_photo?.length) {
|
|
721
|
-
for (let i = 0; i < item.live_photo.length && forwardMessages.length < 100; i++) {
|
|
722
|
-
const liveItem = item.live_photo[i];
|
|
723
|
-
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(liveItem.image), botName));
|
|
724
|
-
if (liveItem.video) {
|
|
725
|
-
try {
|
|
726
|
-
const videoElem = koishi_1.h.video(liveItem.video);
|
|
727
|
-
forwardMessages.push(buildForwardNode(session, videoElem, botName));
|
|
728
|
-
}
|
|
729
|
-
catch (e) {
|
|
730
|
-
forwardMessages.push(buildForwardNode(session, koishi_1.h.text(`视频链接: ${liveItem.video}`), botName));
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
else if (item.images?.length) {
|
|
736
|
-
for (let i = 0; i < item.images.length && forwardMessages.length < 100; i++) {
|
|
737
|
-
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(item.images[i]), botName));
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
if (item.video && config.showVideoFile && forwardMessages.length < 100) {
|
|
742
|
-
let videoElem;
|
|
700
|
+
if (item.video && config.showVideoFile) {
|
|
743
701
|
try {
|
|
744
702
|
if (config.downloadVideoBeforeSend) {
|
|
745
703
|
const filename = crypto_1.default.createHash('md5').update(item.video).digest('hex');
|
|
746
|
-
const
|
|
747
|
-
if (
|
|
748
|
-
|
|
749
|
-
forwardMessages.push(buildForwardNode(session, koishi_1.h.text(`${errorMsg}\n链接:${item.video}`), botName));
|
|
704
|
+
const dl = await downloadVideo(item.video, filename, config.userAgent, config.maxVideoSize, config.downloadThreads);
|
|
705
|
+
if (dl.code === ErrorCode.SUCCESS) {
|
|
706
|
+
forwardMessages.push(buildForwardNode(session, koishi_1.h.file(dl.filePath), botName));
|
|
750
707
|
}
|
|
751
708
|
else {
|
|
752
|
-
|
|
753
|
-
forwardMessages.push(buildForwardNode(session, videoElem, botName));
|
|
709
|
+
forwardMessages.push(buildForwardNode(session, koishi_1.h.text(`视频:${item.video}`), botName));
|
|
754
710
|
}
|
|
755
711
|
}
|
|
756
712
|
else {
|
|
757
|
-
|
|
758
|
-
if (config.maxVideoSize > 0 && fileSize > config.maxVideoSize) {
|
|
759
|
-
const code = ErrorCode.VIDEO_SIZE_EXCEEDED;
|
|
760
|
-
const errorMsg = getErrorInfo(code, `${fileSize}MB超过限制${config.maxVideoSize}MB`);
|
|
761
|
-
videoElem = koishi_1.h.text(`${errorMsg},仅发送链接:${item.video}`);
|
|
762
|
-
}
|
|
763
|
-
else {
|
|
764
|
-
videoElem = koishi_1.h.video(item.video);
|
|
765
|
-
}
|
|
713
|
+
forwardMessages.push(buildForwardNode(session, koishi_1.h.video(item.video), botName));
|
|
766
714
|
}
|
|
767
715
|
}
|
|
768
|
-
catch (
|
|
769
|
-
|
|
770
|
-
const code = ErrorCode.VIDEO_DOWNLOAD_FAILED;
|
|
771
|
-
logger.error(`[${code}] 视频处理失败: ${errorMsg}`);
|
|
772
|
-
forwardMessages.push(buildForwardNode(session, koishi_1.h.text(getErrorInfo(code, errorMsg) + `\n链接:${item.video}`), botName));
|
|
716
|
+
catch (e) {
|
|
717
|
+
forwardMessages.push(buildForwardNode(session, koishi_1.h.text(`视频:${item.video}`), botName));
|
|
773
718
|
}
|
|
774
719
|
}
|
|
775
720
|
}
|
|
@@ -778,98 +723,37 @@ function apply(ctx, config) {
|
|
|
778
723
|
await sendTimeout(session, item.text);
|
|
779
724
|
await delay(300);
|
|
780
725
|
}
|
|
781
|
-
if (item.
|
|
782
|
-
|
|
783
|
-
await
|
|
726
|
+
if (item.cover) {
|
|
727
|
+
await sendTimeout(session, koishi_1.h.image(item.cover));
|
|
728
|
+
await delay(300);
|
|
784
729
|
}
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
await delay(200);
|
|
790
|
-
if (liveItem.video) {
|
|
791
|
-
try {
|
|
792
|
-
await sendTimeout(session, koishi_1.h.video(liveItem.video));
|
|
793
|
-
}
|
|
794
|
-
catch (e) {
|
|
795
|
-
await sendTimeout(session, koishi_1.h.text(`Live Photo 视频链接: ${liveItem.video}`));
|
|
796
|
-
}
|
|
797
|
-
await delay(300);
|
|
798
|
-
}
|
|
799
|
-
}
|
|
730
|
+
if ((item.type === '图集' || item.type === 'image') && item.images?.length) {
|
|
731
|
+
for (const img of item.images) {
|
|
732
|
+
await sendTimeout(session, koishi_1.h.image(img));
|
|
733
|
+
await delay(200);
|
|
800
734
|
}
|
|
801
|
-
else if (item.images?.length) {
|
|
802
|
-
const imgMsg = (0, koishi_1.h)('message', ...item.images.map((url) => koishi_1.h.image(url)));
|
|
803
|
-
await sendTimeout(session, imgMsg);
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
else if (item.type === 'image' && item.images?.length) {
|
|
807
|
-
const imgMsg = (0, koishi_1.h)('message', ...item.images.map((url) => koishi_1.h.image(url)));
|
|
808
|
-
await sendTimeout(session, imgMsg);
|
|
809
735
|
}
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
await sendTimeout(session, koishi_1.h.
|
|
813
|
-
await delay(300);
|
|
736
|
+
if (item.video && config.showVideoFile) {
|
|
737
|
+
try {
|
|
738
|
+
await sendTimeout(session, koishi_1.h.video(item.video));
|
|
814
739
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
let videoElem;
|
|
818
|
-
if (config.downloadVideoBeforeSend) {
|
|
819
|
-
const filename = crypto_1.default.createHash('md5').update(item.video).digest('hex');
|
|
820
|
-
const downloadResult = await downloadVideo(item.video, filename, config.userAgent, config.maxVideoSize, config.downloadThreads);
|
|
821
|
-
if (downloadResult.code !== ErrorCode.SUCCESS) {
|
|
822
|
-
await sendTimeout(session, koishi_1.h.text(`${getErrorInfo(downloadResult.code)}\n链接:${item.video}`));
|
|
823
|
-
continue;
|
|
824
|
-
}
|
|
825
|
-
else {
|
|
826
|
-
videoElem = koishi_1.h.file(downloadResult.filePath);
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
else {
|
|
830
|
-
const fileSize = await getFileSize(item.video, config.userAgent);
|
|
831
|
-
if (config.maxVideoSize > 0 && fileSize > config.maxVideoSize) {
|
|
832
|
-
const code = ErrorCode.VIDEO_SIZE_EXCEEDED;
|
|
833
|
-
const errorMsg = getErrorInfo(code, `${fileSize}MB超过限制${config.maxVideoSize}MB`);
|
|
834
|
-
videoElem = koishi_1.h.text(`${errorMsg},仅发送链接:${item.video}`);
|
|
835
|
-
}
|
|
836
|
-
else {
|
|
837
|
-
videoElem = koishi_1.h.video(item.video);
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
await sendTimeout(session, videoElem);
|
|
841
|
-
}
|
|
842
|
-
catch (error) {
|
|
843
|
-
const errorMsg = getErrorMessage(error);
|
|
844
|
-
const code = ErrorCode.VIDEO_DOWNLOAD_FAILED;
|
|
845
|
-
logger.error(`[${code}] 视频处理失败: ${errorMsg}`);
|
|
846
|
-
await sendTimeout(session, koishi_1.h.text(getErrorInfo(code, errorMsg) + `\n链接:${item.video}`));
|
|
847
|
-
}
|
|
740
|
+
catch (e) {
|
|
741
|
+
await sendTimeout(session, `视频:${item.video}`);
|
|
848
742
|
}
|
|
743
|
+
await delay(500);
|
|
849
744
|
}
|
|
850
|
-
await delay(1000);
|
|
851
745
|
}
|
|
852
746
|
}
|
|
853
|
-
catch (
|
|
854
|
-
const errorMsg = getErrorMessage(error);
|
|
855
|
-
const code = ErrorCode.UNKNOWN_ERROR;
|
|
856
|
-
logger.error(`[${code}] 处理内容失败: ${errorMsg}`);
|
|
857
|
-
await sendTimeout(session, koishi_1.h.text(getErrorInfo(code, `处理${item.type}内容失败: ${errorMsg}`)));
|
|
858
|
-
}
|
|
747
|
+
catch (e) { }
|
|
859
748
|
}
|
|
860
749
|
if (enableForward && forwardMessages.length) {
|
|
861
750
|
try {
|
|
862
|
-
|
|
863
|
-
const forwardMsg = (0, koishi_1.h)('message', { forward: true }, safeForwardMessages);
|
|
864
|
-
await sendTimeout(session, forwardMsg);
|
|
751
|
+
await sendTimeout(session, (0, koishi_1.h)('message', { forward: true }, forwardMessages.slice(0, 100)));
|
|
865
752
|
}
|
|
866
|
-
catch (
|
|
867
|
-
const errorMsg = getErrorMessage(error);
|
|
868
|
-
const code = ErrorCode.FORWARD_MESSAGE_FAILED;
|
|
869
|
-
logger.error(`[${code}] 合并转发失败: ${errorMsg}`);
|
|
753
|
+
catch (e) {
|
|
870
754
|
for (const node of forwardMessages) {
|
|
871
755
|
await sendTimeout(session, node.data.content);
|
|
872
|
-
await delay(
|
|
756
|
+
await delay(300);
|
|
873
757
|
}
|
|
874
758
|
}
|
|
875
759
|
}
|
|
@@ -878,88 +762,26 @@ function apply(ctx, config) {
|
|
|
878
762
|
if (!config.enable)
|
|
879
763
|
return;
|
|
880
764
|
const content = session.content?.trim() || '';
|
|
881
|
-
|
|
882
|
-
if (urls.length
|
|
883
|
-
const allLinks = content.match(/https?:\/\/[^\s\"\'\>\]]+/gi) || [];
|
|
884
|
-
urls = allLinks.filter((u) => getPlatformType(u));
|
|
885
|
-
}
|
|
886
|
-
if (urls.length === 0)
|
|
765
|
+
const urls = extractUrl(content);
|
|
766
|
+
if (!urls.length)
|
|
887
767
|
return;
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
const buffer = linkBuffer.get(key);
|
|
891
|
-
const newUrls = urls.filter(url => !buffer.urls.includes(url));
|
|
892
|
-
if (newUrls.length) {
|
|
893
|
-
buffer.urls.push(...newUrls);
|
|
894
|
-
clearTimeout(buffer.timer);
|
|
895
|
-
buffer.timer = setTimeout(() => flush(session), config.messageBufferDelay * 1000);
|
|
896
|
-
}
|
|
897
|
-
return;
|
|
898
|
-
}
|
|
899
|
-
let tipMsgId;
|
|
900
|
-
if (config.showWaitingTip) {
|
|
901
|
-
const msg = await sendTimeout(session, config.waitingTipText);
|
|
902
|
-
tipMsgId = msg?.messageId || msg?.id || msg;
|
|
903
|
-
}
|
|
904
|
-
linkBuffer.set(key, {
|
|
905
|
-
urls,
|
|
906
|
-
timer: setTimeout(() => flush(session), config.messageBufferDelay * 1000),
|
|
907
|
-
tipMsgId
|
|
908
|
-
});
|
|
909
|
-
});
|
|
910
|
-
ctx.command('parse <url>', '手动解析视频链接')
|
|
911
|
-
.action(async ({ session }, url) => {
|
|
912
|
-
if (!url) {
|
|
913
|
-
const code = ErrorCode.INVALID_URL;
|
|
914
|
-
return getErrorInfo(code, '请输入视频链接');
|
|
915
|
-
}
|
|
916
|
-
let urls = extractUrl(url);
|
|
917
|
-
if (urls.length === 0 && hasPlatformKeyword(url)) {
|
|
918
|
-
const allLinks = url.match(/https?:\/\/[^\s\"\'\>\]]+/gi) || [];
|
|
919
|
-
urls = allLinks.filter((u) => getPlatformType(u));
|
|
920
|
-
}
|
|
921
|
-
if (urls.length === 0) {
|
|
922
|
-
const code = ErrorCode.UNSUPPORTED_PLATFORM;
|
|
923
|
-
return getErrorInfo(code, '不支持该链接');
|
|
924
|
-
}
|
|
768
|
+
if (config.showWaitingTip)
|
|
769
|
+
await sendTimeout(session, config.waitingTipText);
|
|
925
770
|
await flush(session, urls);
|
|
926
771
|
});
|
|
927
|
-
ctx.command('
|
|
928
|
-
|
|
772
|
+
ctx.command('parse <url>', '手动解析视频').action(async ({ session }, url) => {
|
|
773
|
+
const us = extractUrl(url);
|
|
774
|
+
if (!us.length)
|
|
775
|
+
return getErrorInfo(ErrorCode.INVALID_URL);
|
|
776
|
+
await flush(session, us);
|
|
777
|
+
});
|
|
778
|
+
ctx.command('clear-cache', '清空缓存').action(() => {
|
|
929
779
|
clearAllCache();
|
|
930
|
-
return
|
|
780
|
+
return '✅ 缓存已清空';
|
|
931
781
|
});
|
|
932
782
|
setInterval(() => {
|
|
933
783
|
const now = Date.now();
|
|
934
|
-
processed.forEach((
|
|
935
|
-
if (now - timestamp > 86400000)
|
|
936
|
-
processed.delete(hash);
|
|
937
|
-
});
|
|
784
|
+
processed.forEach((t, h) => now - t > 86400000 && processed.delete(h));
|
|
938
785
|
}, 3600000);
|
|
939
|
-
|
|
940
|
-
const tempDir = path_1.default.join(process.cwd(), 'temp_videos');
|
|
941
|
-
if (!fs_1.default.existsSync(tempDir))
|
|
942
|
-
return;
|
|
943
|
-
const now = Date.now();
|
|
944
|
-
fs_1.default.readdirSync(tempDir).forEach(file => {
|
|
945
|
-
try {
|
|
946
|
-
const stat = fs_1.default.statSync(path_1.default.join(tempDir, file));
|
|
947
|
-
if (now - stat.mtimeMs > 3600000) {
|
|
948
|
-
fs_1.default.unlinkSync(path_1.default.join(tempDir, file));
|
|
949
|
-
logger.info(`清理过期临时文件: ${file}`);
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
catch (error) {
|
|
953
|
-
const errorMsg = getErrorMessage(error);
|
|
954
|
-
logger.error(`[${ErrorCode.UNKNOWN_ERROR}] 清理临时文件失败: ${file}, ${errorMsg}`);
|
|
955
|
-
}
|
|
956
|
-
});
|
|
957
|
-
}, 1800000);
|
|
958
|
-
if (config.autoClearCacheInterval > 0) {
|
|
959
|
-
setInterval(() => {
|
|
960
|
-
clearAllCache();
|
|
961
|
-
logger.info(getErrorInfo(ErrorCode.SUCCESS, '自动清理缓存完成'));
|
|
962
|
-
}, config.autoClearCacheInterval * 60000);
|
|
963
|
-
}
|
|
964
|
-
logger.info(getErrorInfo(ErrorCode.SUCCESS, '视频解析插件已加载'));
|
|
786
|
+
logger.info('✅ 视频解析插件已启动');
|
|
965
787
|
}
|
package/package.json
CHANGED