koishi-plugin-video-parser-all 0.6.4 → 0.6.6
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 +114 -67
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -38,13 +38,9 @@ IP属地:${'${IP属地}'}
|
|
|
38
38
|
在线人数:${'${在线人数}'}
|
|
39
39
|
关注数:${'${关注数}'}
|
|
40
40
|
文件大小:${'${文件大小}'}
|
|
41
|
-
分辨率:${'${分辨率}'}
|
|
42
|
-
音乐作者:${'${音乐作者}'}
|
|
43
|
-
音乐标题:${'${音乐标题}'}
|
|
44
41
|
直播间地址:${'${直播间地址}'}
|
|
45
42
|
直播间ID:${'${直播间ID}'}
|
|
46
43
|
直播间状态:${'${直播间状态}'}
|
|
47
|
-
默认画质:${'${默认画质}'}
|
|
48
44
|
图片数量:${'${图片数量}'}
|
|
49
45
|
作者ID:${'${作者ID}'}`).description('统一消息格式'),
|
|
50
46
|
}).description('统一消息格式'),
|
|
@@ -145,35 +141,31 @@ const API_CONFIG = {
|
|
|
145
141
|
weibo: 'https://api.bugpk.com/api/weibo',
|
|
146
142
|
toutiao: 'https://api.bugpk.com/api/toutiao',
|
|
147
143
|
pipigx: 'https://api.bugpk.com/api/pipigx',
|
|
148
|
-
pipixia: 'https://api.bugpk.com/api/
|
|
144
|
+
pipixia: 'https://api.bugpk.com/api/pipixia',
|
|
149
145
|
zuiyou: 'https://api.bugpk.com/api/zuiyou'
|
|
150
146
|
};
|
|
151
147
|
const VARIABLE_MAPPING = {
|
|
152
|
-
'标题': ['title', 'Title', 'TITLE', 'note_title', 'content_title', 'item.title', 'data.title', 'video.title', 'live.title'],
|
|
153
|
-
'作者': ['author.name', 'author', 'name', 'Author', 'Name', 'owner.name', 'nickname', 'user_name', 'data.author', 'item.author', 'user.name', 'live.author'],
|
|
154
|
-
'简介': ['desc', 'description', 'Desc', 'Description', 'content', 'Content', 'note_desc', 'text', 'data.desc', 'item.description', 'live.desc'],
|
|
155
|
-
'视频时长': ['duration', 'Duration', 'time', 'Time', 'video_duration', 'item.duration', 'stat.duration'],
|
|
156
|
-
'点赞数': ['like', 'Like', 'attitudes_count', 'digg_count', 'praise', 'stat.like', 'liked_count', 'data.like', 'data.attitudes_count', 'item.attitudes_count'],
|
|
148
|
+
'标题': ['title', 'Title', 'TITLE', 'note_title', 'content_title', 'item.title', 'data.title', 'video.title', 'live.title', 'data.item.title'],
|
|
149
|
+
'作者': ['author.name', 'author', 'name', 'Author', 'Name', 'owner.name', 'nickname', 'user_name', 'data.author', 'item.author', 'user.name', 'live.author', 'data.user.name', 'data.author.name'],
|
|
150
|
+
'简介': ['desc', 'description', 'Desc', 'Description', 'content', 'Content', 'note_desc', 'text', 'data.desc', 'item.description', 'live.desc', 'data.item.description'],
|
|
151
|
+
'视频时长': ['duration', 'Duration', 'time', 'Time', 'video_duration', 'item.duration', 'stat.duration', 'data.item.duration'],
|
|
152
|
+
'点赞数': ['like', 'Like', 'attitudes_count', 'digg_count', 'praise', 'stat.like', 'liked_count', 'data.like', 'data.attitudes_count', 'item.attitudes_count', 'data.item.attitudes_count'],
|
|
157
153
|
'投币数': ['coin', 'Coin', 'bi', 'Bi', 'stat.coin', 'stast.coin'],
|
|
158
|
-
'收藏数': ['collect', 'Collect', 'favorite', 'Favorite', 'star', 'Star', 'stat.collect', 'collected_count', 'stast.favorite', 'data.favorite'],
|
|
159
|
-
'转发数': ['share', 'Share', 'forward', 'Forward', 'repost', 'stat.share', 'reposts_count', 'shared_count', 'stast.share', 'data.reposts_count'],
|
|
160
|
-
'播放数': ['view', 'View', 'play_count', 'PlayCount', 'play', 'stat.view', 'play_times', 'stast.view', 'data.play_count', 'item.play_count'],
|
|
161
|
-
'评论数': ['comment', 'Comment', 'comments_count', 'comment_count', 'discuss', 'stat.comment', 'stast.reply', 'data.comments_count', 'item.comments_count'],
|
|
162
|
-
'IP属地': ['ip_info_str', 'data.ip_info_str', 'item.ip_info'],
|
|
163
|
-
'发布时间': ['date', 'time', 'publish_time', 'data.date', 'item.publish_time', 'live.time', 'stast.publish_time'],
|
|
164
|
-
'粉丝数': ['followers_count', 'data.followers_count', 'item.followers', 'author.fans'],
|
|
165
|
-
'在线人数': ['online', 'data.online', 'live.online', 'room.online'],
|
|
166
|
-
'关注数': ['attention', 'data.attention', 'live.attention', 'stast.attention'],
|
|
167
|
-
'文件大小': ['size', 'size_str', 'item.size', 'item.size_str', 'data.size'],
|
|
168
|
-
'
|
|
169
|
-
'
|
|
170
|
-
'
|
|
171
|
-
'
|
|
172
|
-
'
|
|
173
|
-
'直播间状态': ['status', 'live.status', 'data.status', 'room.status'],
|
|
174
|
-
'默认画质': ['default_quality', 'data.default_quality', 'item.default_quality'],
|
|
175
|
-
'图片数量': ['count', 'data.count', 'item.count', 'images.length', 'data.images.length'],
|
|
176
|
-
'作者ID': ['userId', 'userID', 'author_id', 'data.userId', 'item.userID', 'author.mid', 'user.mid'],
|
|
154
|
+
'收藏数': ['collect', 'Collect', 'favorite', 'Favorite', 'star', 'Star', 'stat.collect', 'collected_count', 'stast.favorite', 'data.favorite', 'stast.favorite'],
|
|
155
|
+
'转发数': ['share', 'Share', 'forward', 'Forward', 'repost', 'stat.share', 'reposts_count', 'shared_count', 'stast.share', 'data.reposts_count', 'data.item.reposts_count'],
|
|
156
|
+
'播放数': ['view', 'View', 'play_count', 'PlayCount', 'play', 'stat.view', 'play_times', 'stast.view', 'data.play_count', 'item.play_count', 'data.item.play_count'],
|
|
157
|
+
'评论数': ['comment', 'Comment', 'comments_count', 'comment_count', 'discuss', 'stat.comment', 'stast.reply', 'data.comments_count', 'item.comments_count', 'data.item.comments_count'],
|
|
158
|
+
'IP属地': ['ip_info_str', 'data.ip_info_str', 'item.ip_info', 'data.item.ip_info_str'],
|
|
159
|
+
'发布时间': ['date', 'time', 'publish_time', 'data.date', 'item.publish_time', 'live.time', 'stast.publish_time', 'stat.time', 'data.time.publish_time', 'data.live.time'],
|
|
160
|
+
'粉丝数': ['followers_count', 'data.followers_count', 'item.followers', 'author.fans', 'data.item.followers_count'],
|
|
161
|
+
'在线人数': ['online', 'data.online', 'live.online', 'room.online', 'data.live.online'],
|
|
162
|
+
'关注数': ['attention', 'data.attention', 'live.attention', 'stast.attention', 'data.live.attention'],
|
|
163
|
+
'文件大小': ['size', 'size_str', 'item.size', 'item.size_str', 'data.size', 'data.item.size_str'],
|
|
164
|
+
'直播间地址': ['room_url', 'live.room_url', 'data.room_url', 'live.url', 'data.live.room_url'],
|
|
165
|
+
'直播间ID': ['room_id', 'live.room_id', 'data.room_id', 'live.room_id', 'data.live.room_id'],
|
|
166
|
+
'直播间状态': ['status', 'live.status', 'data.status', 'room.status', 'data.live.status'],
|
|
167
|
+
'图片数量': ['count', 'data.count', 'item.count', 'images.length', 'data.images.length', 'data.item.count'],
|
|
168
|
+
'作者ID': ['userId', 'userID', 'author_id', 'data.userId', 'item.userID', 'author.mid', 'user.mid', 'data.item.userID', 'data.author_id', 'data.user.mid'],
|
|
177
169
|
};
|
|
178
170
|
function getErrorInfo(code, detail) {
|
|
179
171
|
const baseMsg = exports.ErrorMessageMap[code] || exports.ErrorMessageMap[ErrorCode.UNKNOWN_ERROR];
|
|
@@ -393,6 +385,39 @@ function formatDuration(input) {
|
|
|
393
385
|
const secs = Math.floor(seconds % 60);
|
|
394
386
|
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
|
|
395
387
|
}
|
|
388
|
+
function formatPublishTime(value) {
|
|
389
|
+
if (!value)
|
|
390
|
+
return '';
|
|
391
|
+
const str = String(value).trim();
|
|
392
|
+
if (/^\d{10,}$/.test(str) && Number(str) > 1e12) {
|
|
393
|
+
if (Number(str) > 1e15) {
|
|
394
|
+
value = Number(str) / 1000;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
try {
|
|
398
|
+
const d = new Date(/^\d+$/.test(str) ? Number(str) * 1000 : str);
|
|
399
|
+
if (isNaN(d.getTime()))
|
|
400
|
+
return '';
|
|
401
|
+
const y = d.getFullYear();
|
|
402
|
+
const m = (d.getMonth() + 1).toString().padStart(2, '0');
|
|
403
|
+
const d_ = d.getDate().toString().padStart(2, '0');
|
|
404
|
+
const H = d.getHours().toString().padStart(2, '0');
|
|
405
|
+
const i = d.getMinutes().toString().padStart(2, '0');
|
|
406
|
+
const parts = [];
|
|
407
|
+
if (y > 2000)
|
|
408
|
+
parts.push(`${y}年`);
|
|
409
|
+
if (m)
|
|
410
|
+
parts.push(`${m}月`);
|
|
411
|
+
if (d_)
|
|
412
|
+
parts.push(`${d_}日`);
|
|
413
|
+
if (H && i)
|
|
414
|
+
parts.push(`${H}:${i}`);
|
|
415
|
+
return parts.join(' ').trim();
|
|
416
|
+
}
|
|
417
|
+
catch {
|
|
418
|
+
return str;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
396
421
|
function getNestedValue(obj, path) {
|
|
397
422
|
if (!obj || typeof obj !== 'object' || !path)
|
|
398
423
|
return undefined;
|
|
@@ -436,15 +461,10 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
436
461
|
Object.entries(VARIABLE_MAPPING).forEach(([varName, keys]) => {
|
|
437
462
|
let value = findValueInObject(data, keys) || findValueInObject(rootData, keys);
|
|
438
463
|
if (varName === '图片数量' && value === undefined) {
|
|
439
|
-
value = Array.isArray(data.images) ? data.images.length :
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
const w = findValueInObject(data, ['width', 'item.width']) || findValueInObject(rootData, ['width', 'item.width']);
|
|
444
|
-
if (h && w)
|
|
445
|
-
value = `${w}x${h}`;
|
|
446
|
-
else if (data.h_w && Array.isArray(data.h_w) && data.h_w.length)
|
|
447
|
-
value = data.h_w.join(', ');
|
|
464
|
+
value = Array.isArray(data.images) ? data.images.length :
|
|
465
|
+
Array.isArray(rootData.images) ? rootData.images.length :
|
|
466
|
+
Array.isArray(data.imgurl) ? data.imgurl.length :
|
|
467
|
+
Array.isArray(rootData.imgurl) ? rootData.imgurl.length : undefined;
|
|
448
468
|
}
|
|
449
469
|
if (value !== undefined && value !== null && value !== '') {
|
|
450
470
|
stat[varName] = value;
|
|
@@ -459,33 +479,62 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
459
479
|
type = 'cv';
|
|
460
480
|
else if (rootData.msg === 'live')
|
|
461
481
|
type = 'live';
|
|
462
|
-
else if ((data.images && data.images.length > 1) || (rootData.images && rootData.images.length > 1)
|
|
482
|
+
else if ((data.images && data.images.length > 1) || (rootData.images && rootData.images.length > 1) ||
|
|
483
|
+
(data.imgurl && data.imgurl.length > 1) || (rootData.imgurl && rootData.imgurl.length > 1))
|
|
463
484
|
type = '图集';
|
|
464
|
-
const title = stat['标题'] ||
|
|
465
|
-
|
|
466
|
-
|
|
485
|
+
const title = stat['标题'] || data.note_title || data.title || data.content_title || data.item?.title || rootData.title || '无标题';
|
|
486
|
+
let author = stat['作者'] || data.author?.name || data.nickname || data.user_name || data.item?.author ||
|
|
487
|
+
rootData.author || data.user?.name || data.owner?.name || '未知作者';
|
|
488
|
+
if (typeof author === 'object' && author.name)
|
|
489
|
+
author = author.name;
|
|
490
|
+
const rawDesc = stat['简介'] || data.note_desc || data.content || data.text || data.description ||
|
|
491
|
+
data.item?.description || rootData.desc || rootData.description || '';
|
|
467
492
|
const desc = rawDesc.length > 0 ? rawDesc.slice(0, maxDescLength) : (title.length > 0 ? title : '暂无简介');
|
|
468
|
-
const cover = data.cover
|
|
493
|
+
const cover = data.cover || data.imgurl || data.pic || data.thumbnail || data.cover_url ||
|
|
494
|
+
data.item?.cover || rootData.cover || (Array.isArray(data.images) && data.images[0]) ||
|
|
495
|
+
(Array.isArray(rootData.images) && rootData.images[0]) || '';
|
|
469
496
|
let images = [];
|
|
470
|
-
const
|
|
471
|
-
|
|
472
|
-
images
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
497
|
+
const imgSources = [
|
|
498
|
+
data.images, data.pics, data.pic_urls, data.image_list, data.imgurl,
|
|
499
|
+
rootData.images, rootData.pics, rootData.pic_urls, rootData.image_list, rootData.imgurl,
|
|
500
|
+
data.item?.images
|
|
501
|
+
];
|
|
502
|
+
for (const source of imgSources) {
|
|
503
|
+
if (Array.isArray(source) && source.length > 0) {
|
|
504
|
+
images = source.filter(i => i && typeof i === 'string');
|
|
505
|
+
break;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
let video = data.video?.url || data.item?.url || data.url || data.download_url || data.playUrl ||
|
|
509
|
+
data.video_url || rootData.url || data.item?.url || '';
|
|
510
|
+
const durationValue = stat['视频时长'] || data.item?.duration || data.duration || 0;
|
|
477
511
|
const duration = typeof durationValue === 'number' ? durationValue : parseInt(durationValue) || 0;
|
|
478
512
|
const durationFormatted = formatDuration(durationValue);
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
513
|
+
const pubTime = formatPublishTime(stat['发布时间']);
|
|
514
|
+
if (pubTime)
|
|
515
|
+
stat['发布时间'] = pubTime;
|
|
516
|
+
else
|
|
517
|
+
delete stat['发布时间'];
|
|
518
|
+
const durShow = durationFormatted === '00:00:00' && (String(durationValue).length > 12) ? '' : durationFormatted;
|
|
519
|
+
if (durShow)
|
|
520
|
+
stat['视频时长'] = durShow;
|
|
521
|
+
else
|
|
522
|
+
delete stat['视频时长'];
|
|
523
|
+
const sizeVal = stat['文件大小'];
|
|
524
|
+
if (sizeVal && !String(sizeVal).includes('MB')) {
|
|
525
|
+
const num = Number(sizeVal);
|
|
526
|
+
if (!isNaN(num) && num > 0)
|
|
527
|
+
stat['文件大小'] = `${num.toFixed(2)} MB`;
|
|
528
|
+
}
|
|
529
|
+
const live_photo = data.live_photo || rootData.live_photo || [];
|
|
530
|
+
const h_w = data.item?.h_w || rootData.h_w || [];
|
|
531
|
+
const quality_urls = data.quality_urls || rootData.quality_urls || {};
|
|
532
|
+
const default_quality = data.default_quality || rootData.default_quality || '';
|
|
533
|
+
const download_url = data.download_url || video;
|
|
534
|
+
const play_count = stat['播放数'] || '';
|
|
535
|
+
const reposts_count = Number(stat['转发数']) || data.reposts_count || rootData.reposts_count || 0;
|
|
536
|
+
const attitudes_count = Number(stat['点赞数']) || data.attitudes_count || rootData.attitudes_count || 0;
|
|
537
|
+
const comments_count = Number(stat['评论数']) || data.comments_count || rootData.comments_count || 0;
|
|
489
538
|
return {
|
|
490
539
|
type: type,
|
|
491
540
|
rawData: rawResponse,
|
|
@@ -499,9 +548,8 @@ function parseData(rawResponse, maxDescLength) {
|
|
|
499
548
|
durationFormatted,
|
|
500
549
|
stat,
|
|
501
550
|
live_photo,
|
|
502
|
-
music: String(music),
|
|
503
551
|
h_w,
|
|
504
|
-
jx: data.jx
|
|
552
|
+
jx: data.jx || null,
|
|
505
553
|
quality_urls,
|
|
506
554
|
default_quality,
|
|
507
555
|
download_url,
|
|
@@ -635,7 +683,7 @@ function apply(ctx, config) {
|
|
|
635
683
|
}
|
|
636
684
|
const isSuccess = resData.code === 0 || resData.code === 200 || resData.code === 1 ||
|
|
637
685
|
(resData.msg && (resData.msg.includes('解析成功') || resData.msg.includes('success') || resData.msg.includes('请求成功'))) ||
|
|
638
|
-
!!resData.data || !!resData.result || !!resData.video || !!resData.images;
|
|
686
|
+
!!resData.data || !!resData.result || !!resData.video || !!resData.images || !!resData.imgurl;
|
|
639
687
|
if (!isSuccess) {
|
|
640
688
|
const apiErrorMsg = resData.msg || resData.error || '解析失败';
|
|
641
689
|
const code = ErrorCode.API_RETURN_ERROR;
|
|
@@ -699,7 +747,6 @@ function apply(ctx, config) {
|
|
|
699
747
|
video: parseData.video,
|
|
700
748
|
type: parseData.type,
|
|
701
749
|
live_photo: parseData.live_photo,
|
|
702
|
-
music: parseData.music,
|
|
703
750
|
h_w: parseData.h_w,
|
|
704
751
|
quality_urls: parseData.quality_urls,
|
|
705
752
|
default_quality: parseData.default_quality,
|
|
@@ -784,7 +831,7 @@ function apply(ctx, config) {
|
|
|
784
831
|
forwardMessages.push(buildForwardNode(session, koishi_1.h.file(dl.filePath), botName));
|
|
785
832
|
}
|
|
786
833
|
else {
|
|
787
|
-
forwardMessages.push(buildForwardNode(session, koishi_1.h.
|
|
834
|
+
forwardMessages.push(buildForwardNode(session, koishi_1.h.video(item.video), botName));
|
|
788
835
|
}
|
|
789
836
|
}
|
|
790
837
|
else {
|
|
@@ -792,7 +839,7 @@ function apply(ctx, config) {
|
|
|
792
839
|
}
|
|
793
840
|
}
|
|
794
841
|
catch (e) {
|
|
795
|
-
forwardMessages.push(buildForwardNode(session, koishi_1.h.
|
|
842
|
+
forwardMessages.push(buildForwardNode(session, koishi_1.h.video(item.video), botName));
|
|
796
843
|
}
|
|
797
844
|
}
|
|
798
845
|
}
|
|
@@ -816,7 +863,7 @@ function apply(ctx, config) {
|
|
|
816
863
|
await sendTimeout(session, koishi_1.h.video(item.video));
|
|
817
864
|
}
|
|
818
865
|
catch (e) {
|
|
819
|
-
await sendTimeout(session,
|
|
866
|
+
await sendTimeout(session, koishi_1.h.video(item.video));
|
|
820
867
|
}
|
|
821
868
|
await delay(500);
|
|
822
869
|
}
|
package/package.json
CHANGED