koishi-plugin-video-parser-all 0.5.7 → 0.5.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.d.ts CHANGED
@@ -81,12 +81,7 @@ export declare enum ErrorCode {
81
81
  NO_IMAGE_FOUND = 3004,
82
82
  MESSAGE_SEND_FAILED = 4000,
83
83
  MESSAGE_SEND_TIMEOUT = 4001,
84
- FORWARD_MESSAGE_FAILED = 4002,
85
- DOUYIN_PARSE_FAILED = 5001,
86
- XIAOHONGSHU_PARSE_FAILED = 5002,
87
- BILIBILI_PARSE_FAILED = 5003,
88
- KUAISHOU_PARSE_FAILED = 5004,
89
- WEIBO_PARSE_FAILED = 5005
84
+ FORWARD_MESSAGE_FAILED = 4002
90
85
  }
91
86
  export declare const ErrorMessageMap: Record<ErrorCode, string>;
92
87
  export declare function apply(ctx: Context, config: any): void;
package/lib/index.js CHANGED
@@ -76,11 +76,6 @@ var ErrorCode;
76
76
  ErrorCode[ErrorCode["MESSAGE_SEND_FAILED"] = 4000] = "MESSAGE_SEND_FAILED";
77
77
  ErrorCode[ErrorCode["MESSAGE_SEND_TIMEOUT"] = 4001] = "MESSAGE_SEND_TIMEOUT";
78
78
  ErrorCode[ErrorCode["FORWARD_MESSAGE_FAILED"] = 4002] = "FORWARD_MESSAGE_FAILED";
79
- ErrorCode[ErrorCode["DOUYIN_PARSE_FAILED"] = 5001] = "DOUYIN_PARSE_FAILED";
80
- ErrorCode[ErrorCode["XIAOHONGSHU_PARSE_FAILED"] = 5002] = "XIAOHONGSHU_PARSE_FAILED";
81
- ErrorCode[ErrorCode["BILIBILI_PARSE_FAILED"] = 5003] = "BILIBILI_PARSE_FAILED";
82
- ErrorCode[ErrorCode["KUAISHOU_PARSE_FAILED"] = 5004] = "KUAISHOU_PARSE_FAILED";
83
- ErrorCode[ErrorCode["WEIBO_PARSE_FAILED"] = 5005] = "WEIBO_PARSE_FAILED";
84
79
  })(ErrorCode || (exports.ErrorCode = ErrorCode = {}));
