koishi-plugin-video-parser-all 0.5.5 → 0.5.7
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 +35 -38
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -123,7 +123,6 @@ const PLATFORM_KEYWORDS = {
|
|
|
123
123
|
douyin: ['douyin', '抖音', 'v.douyin.com', 'douyinpic.com', 'douyinvod.com', 'douyin.com/video', 'douyin.com/note', 'www.douyin.com', 'tiktok.com'],
|
|
124
124
|
zuiyou: ['zuiyou', '最右', 'xiaochuankeji.cn', 'izuiyou.com', 'izuiyou.com/topic']
|
|
125
125
|
};
|
|
126
|
-
// 更新API配置:B站和抖音使用新的api.xingzhige.com,其他平台保持不变
|
|
127
126
|
const API_CONFIG = {
|
|
128
127
|
bilibili: 'https://api.xingzhige.com/API/b_parse',
|
|
129
128
|
douyin: 'https://api.xingzhige.com/API/douyin/',
|
|
@@ -154,10 +153,10 @@ const VARIABLE_MAPPING = {
|
|
|
154
153
|
'点赞数': ['like', 'Like', 'attitudes_count', 'digg_count', 'praise', 'stat.like'],
|
|
155
154
|
'投币数': ['coin', 'Coin', 'bi', 'Bi'],
|
|
156
155
|
'收藏数': ['collect', 'Collect', 'favorite', 'Favorite', 'star', 'Star', 'stat.collect'],
|
|
157
|
-
'转发数': ['share', 'Share', 'forward', 'Forward', 'repost', 'stat.share'],
|
|
156
|
+
'转发数': ['share', 'Share', 'forward', 'Forward', 'repost', 'stat.share', 'reposts_count'],
|
|
158
157
|
'播放数': ['view', 'View', 'play_count', 'PlayCount', 'play'],
|
|
159
158
|
'评论数': ['comment', 'Comment', 'comments_count', 'comment_count', 'discuss', 'stat.comment'],
|
|
160
|
-
'音乐名': ['music.title', 'music_name', 'audio_name', 'sound_name', 'muisic']
|
|
159
|
+
'音乐名': ['music.title', 'music_name', 'audio_name', 'sound_name', 'muisic', 'music']
|
|
161
160
|
};
|
|
162
161
|
function getErrorInfo(code, detail) {
|
|
163
162
|
const baseMsg = exports.ErrorMessageMap[code] || exports.ErrorMessageMap[ErrorCode.UNKNOWN_ERROR];
|
|
@@ -322,7 +321,6 @@ function getPlatformType(url) {
|
|
|
322
321
|
}
|
|
323
322
|
function cleanUrl(url) {
|
|
324
323
|
try {
|
|
325
|
-
// 处理HTML实体编码
|
|
326
324
|
url = url.replace(/&/g, '&');
|
|
327
325
|
const urlObj = new URL(url);
|
|
328
326
|
if (urlObj.hostname.includes('xiaohongshu.com')) {
|
|
@@ -330,7 +328,7 @@ function cleanUrl(url) {
|
|
|
330
328
|
urlObj.searchParams.delete('xhsshare');
|
|
331
329
|
urlObj.searchParams.delete('xsec_token');
|
|
332
330
|
urlObj.searchParams.delete('xsec_source');
|
|
333
|
-
return urlObj.origin + urlObj.pathname
|
|
331
|
+
return urlObj.origin + urlObj.pathname;
|
|
334
332
|
}
|
|
335
333
|
if (urlObj.hostname.includes('douyin.com') || urlObj.hostname.includes('v.douyin.com')) {
|
|
336
334
|
return urlObj.origin + urlObj.pathname;
|
|
@@ -338,7 +336,6 @@ function cleanUrl(url) {
|
|
|
338
336
|
return url;
|
|
339
337
|
}
|
|
340
338
|
catch (e) {
|
|
341
|
-
// 处理HTML实体编码
|
|
342
339
|
return url.replace(/&/g, '&');
|
|
343
340
|
}
|
|
344
341
|
}
|
|
@@ -409,39 +406,31 @@ function findValueInObject(obj, keys) {
|
|
|
409
406
|
}
|
|
410
407
|
return undefined;
|
|
411
408
|
}
|
|
412
|
-
// 适配新的API返回格式
|
|
413
409
|
function parseData(rawResponse, maxDescLength, platform) {
|
|
414
410
|
let data = rawResponse;
|
|
415
|
-
// 处理不同平台的返回结构差异
|
|
416
411
|
if (platform === 'bilibili' && rawResponse.data) {
|
|
417
|
-
// 适配api.xingzhige.com的B站返回格式
|
|
418
412
|
data = rawResponse.data;
|
|
419
413
|
}
|
|
420
414
|
else if (platform === 'douyin' && rawResponse.data) {
|
|
421
|
-
// 适配api.xingzhige.com的抖音返回格式
|
|
422
415
|
data = rawResponse.data;
|
|
423
416
|
}
|
|
424
417
|
else if (data.data) {
|
|
425
|
-
// 其他平台保持原有逻辑
|
|
426
418
|
data = data.data;
|
|
427
419
|
}
|
|
428
420
|
const stat = {};
|
|
429
|
-
// 适配新的字段映射
|
|
430
421
|
Object.entries(VARIABLE_MAPPING).forEach(([varName, keys]) => {
|
|
431
422
|
const value = findValueInObject(data, keys);
|
|
432
423
|
if (value !== undefined) {
|
|
433
424
|
stat[varName] = value;
|
|
434
425
|
}
|
|
435
426
|
});
|
|
436
|
-
// 处理不同平台的类型字段
|
|
437
427
|
let type = 'video';
|
|
438
428
|
if (platform === 'douyin' && data.jx && data.jx.type) {
|
|
439
|
-
type = data.jx.type;
|
|
429
|
+
type = data.jx.type;
|
|
440
430
|
}
|
|
441
431
|
else if (data.type) {
|
|
442
432
|
type = data.type;
|
|
443
433
|
}
|
|
444
|
-
// 适配不同平台的标题字段
|
|
445
434
|
let title = '无标题';
|
|
446
435
|
if (platform === 'bilibili' && data.video && data.video.title) {
|
|
447
436
|
title = data.video.title;
|
|
@@ -452,7 +441,6 @@ function parseData(rawResponse, maxDescLength, platform) {
|
|
|
452
441
|
else {
|
|
453
442
|
title = findValueInObject(data, ['title']) || '无标题';
|
|
454
443
|
}
|
|
455
|
-
// 适配不同平台的作者字段
|
|
456
444
|
let author = '未知作者';
|
|
457
445
|
if (platform === 'bilibili' && data.owner && data.owner.name) {
|
|
458
446
|
author = data.owner.name;
|
|
@@ -463,19 +451,17 @@ function parseData(rawResponse, maxDescLength, platform) {
|
|
|
463
451
|
else {
|
|
464
452
|
author = findValueInObject(data, ['author.name', 'author', 'name', 'auther']) || '未知作者';
|
|
465
453
|
}
|
|
466
|
-
// 适配不同平台的描述字段
|
|
467
454
|
let desc = title;
|
|
468
455
|
if (platform === 'bilibili' && data.video && data.video.desc) {
|
|
469
456
|
desc = data.video.desc;
|
|
470
457
|
}
|
|
471
458
|
else if (platform === 'douyin') {
|
|
472
|
-
desc = title;
|
|
459
|
+
desc = title;
|
|
473
460
|
}
|
|
474
461
|
else {
|
|
475
462
|
desc = findValueInObject(data, ['desc', 'description', 'content']) || title;
|
|
476
463
|
}
|
|
477
464
|
desc = desc.toString().slice(0, maxDescLength);
|
|
478
|
-
// 适配不同平台的封面字段
|
|
479
465
|
let cover = '';
|
|
480
466
|
if (platform === 'bilibili' && data.video && data.video.fm) {
|
|
481
467
|
cover = data.video.fm;
|
|
@@ -486,7 +472,6 @@ function parseData(rawResponse, maxDescLength, platform) {
|
|
|
486
472
|
else {
|
|
487
473
|
cover = findValueInObject(data, ['cover', 'imgurl', 'pic', 'thumbnail']) || '';
|
|
488
474
|
}
|
|
489
|
-
// 适配不同平台的图片字段
|
|
490
475
|
let images = [];
|
|
491
476
|
if (platform === 'douyin' && data.item && data.item.images) {
|
|
492
477
|
images = data.item.images;
|
|
@@ -496,13 +481,12 @@ function parseData(rawResponse, maxDescLength, platform) {
|
|
|
496
481
|
}
|
|
497
482
|
if (!Array.isArray(images))
|
|
498
483
|
images = [images];
|
|
499
|
-
// 适配不同平台的视频链接字段
|
|
500
484
|
let video = '';
|
|
501
485
|
if (platform === 'bilibili' && data.video && data.video.url) {
|
|
502
486
|
video = data.video.url;
|
|
503
487
|
}
|
|
504
|
-
else if (platform === 'douyin') {
|
|
505
|
-
video =
|
|
488
|
+
else if (platform === 'douyin' && data.item && data.item.url) {
|
|
489
|
+
video = data.item.url;
|
|
506
490
|
}
|
|
507
491
|
else {
|
|
508
492
|
const videoUrls = [
|
|
@@ -524,12 +508,19 @@ function parseData(rawResponse, maxDescLength, platform) {
|
|
|
524
508
|
}
|
|
525
509
|
}
|
|
526
510
|
}
|
|
527
|
-
// 适配不同平台的时长字段
|
|
528
511
|
const durationValue = findValueInObject(data, ['duration']);
|
|
529
512
|
const duration = typeof durationValue === 'number' ? durationValue : parseInt(durationValue) || 0;
|
|
530
513
|
const durationFormatted = formatDuration(durationValue || 0);
|
|
531
|
-
// 处理live_photo字段
|
|
532
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;
|
|
533
524
|
return {
|
|
534
525
|
type: type,
|
|
535
526
|
rawData: rawResponse,
|
|
@@ -542,7 +533,17 @@ function parseData(rawResponse, maxDescLength, platform) {
|
|
|
542
533
|
duration,
|
|
543
534
|
durationFormatted,
|
|
544
535
|
stat,
|
|
545
|
-
live_photo
|
|
536
|
+
live_photo,
|
|
537
|
+
music,
|
|
538
|
+
h_w,
|
|
539
|
+
jx: data.jx || null,
|
|
540
|
+
quality_urls,
|
|
541
|
+
default_quality,
|
|
542
|
+
download_url,
|
|
543
|
+
play_count,
|
|
544
|
+
reposts_count,
|
|
545
|
+
attitudes_count,
|
|
546
|
+
comments_count
|
|
546
547
|
};
|
|
547
548
|
}
|
|
548
549
|
function generateFormattedText(platform, parseData, config) {
|
|
@@ -621,8 +622,9 @@ function apply(ctx, config) {
|
|
|
621
622
|
let lastError = null;
|
|
622
623
|
for (let i = 0; i <= retryTimes; i++) {
|
|
623
624
|
try {
|
|
625
|
+
const params = { url };
|
|
624
626
|
const res = await http.get(API_CONFIG[platform], {
|
|
625
|
-
params
|
|
627
|
+
params,
|
|
626
628
|
timeout: config.timeout
|
|
627
629
|
});
|
|
628
630
|
return res.data;
|
|
@@ -655,14 +657,11 @@ function apply(ctx, config) {
|
|
|
655
657
|
}
|
|
656
658
|
try {
|
|
657
659
|
const resData = await parseWithRetry(realUrl, platform, config.retryTimes);
|
|
658
|
-
// 适配不同平台的成功判断逻辑
|
|
659
660
|
let isSuccess = false;
|
|
660
|
-
// B站和抖音使用新的判断逻辑(code=0表示成功)
|
|
661
661
|
if (platform === 'bilibili' || platform === 'douyin') {
|
|
662
662
|
isSuccess = resData.code === 0 || (resData.msg && (resData.msg.includes('解析成功') || resData.msg === 'video'));
|
|
663
663
|
}
|
|
664
664
|
else {
|
|
665
|
-
// 其他平台保持原有逻辑
|
|
666
665
|
isSuccess = resData.code === 200 || resData.code === 0 ||
|
|
667
666
|
(resData.msg && resData.msg.includes('解析成功'));
|
|
668
667
|
}
|
|
@@ -680,7 +679,6 @@ function apply(ctx, config) {
|
|
|
680
679
|
}
|
|
681
680
|
try {
|
|
682
681
|
const parseResult = parseData(resData, config.maxDescLength, platform);
|
|
683
|
-
// 修正内容判断逻辑:支持抖音图集、live类型和live_photo
|
|
684
682
|
const hasValidContent = parseResult.video ||
|
|
685
683
|
(parseResult.images && parseResult.images.length > 0) ||
|
|
686
684
|
(parseResult.live_photo && parseResult.live_photo.length > 0) ||
|
|
@@ -746,7 +744,12 @@ function apply(ctx, config) {
|
|
|
746
744
|
images: parseData.images,
|
|
747
745
|
video: parseData.video,
|
|
748
746
|
type: parseData.type,
|
|
749
|
-
live_photo: parseData.live_photo
|
|
747
|
+
live_photo: parseData.live_photo,
|
|
748
|
+
music: parseData.music,
|
|
749
|
+
h_w: parseData.h_w,
|
|
750
|
+
quality_urls: parseData.quality_urls,
|
|
751
|
+
default_quality: parseData.default_quality,
|
|
752
|
+
download_url: parseData.download_url
|
|
750
753
|
},
|
|
751
754
|
code: ErrorCode.SUCCESS,
|
|
752
755
|
msg: getErrorInfo(ErrorCode.SUCCESS)
|
|
@@ -816,7 +819,6 @@ function apply(ctx, config) {
|
|
|
816
819
|
forwardMessages.push(buildForwardNode(session, item.text, botName));
|
|
817
820
|
if (item.cover && forwardMessages.length < 100)
|
|
818
821
|
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(item.cover), botName));
|
|
819
|
-
// 处理抖音图集
|
|
820
822
|
if (item.type === '图集' && item.images?.length) {
|
|
821
823
|
for (let i = 0; i < item.images.length && forwardMessages.length < 100; i++) {
|
|
822
824
|
forwardMessages.push(buildForwardNode(session, koishi_1.h.image(item.images[i]), botName));
|
|
@@ -889,7 +891,6 @@ function apply(ctx, config) {
|
|
|
889
891
|
await sendTimeout(session, item.text);
|
|
890
892
|
await delay(300);
|
|
891
893
|
}
|
|
892
|
-
// 处理抖音图集
|
|
893
894
|
if (item.type === '图集' && item.images?.length) {
|
|
894
895
|
const imgMsg = (0, koishi_1.h)('message', ...item.images.map((url) => koishi_1.h.image(url)));
|
|
895
896
|
await sendTimeout(session, imgMsg);
|
|
@@ -1074,9 +1075,5 @@ function apply(ctx, config) {
|
|
|
1074
1075
|
logger.info(getErrorInfo(ErrorCode.SUCCESS, '自动清理缓存完成'));
|
|
1075
1076
|
}, config.autoClearCacheInterval * 60000);
|
|
1076
1077
|
}
|
|
1077
|
-
process.on('exit', () => {
|
|
1078
|
-
clearAllCache();
|
|
1079
|
-
logger.info(getErrorInfo(ErrorCode.SUCCESS, '进程退出,已清理缓存'));
|
|
1080
|
-
});
|
|
1081
1078
|
logger.info(getErrorInfo(ErrorCode.SUCCESS, '视频解析插件已加载'));
|
|
1082
1079
|
}
|
package/package.json
CHANGED