koishi-plugin-video-parser-all 1.0.3 → 1.0.5

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 CHANGED
@@ -15,7 +15,6 @@ export declare const Config: Schema<{
15
15
  tempDir?: string | null | undefined;
16
16
  maxVideoSize?: number | null | undefined;
17
17
  forceDownloadVideo?: boolean | null | undefined;
18
- videoLoadWaitTime?: number | null | undefined;
19
18
  } & {
20
19
  timeout?: number | null | undefined;
21
20
  videoSendTimeout?: number | null | undefined;
@@ -47,7 +46,6 @@ export declare const Config: Schema<{
47
46
  tempDir: string;
48
47
  maxVideoSize: number;
49
48
  forceDownloadVideo: boolean;
50
- videoLoadWaitTime: number;
51
49
  } & {
52
50
  timeout: number;
53
51
  videoSendTimeout: number;
package/lib/index.js CHANGED
@@ -30,8 +30,7 @@ exports.Config = koishi_1.Schema.intersect([
30
30
  videoDownloadTimeout: koishi_1.Schema.number().min(0).step(1).default(120000).description('视频下载超时(毫秒)'),
31
31
  tempDir: koishi_1.Schema.string().default('./temp_videos').description('临时视频存储目录'),
32
32
  maxVideoSize: koishi_1.Schema.number().min(0).step(1).default(0).description('最大下载视频大小(MB),0 为不限制大小'),
33
- forceDownloadVideo: koishi_1.Schema.boolean().default(true).description('强制下载视频后发送(解决B站、小红书等平台URL无法直接发送的问题)'),
34
- videoLoadWaitTime: koishi_1.Schema.number().min(0).step(1).default(180000).description('视频链接加载等待时间(毫秒),获取到视频链接后等待指定时间再发送,0为不等待'),
33
+ forceDownloadVideo: koishi_1.Schema.boolean().default(false).description('强制下载视频后发送'),
35
34
  }).description('内容显示设置'),
36
35
  koishi_1.Schema.object({
37
36
  timeout: koishi_1.Schema.number().min(0).step(1).default(180000).description('API 请求超时(毫秒)'),
@@ -77,32 +76,32 @@ function linkTypeParser(content) {
77
76
  content = content.replace(/\\\//g, '/');
78
77
  const rules = [
79
78
  { pattern: /bilibili\.com\/video\/([ab]v[0-9a-zA-Z]+)/gi, type: 'bilibili', buildUrl: (id) => `https://www.bilibili.com/video/${id}` },
80
- { pattern: /b23\.tv\/([0-9a-zA-Z]+)/gi, type: 'bilibili', buildUrl: (id) => `https://b23.tv/${id}` },
81
- { pattern: /bili(?:22|23|33)\.cn\/([0-9a-zA-Z]+)/gi, type: 'bilibili', buildUrl: (id) => `https://bili23.cn/${id}` },
82
- { pattern: /bili2233\.cn\/([0-9a-zA-Z]+)/gi, type: 'bilibili', buildUrl: (id) => `https://bili2233.cn/${id}` },
83
- { pattern: /douyin\.com\/video\/(\d+)/gi, type: 'douyin', buildUrl: (id) => `https://www.douyin.com/video/${id}` },
84
- { pattern: /v\.douyin\.com\/([0-9a-zA-Z]+)/gi, type: 'douyin', buildUrl: (id) => `https://v.douyin.com/${id}` },
85
- { pattern: /kuaishou\.com\/short-video\/([0-9a-zA-Z]+)/gi, type: 'kuaishou', buildUrl: (id) => `https://www.kuaishou.com/short-video/${id}` },
86
- { pattern: /v\.kuaishou\.com\/([0-9a-zA-Z]+)/gi, type: 'kuaishou', buildUrl: (id) => `https://v.kuaishou.com/${id}` },
87
- { pattern: /xiaohongshu\.com\/discovery\/item\/([0-9a-zA-Z]+)/gi, type: 'xiaohongshu', buildUrl: (id) => `https://www.xiaohongshu.com/discovery/item/${id}` },
88
- { pattern: /xhslink\.com\/([0-9a-zA-Z]+)/gi, type: 'xiaohongshu', buildUrl: (id) => `https://xhslink.com/${id}` },
89
- { pattern: /weibo\.com\/\d+\/([0-9a-zA-Z]+)/gi, type: 'weibo', buildUrl: (id) => `https://weibo.com/${id}` },
90
- { pattern: /video\.weibo\.com\/show\?fid=([0-9a-zA-Z]+)/gi, type: 'weibo', buildUrl: (id) => `https://video.weibo.com/show?fid=${id}` },
91
- { pattern: /ixigua\.com\/(\d+)/gi, type: 'xigua', buildUrl: (id) => `https://www.ixigua.com/${id}` },
92
- { pattern: /youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)/gi, type: 'youtube', buildUrl: (id) => `https://www.youtube.com/watch?v=${id}` },
93
- { pattern: /youtu\.be\/([a-zA-Z0-9_-]+)/gi, type: 'youtube', buildUrl: (id) => `https://youtu.be/${id}` },
94
- { pattern: /tiktok\.com\/@[\w.]+\/video\/(\d+)/gi, type: 'tiktok', buildUrl: (id) => `https://www.tiktok.com/@user/video/${id}` },
95
- { pattern: /vm\.tiktok\.com\/([0-9a-zA-Z]+)/gi, type: 'tiktok', buildUrl: (id) => `https://vm.tiktok.com/${id}` },
96
- { pattern: /acfun\.cn\/v\/(ac\d+)/gi, type: 'acfun', buildUrl: (id) => `https://www.acfun.cn/v/${id}` },
97
- { pattern: /zhihu\.com\/video\/(\d+)/gi, type: 'zhihu', buildUrl: (id) => `https://www.zhihu.com/video/${id}` },
98
- { pattern: /weishi\.qq\.com\/weishi\/feed\/([0-9a-zA-Z]+)/gi, type: 'weishi', buildUrl: (id) => `https://weishi.qq.com/weishi/feed/${id}` },
99
- { pattern: /huya\.com\/video\/([0-9a-zA-Z]+)/gi, type: 'huya', buildUrl: (id) => `https://www.huya.com/video/${id}` },
100
- { pattern: /haokan\.baidu\.com\/v\?vid=([0-9a-zA-Z]+)/gi, type: 'haokan', buildUrl: (id) => `https://haokan.baidu.com/v?vid=${id}` },
101
- { pattern: /meipai\.com\/media\/(\d+)/gi, type: 'meipai', buildUrl: (id) => `https://www.meipai.com/media/${id}` },
102
- { pattern: /twitter\.com\/\w+\/status\/(\d+)/gi, type: 'twitter', buildUrl: (id) => `https://twitter.com/i/status/${id}` },
103
- { pattern: /x\.com\/\w+\/status\/(\d+)/gi, type: 'twitter', buildUrl: (id) => `https://x.com/i/status/${id}` },
104
- { pattern: /instagram\.com\/p\/([0-9a-zA-Z_-]+)/gi, type: 'instagram', buildUrl: (id) => `https://www.instagram.com/p/${id}` },
105
- { pattern: /doubao\.com\/video\/(\d+)/gi, type: 'doubao', buildUrl: (id) => `https://www.doubao.com/video/${id}` },
79
+ { pattern: /b23\.tv\/([0-9a-zA-Z]{5,})/gi, type: 'bilibili', buildUrl: (id) => `https://b23.tv/${id}` },
80
+ { pattern: /bili(?:22|23|33)\.cn\/([0-9a-zA-Z]{5,})/gi, type: 'bilibili', buildUrl: (id) => `https://bili23.cn/${id}` },
81
+ { pattern: /bili2233\.cn\/([0-9a-zA-Z]{5,})/gi, type: 'bilibili', buildUrl: (id) => `https://bili2233.cn/${id}` },
82
+ { pattern: /douyin\.com\/video\/(\d{10,})/gi, type: 'douyin', buildUrl: (id) => `https://www.douyin.com/video/${id}` },
83
+ { pattern: /v\.douyin\.com\/([0-9a-zA-Z]{8,})/gi, type: 'douyin', buildUrl: (id) => `https://v.douyin.com/${id}/` },
84
+ { pattern: /kuaishou\.com\/short-video\/([0-9a-zA-Z]{10,})/gi, type: 'kuaishou', buildUrl: (id) => `https://www.kuaishou.com/short-video/${id}` },
85
+ { pattern: /v\.kuaishou\.com\/([0-9a-zA-Z]{8,})/gi, type: 'kuaishou', buildUrl: (id) => `https://v.kuaishou.com/${id}` },
86
+ { pattern: /xiaohongshu\.com\/discovery\/item\/([0-9a-zA-Z]{10,})/gi, type: 'xiaohongshu', buildUrl: (id) => `https://www.xiaohongshu.com/discovery/item/${id}` },
87
+ { pattern: /xhslink\.com\/([0-9a-zA-Z]{8,})/gi, type: 'xiaohongshu', buildUrl: (id) => `https://xhslink.com/${id}` },
88
+ { pattern: /weibo\.com\/\d+\/([0-9a-zA-Z]{10,})/gi, type: 'weibo', buildUrl: (id) => `https://weibo.com/${id}` },
89
+ { pattern: /video\.weibo\.com\/show\?fid=([0-9a-zA-Z]{10,})/gi, type: 'weibo', buildUrl: (id) => `https://video.weibo.com/show?fid=${id}` },
90
+ { pattern: /ixigua\.com\/(\d{10,})/gi, type: 'xigua', buildUrl: (id) => `https://www.ixigua.com/${id}` },
91
+ { pattern: /youtube\.com\/watch\?v=([a-zA-Z0-9_-]{11})/gi, type: 'youtube', buildUrl: (id) => `https://www.youtube.com/watch?v=${id}` },
92
+ { pattern: /youtu\.be\/([a-zA-Z0-9_-]{11})/gi, type: 'youtube', buildUrl: (id) => `https://youtu.be/${id}` },
93
+ { pattern: /tiktok\.com\/@[\w.]+\/video\/(\d{10,})/gi, type: 'tiktok', buildUrl: (id) => `https://www.tiktok.com/@user/video/${id}` },
94
+ { pattern: /vm\.tiktok\.com\/([0-9a-zA-Z]{8,})/gi, type: 'tiktok', buildUrl: (id) => `https://vm.tiktok.com/${id}` },
95
+ { pattern: /acfun\.cn\/v\/(ac\d{10,})/gi, type: 'acfun', buildUrl: (id) => `https://www.acfun.cn/v/${id}` },
96
+ { pattern: /zhihu\.com\/video\/(\d{10,})/gi, type: 'zhihu', buildUrl: (id) => `https://www.zhihu.com/video/${id}` },
97
+ { pattern: /weishi\.qq\.com\/weishi\/feed\/([0-9a-zA-Z]{10,})/gi, type: 'weishi', buildUrl: (id) => `https://weishi.qq.com/weishi/feed/${id}` },
98
+ { pattern: /huya\.com\/video\/([0-9a-zA-Z]{10,})/gi, type: 'huya', buildUrl: (id) => `https://www.huya.com/video/${id}` },
99
+ { pattern: /haokan\.baidu\.com\/v\?vid=([0-9a-zA-Z]{10,})/gi, type: 'haokan', buildUrl: (id) => `https://haokan.baidu.com/v?vid=${id}` },
100
+ { pattern: /meipai\.com\/media\/(\d{10,})/gi, type: 'meipai', buildUrl: (id) => `https://www.meipai.com/media/${id}` },
101
+ { pattern: /twitter\.com\/\w+\/status\/(\d{10,})/gi, type: 'twitter', buildUrl: (id) => `https://twitter.com/i/status/${id}` },
102
+ { pattern: /x\.com\/\w+\/status\/(\d{10,})/gi, type: 'twitter', buildUrl: (id) => `https://x.com/i/status/${id}` },
103
+ { pattern: /instagram\.com\/p\/([0-9a-zA-Z_-]{10,})/gi, type: 'instagram', buildUrl: (id) => `https://www.instagram.com/p/${id}` },
104
+ { pattern: /doubao\.com\/video\/(\d{10,})/gi, type: 'doubao', buildUrl: (id) => `https://www.doubao.com/video/${id}` },
106
105
  ];
107
106
  const matches = [];
108
107
  const seen = new Set();
@@ -133,6 +132,10 @@ function extractUrl(content) {
133
132
  hostname.includes('qlogo.cn')) {
134
133
  return false;
135
134
  }
135
+ if (hostname === 'v.douyin.com' && urlObj.pathname.length < 3)
136
+ return false;
137
+ if (hostname === 'www.douyin.com' && urlObj.pathname === '/')
138
+ return false;
136
139
  return true;
137
140
  }
138
141
  catch {
@@ -194,7 +197,19 @@ function extractAllUrlsFromMessage(session) {
194
197
  }
195
198
  }
196
199
  }
197
- return [...new Set(urls)];
200
+ return [...new Set(urls)].filter(url => {
201
+ try {
202
+ const urlObj = new URL(url);
203
+ if (urlObj.hostname === 'v.douyin.com' && urlObj.pathname.length < 3)
204
+ return false;
205
+ if (urlObj.hostname === 'www.douyin.com' && urlObj.pathname === '/')
206
+ return false;
207
+ return true;
208
+ }
209
+ catch {
210
+ return false;
211
+ }
212
+ });
198
213
  }
199
214
  function cleanUrl(url) {
200
215
  try {
@@ -459,7 +474,7 @@ async function downloadVideoFile(videoUrl, tempDir, timeout, maxSizeMB) {
459
474
  timeout: timeout,
460
475
  headers: {
461
476
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
462
- 'Referer': 'https://www.baidu.com/',
477
+ 'Referer': 'https://www.bilibili.com/',
463
478
  },
464
479
  validateStatus: (status) => status >= 200 && status < 300,
465
480
  });
@@ -501,45 +516,6 @@ function getErrorMessage(error) {
501
516
  return error.message;
502
517
  return String(error);
503
518
  }
504
- function isSpecialPlatformVideo(url) {
505
- const specialHosts = [
506
- 'bilibili.com',
507
- 'akamaized.net',
508
- 'hdslb.com',
509
- 'xiaohongshu.com',
510
- 'xhslink.com',
511
- 'zhihu.com',
512
- 'weibo.com',
513
- 'sinaimg.cn',
514
- 'ixigua.com',
515
- 'toutiao.com',
516
- ];
517
- return specialHosts.some(host => url.includes(host));
518
- }
519
- async function getShortUrl(url) {
520
- if (!url)
521
- return '';
522
- try {
523
- const urlObj = new URL(url);
524
- if (urlObj.hostname.includes('bilibili.com')) {
525
- const bvMatch = url.match(/\/video\/(bv[0-9a-zA-Z]+)/i);
526
- if (bvMatch)
527
- return `https://b23.tv/${bvMatch[1]}`;
528
- }
529
- if (urlObj.hostname.includes('douyin.com')) {
530
- const idMatch = url.match(/\/video\/(\d+)/);
531
- if (idMatch)
532
- return `https://v.douyin.com/${idMatch[1].substring(0, 8)}/`;
533
- }
534
- if (urlObj.hostname.includes('xiaohongshu.com')) {
535
- const idMatch = url.match(/\/item\/([0-9a-zA-Z]+)/);
536
- if (idMatch)
537
- return `https://xhslink.com/${idMatch[1].substring(0, 8)}`;
538
- }
539
- }
540
- catch { }
541
- return url;
542
- }
543
519
  function apply(ctx, config) {
544
520
  debugEnabled = config.debug || false;
545
521
  debugLog('INFO', '插件初始化开始');
@@ -617,13 +593,11 @@ function apply(ctx, config) {
617
593
  return { success: false, msg: result.msg, url };
618
594
  }
619
595
  const text = generateFormattedText(result.data, config.unifiedMessageFormat);
620
- const shortUrl = await getShortUrl(result.data.video);
621
596
  return {
622
597
  success: true,
623
598
  data: {
624
599
  text,
625
- parsed: result.data,
626
- shortUrl
600
+ parsed: result.data
627
601
  }
628
602
  };
629
603
  }
@@ -665,41 +639,52 @@ function apply(ctx, config) {
665
639
  }
666
640
  return null;
667
641
  }
668
- async function sendVideoFile(session, videoUrl, shortUrl) {
642
+ async function sendVideoFile(session, videoUrl) {
669
643
  if (!videoUrl)
670
644
  throw new Error('视频链接为空');
671
- if (config.videoLoadWaitTime > 0) {
672
- await delay(config.videoLoadWaitTime);
673
- }
674
- if (shortUrl) {
675
- await sendWithTimeout(session, `视频链接:${shortUrl}`).catch(() => { });
676
- }
677
645
  if (!config.showVideoFile) {
678
- return null;
646
+ return await sendWithTimeout(session, `视频链接:${videoUrl}`);
679
647
  }
680
- const shouldForceDownload = config.forceDownloadVideo || isSpecialPlatformVideo(videoUrl);
681
- if (!shouldForceDownload) {
648
+ const sendLinkAsFallback = async () => {
649
+ await sendWithTimeout(session, `视频链接:${videoUrl}`).catch(() => { });
650
+ };
651
+ const tryDownloadAndSend = async () => {
652
+ let tempFilePath = null;
682
653
  try {
683
- debugLog('INFO', `尝试直接发送视频URL: ${videoUrl.substring(0, 100)}...`);
684
- return await sendWithTimeout(session, koishi_1.h.video(videoUrl));
654
+ tempFilePath = await downloadVideoFile(videoUrl, config.tempDir || './temp_videos', config.videoDownloadTimeout || 120000, config.maxVideoSize || 0);
655
+ const localFile = `file://${tempFilePath}`;
656
+ debugLog('INFO', `发送本地视频文件: ${localFile}`);
657
+ return await sendWithTimeout(session, koishi_1.h.video(localFile));
658
+ }
659
+ finally {
660
+ if (tempFilePath) {
661
+ promises_1.default.unlink(tempFilePath).catch(e => debugLog('WARN', `删除临时文件失败: ${e}`));
662
+ }
663
+ }
664
+ };
665
+ if (config.forceDownloadVideo) {
666
+ try {
667
+ return await tryDownloadAndSend();
685
668
  }
686
669
  catch (err) {
687
- debugLog('ERROR', `直接发送URL失败,开始下载视频: ${getErrorMessage(err)}`);
670
+ debugLog('ERROR', `下载并发送视频失败: ${getErrorMessage(err)}`);
671
+ await sendLinkAsFallback();
688
672
  }
689
673
  }
690
674
  else {
691
- debugLog('INFO', `检测到特殊平台视频,强制下载后发送: ${videoUrl.substring(0, 100)}...`);
692
- }
693
- let tempFilePath = null;
694
- try {
695
- tempFilePath = await downloadVideoFile(videoUrl, config.tempDir || './temp_videos', config.videoDownloadTimeout || 120000, config.maxVideoSize || 0);
696
- const localFile = `file://${tempFilePath}`;
697
- debugLog('INFO', `发送本地视频文件: ${localFile}`);
698
- return await sendWithTimeout(session, koishi_1.h.video(localFile));
699
- }
700
- finally {
701
- if (tempFilePath) {
702
- promises_1.default.unlink(tempFilePath).catch(e => debugLog('WARN', `删除临时文件失败: ${e}`));
675
+ try {
676
+ debugLog('INFO', `尝试直接发送视频URL: ${videoUrl.substring(0, 100)}...`);
677
+ return await sendWithTimeout(session, koishi_1.h.video(videoUrl));
678
+ }
679
+ catch (err) {
680
+ debugLog('ERROR', `直接发送URL失败,尝试下载: ${getErrorMessage(err)}`);
681
+ try {
682
+ return await tryDownloadAndSend();
683
+ }
684
+ catch (downloadErr) {
685
+ debugLog('ERROR', `下载并发送视频也失败: ${getErrorMessage(downloadErr)}`);
686
+ await sendLinkAsFallback();
687
+ }
703
688
  }
704
689
  }
705
690
  }
@@ -708,25 +693,21 @@ function apply(ctx, config) {
708
693
  debugLog('INFO', `开始解析 ${uniqueUrls.length} 个链接`);
709
694
  const items = [];
710
695
  const errors = [];
711
- const concurrency = 3;
712
- const chunks = [];
713
- for (let i = 0; i < uniqueUrls.length; i += concurrency) {
714
- chunks.push(uniqueUrls.slice(i, i + concurrency));
715
- }
716
- for (const chunk of chunks) {
717
- const results = await Promise.all(chunk.map(url => processSingleUrl(url)));
718
- for (let idx = 0; idx < results.length; idx++) {
719
- const res = results[idx];
720
- if (res.success) {
721
- items.push(res.data);
722
- }
723
- else {
724
- const url = chunk[idx];
725
- const item = texts.parseErrorItemFormat
726
- .replace(/\$\{url\}/g, url.length > 50 ? url.slice(0, 50) + '...' : url)
727
- .replace(/\$\{msg\}/g, res.msg);
728
- errors.push(item);
729
- }
696
+ for (let i = 0; i < uniqueUrls.length; i++) {
697
+ const url = uniqueUrls[i];
698
+ debugLog('INFO', `正在解析第 ${i + 1}/${uniqueUrls.length} 个链接: ${url}`);
699
+ const result = await processSingleUrl(url);
700
+ if (result.success) {
701
+ items.push(result.data);
702
+ }
703
+ else {
704
+ const item = texts.parseErrorItemFormat
705
+ .replace(/\$\{url\}/g, url.length > 50 ? url.slice(0, 50) + '...' : url)
706
+ .replace(/\$\{msg\}/g, result.msg);
707
+ errors.push(item);
708
+ }
709
+ if (i < uniqueUrls.length - 1) {
710
+ await delay(500);
730
711
  }
731
712
  }
732
713
  if (errors.length) {
@@ -745,7 +726,6 @@ function apply(ctx, config) {
745
726
  for (const item of items) {
746
727
  const p = item.parsed;
747
728
  const text = item.text;
748
- const shortUrl = item.shortUrl;
749
729
  if (text && config.showImageText) {
750
730
  forwardMessages.push(buildForwardNode(session, text, botName));
751
731
  }
@@ -758,10 +738,10 @@ function apply(ctx, config) {
758
738
  forwardMessages.push(buildForwardNode(session, koishi_1.h.image(imgUrl), botName));
759
739
  }
760
740
  }
761
- if (p.video && config.showVideoFile && (p.type === 'video' || (p.type === 'live' && !p.live_photo?.length && !p.images?.length))) {
762
- videoItems.push({ parsed: p, shortUrl });
763
- if (shortUrl) {
764
- forwardMessages.push(buildForwardNode(session, `视频链接:${shortUrl}`, botName));
741
+ if (p.video) {
742
+ forwardMessages.push(buildForwardNode(session, `视频链接:${p.video}`, botName));
743
+ if (config.showVideoFile && (p.type === 'video' || (p.type === 'live' && !p.live_photo?.length && !p.images?.length))) {
744
+ videoItems.push(p);
765
745
  }
766
746
  }
767
747
  }
@@ -779,9 +759,9 @@ function apply(ctx, config) {
779
759
  }
780
760
  }
781
761
  }
782
- for (const item of videoItems) {
762
+ for (const p of videoItems) {
783
763
  try {
784
- await sendVideoFile(session, item.parsed.video, item.shortUrl);
764
+ await sendVideoFile(session, p.video);
785
765
  }
786
766
  catch (err) {
787
767
  debugLog('ERROR', `视频发送失败: ${getErrorMessage(err)}`);
@@ -793,7 +773,6 @@ function apply(ctx, config) {
793
773
  for (const item of items) {
794
774
  const p = item.parsed;
795
775
  const text = item.text;
796
- const shortUrl = item.shortUrl;
797
776
  if (text && config.showImageText) {
798
777
  await sendWithTimeout(session, text);
799
778
  await delay(300);
@@ -803,11 +782,16 @@ function apply(ctx, config) {
803
782
  await delay(300);
804
783
  }
805
784
  if (p.video && (p.type === 'video' || (p.type === 'live' && !p.live_photo?.length && !p.images?.length))) {
806
- try {
807
- await sendVideoFile(session, p.video, shortUrl);
785
+ if (config.showVideoFile) {
786
+ try {
787
+ await sendVideoFile(session, p.video);
788
+ }
789
+ catch (err) {
790
+ debugLog('ERROR', `视频发送失败: ${getErrorMessage(err)}`);
791
+ }
808
792
  }
809
- catch (err) {
810
- debugLog('ERROR', `视频发送失败: ${getErrorMessage(err)}`);
793
+ else {
794
+ await sendWithTimeout(session, `视频链接:${p.video}`);
811
795
  }
812
796
  await delay(500);
813
797
  }
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.0.3",
4
+ "version": "1.0.5",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
package/readme.md CHANGED
@@ -11,8 +11,8 @@
11
11
  - 📤 支持OneBot平台消息合并转发,优化多图文展示体验
12
12
  - 💬 所有提示文案均可自定义,适配多语言场景
13
13
  - 🔁 消息发送支持自动重试,与API重试配置联动,增强稳定性
14
- - 🚀 内置LRU内存缓存,避免短时间内重复解析同一链接;并发控制,防止资源耗尽
15
- - ⚡ 智能视频发送策略:普通平台优先直接发送URL,特殊平台自动降级为本地文件发送
14
+ - 🚀 内置LRU内存缓存,避免短时间内重复解析同一链接;串行解析防止API限流
15
+ - ⚡ 智能视频发送策略:优先直接发送URL,失败自动降级为本地文件发送
16
16
  - 🛡️ 可选视频大小限制,防止超大文件占满服务器磁盘;自动清理所有临时文件
17
17
 
18
18
  ### English
@@ -24,8 +24,8 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
24
24
  - 📤 Support OneBot message forwarding for better image/video display
25
25
  - 💬 All prompt texts are customizable for multilingual scenarios
26
26
  - 🔁 Message sending supports automatic retries, linked with API retry configuration for improved stability
27
- - 🚀 Built-in LRU memory cache to avoid repeated parsing of the same URL; concurrency control to prevent resource exhaustion
28
- - ⚡ Smart video sending strategy: priority to send URL directly for common platforms, auto downgrade to local file for special platforms
27
+ - 🚀 Built-in LRU memory cache to avoid repeated parsing of the same URL; serial parsing to prevent API rate limiting
28
+ - ⚡ Smart video sending strategy: priority to send URL directly, auto downgrade to local file on failure
29
29
  - 🛡️ Optional video size limit to prevent oversized files from filling up server disk; automatic cleanup of all temporary files
30
30
 
31
31
  ## 项目仓库 (Repository)
@@ -62,7 +62,7 @@ This is a **multi-platform video/image parsing plugin** developed for the Koishi
62
62
  | `videoDownloadTimeout` | number | 120000 | 视频下载超时(毫秒) |
63
63
  | `tempDir` | string | `./temp_videos` | 临时视频存储目录 |
64
64
  | `maxVideoSize` | number | 0 | 最大下载视频大小(MB),0 为不限制大小 |
65
- | `forceDownloadVideo` | boolean | true | 强制下载视频后发送(解决B站、小红书等平台URL无法直接发送的问题) |
65
+ | `forceDownloadVideo` | boolean | false | 强制下载视频后发送 |
66
66
  | `videoLoadWaitTime` | number | 180000 | 视频链接加载等待时间(毫秒),获取到视频链接后等待指定时间再发送,0为不等待 |
67
67
 
68
68
  ### 网络与 API 设置