85
80
  exports.ErrorMessageMap = {
86
81
  [ErrorCode.SUCCESS]: '操作成功',
@@ -103,11 +98,6 @@ exports.ErrorMessageMap = {
103
98
  [ErrorCode.MESSAGE_SEND_FAILED]: '消息发送失败',
104
99
  [ErrorCode.MESSAGE_SEND_TIMEOUT]: '消息发送超时',
105
100
  [ErrorCode.FORWARD_MESSAGE_FAILED]: '合并转发失败',
106
- [ErrorCode.DOUYIN_PARSE_FAILED]: '抖音链接解析失败',
107
- [ErrorCode.XIAOHONGSHU_PARSE_FAILED]: '小红书链接解析失败',
108
- [ErrorCode.BILIBILI_PARSE_FAILED]: 'B站链接解析失败',
109
- [ErrorCode.KUAISHOU_PARSE_FAILED]: '快手链接解析失败',
110
- [ErrorCode.WEIBO_PARSE_FAILED]: '微博链接解析失败',
111
101
  };
112
102
  const processed = new Map();
113
103
  const linkBuffer = new Map();
@@ -134,29 +124,18 @@ const API_CONFIG = {
134
124
  pipixia: 'https://api.bugpk.com/api/ppx',
135
125
  zuiyou: 'https://api.bugpk.com/api/zuiyou'
136
126
  };
137
- const PLATFORM_ERROR_CODE_MAP = {
138
- douyin: ErrorCode.DOUYIN_PARSE_FAILED,
139
- xiaohongshu: ErrorCode.XIAOHONGSHU_PARSE_FAILED,
140
- bilibili: ErrorCode.BILIBILI_PARSE_FAILED,
141
- kuaishou: ErrorCode.KUAISHOU_PARSE_FAILED,
142
- weibo: ErrorCode.WEIBO_PARSE_FAILED,
143
- toutiao: ErrorCode.API_RETURN_ERROR,
144
- pipigx: ErrorCode.API_RETURN_ERROR,
145
- pipixia: ErrorCode.API_RETURN_ERROR,
146
- zuiyou: ErrorCode.API_RETURN_ERROR
147
- };
148
127
  const VARIABLE_MAPPING = {
149
- '标题': ['title', 'Title', 'TITLE'],
150
- '作者': ['author.name', 'author', 'name', 'Author', 'Name', 'owner.name'],
151
- '简介': ['desc', 'description', 'Desc', 'Description', 'content', 'Content'],
152
- '视频时长': ['duration', 'Duration', 'time', 'Time'],
153
- '点赞数': ['like', 'Like', 'attitudes_count', 'digg_count', 'praise', 'stat.like'],
154
- '投币数': ['coin', 'Coin', 'bi', 'Bi'],
155
- '收藏数': ['collect', 'Collect', 'favorite', 'Favorite', 'star', 'Star', 'stat.collect'],
156
- '转发数': ['share', 'Share', 'forward', 'Forward', 'repost', 'stat.share', 'reposts_count'],
157
- '播放数': ['view', 'View', 'play_count', 'PlayCount', 'play'],
128
+ '标题': ['title', 'Title', 'TITLE', 'note_title', 'content_title'],
129
+ '作者': ['author.name', 'author', 'name', 'Author', 'Name', 'owner.name', 'nickname', 'user_name'],
130
+ '简介': ['desc', 'description', 'Desc', 'Description', 'content', 'Content', 'note_desc', 'text'],
131
+ '视频时长': ['duration', 'Duration', 'time', 'Time', 'video_duration'],
132
+ '点赞数': ['like', 'Like', 'attitudes_count', 'digg_count', 'praise', 'stat.like', 'liked_count'],
133
+ '投币数': ['coin', 'Coin', 'bi', 'Bi', 'stat.coin'],
134
+ '收藏数': ['collect', 'Collect', 'favorite', 'Favorite', 'star', 'Star', 'stat.collect', 'collected_count'],
135
+ '转发数': ['share', 'Share', 'forward', 'Forward', 'repost', 'stat.share', 'reposts_count', 'shared_count'],
136
+ '播放数': ['view', 'View', 'play_count', 'PlayCount', 'play', 'stat.view', 'play_times'],
158
137
  '评论数': ['comment', 'Comment', 'comments_count', 'comment_count', 'discuss', 'stat.comment'],
159
- '音乐名': ['music.title', 'music_name', 'audio_name', 'sound_name', 'muisic', 'music']
138
+ '音乐名': ['music.title', 'music_name', 'audio_name', 'sound_name', 'muisic', 'music', 'bgm_name']
160
139
  };
161
140
  function getErrorInfo(code, detail) {
162
141
  const baseMsg = exports.ErrorMessageMap[code] || exports.ErrorMessageMap[ErrorCode.UNKNOWN_ERROR];
@@ -324,19 +303,18 @@ function cleanUrl(url) {
324
303
  url = url.replace(/&amp;/g, '&');
325
304
  const urlObj = new URL(url);
326
305
  if (urlObj.hostname.includes('xiaohongshu.com')) {
327
- urlObj.searchParams.delete('source');
328
- urlObj.searchParams.delete('xhsshare');
329
- urlObj.searchParams.delete('xsec_token');
330
- urlObj.searchParams.delete('xsec_source');
306
+ urlObj.searchParams.forEach((_, key) => urlObj.searchParams.delete(key));
331
307
  return urlObj.origin + urlObj.pathname;
332
308
  }
333
309
  if (urlObj.hostname.includes('douyin.com') || urlObj.hostname.includes('v.douyin.com')) {
310
+ urlObj.searchParams.delete('source');
311
+ urlObj.searchParams.delete('share_type');
334
312
  return urlObj.origin + urlObj.pathname;
335
313
  }
336
314
  return url;
337
315
  }
338
316
  catch (e) {
339
- return url.replace(/&amp;/g, '&');
317
+ return url.replace(/&amp;/g, '&').replace(/\?.*/, '');
340
318
  }
341
319
  }
342
320
  async function resolveShortUrl(url) {
@@ -345,7 +323,9 @@ async function resolveShortUrl(url) {
345
323
  timeout: 10000,
346
324
  maxRedirects: 10,
347
325
  headers: {
348
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
326
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
327
+ 'Referer': 'https://www.baidu.com/',
328
+ 'Cookie': 'xhsTrackerId=xxx; xhs_sessionId=xxx'
349
329
  }
350
330
  });
351
331
  return cleanUrl(res.request.res?.responseUrl || url);
@@ -373,7 +353,7 @@ function formatDuration(input) {
373
353
  : `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
374
354
  }
375
355
  function getNestedValue(obj, path) {
376
- if (!obj || typeof obj !== 'object')
356
+ if (!obj || typeof obj !== 'object' || !path)
377
357
  return undefined;
378
358
  const keys = path.split('.');
379
359
  let value = obj;
@@ -385,142 +365,86 @@ function getNestedValue(obj, path) {
385
365
  return value;
386
366
  }
387
367
  function findValueInObject(obj, keys) {
388
- if (!obj || typeof obj !== 'object')
368
+ if (!obj || typeof obj !== 'object' || !keys || keys.length === 0)
389
369
  return undefined;
390
370
  for (const key of keys) {
391
371
  if (key.includes('.')) {
392
372
  const value = getNestedValue(obj, key);
393
- if (value !== undefined && value !== null && value !== '')
373
+ if (value !== undefined && value !== null && value !== '' && value !== 0)
394
374
  return value;
395
375
  }
396
376
  else {
397
- if (obj[key] !== undefined && obj[key] !== null && obj[key] !== '')
377
+ if (obj[key] !== undefined && obj[key] !== null && obj[key] !== '' && obj[key] !== 0)
398
378
  return obj[key];
399
379
  const lowerKey = key.toLowerCase();
400
380
  for (const objKey of Object.keys(obj)) {
401
381
  if (objKey.toLowerCase() === lowerKey) {
402
- return obj[objKey];
382
+ const val = obj[objKey];
383
+ if (val !== undefined && val !== null && val !== '' && val !== 0)
384
+ return val;
403
385
  }
404
386
  }
405
387
  }
406
388
  }
407
389
  return undefined;
408
390
  }
409
- function parseData(rawResponse, maxDescLength, platform) {
410
- let data = rawResponse;
411
- if (platform === 'bilibili' && rawResponse.data) {
412
- data = rawResponse.data;
413
- }
414
- else if (platform === 'douyin' && rawResponse.data) {
415
- data = rawResponse.data;
416
- }
417
- else if (data.data) {
418
- data = data.data;
419
- }
391
+ function parseData(rawResponse, maxDescLength) {
392
+ const rootData = rawResponse || {};
393
+ const data = rootData.data || rootData.result || rootData || {};
420
394
  const stat = {};
421
395
  Object.entries(VARIABLE_MAPPING).forEach(([varName, keys]) => {
422
- const value = findValueInObject(data, keys);
423
- if (value !== undefined) {
396
+ const value = findValueInObject(data, keys) || findValueInObject(rootData, keys);
397
+ if (value !== undefined)
424
398
  stat[varName] = value;
425
- }
426
399
  });
427
400
  let type = 'video';
428
- if (platform === 'douyin' && data.jx && data.jx.type) {
401
+ if (data.jx?.type)
429
402
  type = data.jx.type;
430
- }
431
- else if (data.type) {
403
+ else if (data.type)
432
404
  type = data.type;
433
- }
434
- let title = '无标题';
435
- if (platform === 'bilibili' && data.video && data.video.title) {
436
- title = data.video.title;
437
- }
438
- else if (platform === 'douyin' && data.item && data.item.title) {
439
- title = data.item.title;
440
- }
441
- else {
442
- title = findValueInObject(data, ['title']) || '无标题';
443
- }
444
- let author = '未知作者';
445
- if (platform === 'bilibili' && data.owner && data.owner.name) {
446
- author = data.owner.name;
447
- }
448
- else if (platform === 'douyin' && data.author && data.author.name) {
449
- author = data.author.name;
450
- }
451
- else {
452
- author = findValueInObject(data, ['author.name', 'author', 'name', 'auther']) || '未知作者';
453
- }
454
- let desc = title;
455
- if (platform === 'bilibili' && data.video && data.video.desc) {
456
- desc = data.video.desc;
457
- }
458
- else if (platform === 'douyin') {
459
- desc = title;
460
- }
461
- else {
462
- desc = findValueInObject(data, ['desc', 'description', 'content']) || title;
463
- }
405
+ else if (data.images && data.images.length > 0)
406
+ type = 'image';
407
+ else if (data.pics && data.pics.length > 0)
408
+ type = '图集';
409
+ const title = findValueInObject(data, VARIABLE_MAPPING['标题']) || findValueInObject(rootData, VARIABLE_MAPPING['标题']) || '无标题';
410
+ const author = findValueInObject(data, VARIABLE_MAPPING['作者']) || findValueInObject(rootData, VARIABLE_MAPPING['作者']) || '未知作者';
411
+ let desc = findValueInObject(data, VARIABLE_MAPPING['简介']) || findValueInObject(rootData, VARIABLE_MAPPING['简介']) || title;
464
412
  desc = desc.toString().slice(0, maxDescLength);
465
- let cover = '';
466
- if (platform === 'bilibili' && data.video && data.video.fm) {
467
- cover = data.video.fm;
468
- }
469
- else if (platform === 'douyin' && data.item && data.item.cover) {
470
- cover = data.item.cover;
471
- }
472
- else {
473
- cover = findValueInObject(data, ['cover', 'imgurl', 'pic', 'thumbnail']) || '';
474
- }
413
+ const cover = findValueInObject(data, ['cover', 'imgurl', 'pic', 'thumbnail', 'cover_url']) || findValueInObject(rootData, ['cover', 'imgurl', 'pic', 'thumbnail', 'cover_url']) || '';
475
414
  let images = [];
476
- if (platform === 'douyin' && data.item && data.item.images) {
477
- images = data.item.images;
478
- }
479
- else {
480
- images = findValueInObject(data, ['imgurl', 'images', 'pics']) || [];
481
- }
482
- if (!Array.isArray(images))
483
- images = [images];
415
+ const imgList = findValueInObject(data, ['images', 'pics', 'pic_urls', 'image_list']) || findValueInObject(rootData, ['images', 'pics', 'pic_urls', 'image_list']) || [];
416
+ if (Array.isArray(imgList))
417
+ images = imgList.filter(img => img && typeof img === 'string');
418
+ else if (imgList && typeof imgList === 'string')
419
+ images = [imgList];
484
420
  let video = '';
485
- if (platform === 'bilibili' && data.video && data.video.url) {
486
- video = data.video.url;
487
- }
488
- else if (platform === 'douyin' && data.item && data.item.url) {
489
- video = data.item.url;
490
- }
491
- else {
492
- const videoUrls = [
493
- findValueInObject(data, ['url']),
494
- findValueInObject(data, ['download_url']),
495
- findValueInObject(data, ['video_backup']),
496
- findValueInObject(data, ['playUrl']),
497
- findValueInObject(data, ['video_url'])
498
- ];
499
- if (Array.isArray(videoUrls[2])) {
500
- video = videoUrls[2][0]?.url || '';
501
- }
502
- else {
503
- for (const url of videoUrls) {
504
- if (url && typeof url === 'string' && url.trim() !== '') {
505
- video = url;
506
- break;
507
- }
508
- }
509
- }
510
- }
511
- const durationValue = findValueInObject(data, ['duration']);
421
+ const videoUrls = [
422
+ findValueInObject(data, ['url', 'video_url', 'download_url', 'playUrl', 'mp4_url']),
423
+ findValueInObject(rootData, ['url', 'video_url', 'download_url', 'playUrl', 'mp4_url']),
424
+ data.video?.url,
425
+ data.item?.url,
426
+ rootData.video?.url,
427
+ rootData.item?.url
428
+ ];
429
+ for (const url of videoUrls) {
430
+ if (url && typeof url === 'string' && url.startsWith('http')) {
431
+ video = url;
432
+ break;
433
+ }
434
+ }
435
+ const durationValue = findValueInObject(data, VARIABLE_MAPPING['视频时长']) || findValueInObject(rootData, VARIABLE_MAPPING['视频时长']);
512
436
  const duration = typeof durationValue === 'number' ? durationValue : parseInt(durationValue) || 0;
513
437
  const durationFormatted = formatDuration(durationValue || 0);
514
- const live_photo = data.live_photo || [];
515
- const music = findValueInObject(data, ['music', 'muisic']) || '';
516
- const h_w = platform === 'douyin' && data.item && data.item.h_w ? data.item.h_w : [];
517
- const quality_urls = data.quality_urls || {};
518
- const default_quality = data.default_quality || '';
519
- const download_url = data.download_url || '';
520
- const play_count = data.play_count || '';
521
- const reposts_count = data.reposts_count || 0;
522
- const attitudes_count = data.attitudes_count || 0;
523
- const comments_count = data.comments_count || 0;
438
+ const live_photo = data.live_photo || rootData.live_photo || [];
439
+ const music = findValueInObject(data, VARIABLE_MAPPING['音乐名']) || findValueInObject(rootData, VARIABLE_MAPPING['音乐名']) || '';
440
+ const h_w = data.item?.h_w || rootData.item?.h_w || [];
441
+ const quality_urls = data.quality_urls || rootData.quality_urls || {};
442
+ const default_quality = data.default_quality || rootData.default_quality || '';
443
+ const download_url = data.download_url || rootData.download_url || video;
444
+ const play_count = stat['播放数'] || '';
445
+ const reposts_count = stat['转发数'] || 0;
446
+ const attitudes_count = stat['点赞数'] || 0;
447
+ const comments_count = stat['评论数'] || 0;
524
448
  return {
525
449
  type: type,
526
450
  rawData: rawResponse,
@@ -536,7 +460,7 @@ function parseData(rawResponse, maxDescLength, platform) {
536
460
  live_photo,
537
461
  music,
538
462
  h_w,
539
- jx: data.jx || null,
463
+ jx: data.jx || rootData.jx || null,
540
464
  quality_urls,
541
465
  default_quality,
542
466
  download_url,
@@ -546,18 +470,22 @@ function parseData(rawResponse, maxDescLength, platform) {
546
470
  comments_count
547
471
  };
548
472
  }
549
- function generateFormattedText(platform, parseData, config) {
473
+ function generateFormattedText(parseData, config) {
550
474
  let format = config.unifiedMessageFormat;
551
- if (platform !== 'bilibili') {
552
- format = format.replace(/投币:\$\{投币数\}\n?/g, '');
553
- }
554
- let result = format;
555
- const formatLines = result.split('\n');
475
+ if (!format)
476
+ format = '标题:${标题}\n作者:${作者}\n简介:${简介}';
477
+ const formatLines = format.split('\n');
556
478
  const validLines = [];
557
479
  formatLines.forEach((line) => {
480
+ if (!line.trim())
481
+ return;
558
482
  let isValid = true;
559
483
  let processedLine = line;
560
484
  const varMatches = line.match(/\$\{([^}]+)\}/g) || [];
485
+ if (varMatches.length === 0) {
486
+ validLines.push(line);
487
+ return;
488
+ }
561
489
  varMatches.forEach((varMatch) => {
562
490
  const varName = varMatch.replace(/\$\{|\}/g, '');
563
491
  const value = parseData.stat[varName];
@@ -572,7 +500,7 @@ function generateFormattedText(platform, parseData, config) {
572
500
  validLines.push(processedLine);
573
501
  }
574
502
  });
575
- result = validLines.join('\n').trim();
503
+ let result = validLines.join('\n').trim();
576
504
  if (!result) {
577
505
  result = `标题:${parseData.title}\n作者:${parseData.author}\n简介:${parseData.desc}`;
578
506
  }
@@ -616,23 +544,31 @@ function apply(ctx, config) {
616
544
  clearAllCache();
617
545
  const http = axios_1.default.create({
618
546
  timeout: config.timeout,
619
- headers: { 'User-Agent': config.userAgent || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' }
547
+ headers: {
548
+ 'User-Agent': config.userAgent || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
549
+ 'Referer': 'https://www.baidu.com/',
550
+ 'Content-Type': 'application/x-www-form-urlencoded'
551
+ }
620
552
  });
621
553
  async function parseWithRetry(url, platform, retryTimes) {
622
554
  let lastError = null;
623
555
  for (let i = 0; i <= retryTimes; i++) {
624
556
  try {
625
- const params = { url };
557
+ const params = { url, proxyurl: '' };
626
558
  const res = await http.get(API_CONFIG[platform], {
627
559
  params,
628
- timeout: config.timeout
560
+ timeout: config.timeout,
561
+ headers: {
562
+ 'X-Requested-With': 'XMLHttpRequest',
563
+ 'Origin': platform === 'xiaohongshu' ? 'https://api.bugpk.com' : 'https://www.baidu.com'
564
+ }
629
565
  });
630
566
  return res.data;
631
567
  }
632
568
  catch (error) {
633
569
  lastError = error;
634
570
  if (i < retryTimes) {
635
- await delay(config.retryInterval);
571
+ await delay(config.retryInterval * (i + 1));
636
572
  }
637
573
  }
638
574
  }
@@ -657,28 +593,24 @@ function apply(ctx, config) {
657
593
  }
658
594
  try {
659
595
  const resData = await parseWithRetry(realUrl, platform, config.retryTimes);
660
- let isSuccess = false;
661
- if (platform === 'bilibili' || platform === 'douyin') {
662
- isSuccess = resData.code === 0 || (resData.msg && (resData.msg.includes('解析成功') || resData.msg === 'video'));
663
- }
664
- else {
665
- isSuccess = resData.code === 200 || resData.code === 0 ||
666
- (resData.msg && resData.msg.includes('解析成功'));
596
+ if (!resData || Object.keys(resData).length === 0) {
597
+ const code = ErrorCode.API_EMPTY_RESPONSE;
598
+ const msg = getErrorInfo(code, 'API返回空数据');
599
+ logger.error(`[${code}] ${url}`);
600
+ return { data: null, code, msg };
667
601
  }
602
+ const isSuccess = resData.code === 0 || resData.code === 200 || resData.code === 1 ||
603
+ (resData.msg && (resData.msg.includes('解析成功') || resData.msg.includes('success'))) ||
604
+ !!resData.data || !!resData.result || !!resData.video || !!resData.images;
668
605
  if (!isSuccess) {
669
- const apiErrorMsg = resData.msg || '解析失败';
670
- const platformCode = PLATFORM_ERROR_CODE_MAP[platform] || ErrorCode.API_RETURN_ERROR;
671
- let detailedMsg = apiErrorMsg;
672
- if (apiErrorMsg.includes('无法识别解析类型') || apiErrorMsg.includes('未找到有效内容')) {
673
- detailedMsg = `链接格式不支持或内容已失效:${apiErrorMsg}`;
674
- }
675
- const code = platformCode;
676
- const msg = getErrorInfo(code, detailedMsg);
677
- logger.error(`[${code}] API返回错误: ${platform}, URL: ${url}, 错误: ${apiErrorMsg}`);
606
+ const apiErrorMsg = resData.msg || resData.error || '解析失败';
607
+ const code = ErrorCode.API_RETURN_ERROR;
608
+ const msg = getErrorInfo(code, apiErrorMsg);
609
+ logger.error(`[${code}] API返回错误: ${url}, 错误: ${apiErrorMsg}`);
678
610
  return { data: null, code, msg };
679
611
  }
680
612
  try {
681
- const parseResult = parseData(resData, config.maxDescLength, platform);
613
+ const parseResult = parseData(resData, config.maxDescLength);
682
614
  const hasValidContent = parseResult.video ||
683
615
  (parseResult.images && parseResult.images.length > 0) ||
684
616
  (parseResult.live_photo && parseResult.live_photo.length > 0) ||
@@ -686,11 +618,11 @@ function apply(ctx, config) {
686
618
  parseResult.type === '图集';
687
619
  if (!hasValidContent) {
688
620
  const code = ErrorCode.NO_VIDEO_FOUND;
689
- const msg = getErrorInfo(code, '链接有效但未找到视频/图片内容(可能是直播、私密内容或已删除)');
690
- logger.warn(`[${code}] 解析成功但无有效内容: ${platform}, URL: ${url}`);
621
+ const msg = getErrorInfo(code, '链接有效但未获取到有效视频/图片内容,可能是私密/需要登录/已删除内容');
622
+ logger.warn(`[${code}] 解析成功但无有效内容: ${url}`);
691
623
  return { data: null, code, msg };
692
624
  }
693
- logger.info(`[${ErrorCode.SUCCESS}] ${platform}解析成功: ${url}`);
625
+ logger.info(`[${ErrorCode.SUCCESS}] 解析成功: ${url}`);
694
626
  return {
695
627
  data: parseResult,
696
628
  code: ErrorCode.SUCCESS,
@@ -701,7 +633,7 @@ function apply(ctx, config) {
701
633
  const errorMsg = getErrorMessage(parseError);
702
634
  const code = ErrorCode.API_DATA_PARSE_FAILED;
703
635
  const msg = getErrorInfo(code, errorMsg);
704
- logger.error(`[${code}] 解析数据失败: ${platform}, URL: ${url}, 错误: ${errorMsg}`);
636
+ logger.error(`[${code}] 解析数据失败: ${url}, 错误: ${errorMsg}`);
705
637
  return { data: null, code, msg };
706
638
  }
707
639
  }
@@ -711,14 +643,14 @@ function apply(ctx, config) {
711
643
  if (errorMsg.includes('timeout')) {
712
644
  code = ErrorCode.REQUEST_TIMEOUT;
713
645
  }
714
- else if (errorMsg.includes('Network') || errorMsg.includes('network')) {
646
+ else if (errorMsg.includes('Network') || errorMsg.includes('network') || errorMsg.includes('404') || errorMsg.includes('500')) {
715
647
  code = ErrorCode.NETWORK_ERROR;
716
648
  }
717
649
  else {
718
650
  code = ErrorCode.NETWORK_ERROR;
719
651
  }
720
652
  const msg = getErrorInfo(code, errorMsg);
721
- logger.error(`[${code}] 解析请求失败: ${platform}, URL: ${url}, 错误: ${errorMsg}`);
653
+ logger.error(`[${code}] 解析请求失败: ${url}, 错误: ${errorMsg}`);
722
654
  return { data: null, code, msg };
723
655
  }
724
656
  }
@@ -735,8 +667,7 @@ function apply(ctx, config) {
735
667
  if (!result.data)
736
668
  return { data: null, code: result.code, msg: result.msg };
737
669
  const parseData = result.data;
738
- const platform = getPlatformType(url);
739
- const text = generateFormattedText(platform, parseData, config);
670
+ const text = generateFormattedText(parseData, config);
740
671
  return {
741
672
  data: {
742
673
  text,
@@ -798,14 +729,14 @@ function apply(ctx, config) {
798
729
  }
799
730
  }
800
731
  if (errors.length > 0) {
801
- const errorLines = errors.map(err => `【${err.url}】: ${err.msg}`);
732
+ const errorLines = errors.map(err => `【${err.url.slice(0, 50)}${err.url.length > 50 ? '...' : ''}】: ${err.msg}`);
802
733
  const errorMsg = `❌ 解析失败列表(共${errors.length}个链接):\n${errorLines.join('\n')}`;
803
734
  logger.error(`解析失败数量: ${errors.length}, 错误码列表: ${errors.map(e => e.code).join(', ')}`);
804
735
  await sendTimeout(session, errorMsg);
805
736
  await delay(500);
806
737
  }
807
738
  if (items.length === 0) {
808
- const failMsg = getErrorInfo(ErrorCode.UNKNOWN_ERROR, '所有链接均解析失败,请检查链接是否有效或稍后重试');
739
+ const failMsg = getErrorInfo(ErrorCode.UNKNOWN_ERROR, '所有链接均解析失败,请检查链接是否有效/是否需要登录,或稍后重试');
809
740
  await sendTimeout(session, `⚠ ${failMsg}`);
810
741
  return;
811
742
  }
@@ -932,8 +863,7 @@ function apply(ctx, config) {
932
863
  const filename = crypto_1.default.createHash('md5').update(item.video).digest('hex');
933
864
  const downloadResult = await downloadVideo(item.video, filename, config.userAgent, config.maxVideoSize, config.downloadThreads);
934
865
  if (downloadResult.code !== ErrorCode.SUCCESS) {
935
- const errorMsg = getErrorInfo(downloadResult.code);
936
- await sendTimeout(session, koishi_1.h.text(`${errorMsg}\n链接:${item.video}`));
866
+ await sendTimeout(session, koishi_1.h.text(`${getErrorInfo(downloadResult.code)}\n链接:${item.video}`));
937
867
  continue;
938
868
  }
939
869
  else {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-video-parser-all",
3
3
  "description": "Koishi 全平台视频解析插件,支持抖音/快手/B站/小红书/微博/今日头条/皮皮搞笑/皮皮虾/最右视频链接解析",
4
- "version": "0.5.7",
4
+ "version": "0.5.9",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [