bililive-cli 3.22.2 → 4.1.0
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/{fileFromPath-BycXkXgu.cjs → fileFromPath-DN6n6hnT.cjs} +2 -2
- package/lib/{index-yHivC5bo.cjs → index-BfVtxagW.cjs} +116 -25
- package/lib/{index-Bqpkb00O.cjs → index-CyQ_VJuq.cjs} +1479 -897
- package/lib/index.cjs +3 -3
- package/lib/{linux-Cy2IwLL8.cjs → linux-BInfI0l8.cjs} +1 -1
- package/package.json +11 -6
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var require$$0 = require('fs');
|
|
4
4
|
var require$$0$1 = require('path');
|
|
5
|
-
var index$1 = require('./index-
|
|
6
|
-
var index = require('./index-
|
|
5
|
+
var index$1 = require('./index-CyQ_VJuq.cjs');
|
|
6
|
+
var index = require('./index-BfVtxagW.cjs');
|
|
7
7
|
require('node:dns');
|
|
8
8
|
require('constants');
|
|
9
9
|
require('stream');
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var path$3 = require('node:path');
|
|
4
3
|
var http$4 = require('node:http');
|
|
5
|
-
var urlLib = require('node:url');
|
|
6
4
|
var https = require('node:https');
|
|
7
|
-
var index$1 = require('./index-
|
|
5
|
+
var index$1 = require('./index-CyQ_VJuq.cjs');
|
|
8
6
|
var require$$0$5 = require('tty');
|
|
9
7
|
var require$$1$4 = require('util');
|
|
10
8
|
var require$$0$b = require('assert');
|
|
@@ -20,7 +18,9 @@ var require$$1$2 = require('http');
|
|
|
20
18
|
var require$$4$1 = require('net');
|
|
21
19
|
var require$$5$1 = require('querystring');
|
|
22
20
|
var require$$17 = require('async_hooks');
|
|
21
|
+
var urlLib = require('node:url');
|
|
23
22
|
var require$$1$5 = require('string_decoder');
|
|
23
|
+
var path$3 = require('node:path');
|
|
24
24
|
var os$1 = require('node:os');
|
|
25
25
|
var require$$1$6 = require('os');
|
|
26
26
|
var require$$1$1 = require('node:child_process');
|
|
@@ -38,7 +38,6 @@ var require$$0$d = require('node:stream');
|
|
|
38
38
|
var web = require('node:stream/web');
|
|
39
39
|
var shazamioCore = require('shazamio-core');
|
|
40
40
|
|
|
41
|
-
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
42
41
|
/**
|
|
43
42
|
* 百度网盘上传类
|
|
44
43
|
* 使用 BaiduPCS-Go 工具进行文件上传
|
|
@@ -48296,17 +48295,18 @@ router$h.post("/import", upload$1.single("file"), async (ctx) => {
|
|
|
48296
48295
|
// 如果filename是 appConfig.json,那么替换掉ffmpegPath、ffprobePath、danmuFactoryPath配置
|
|
48297
48296
|
if (filename === "appConfig.json") {
|
|
48298
48297
|
const data = await index$1.fs.readJSON(path$3.join(userDataPath, `${filename}.backup`));
|
|
48299
|
-
const
|
|
48300
|
-
|
|
48301
|
-
|
|
48302
|
-
|
|
48303
|
-
|
|
48304
|
-
|
|
48305
|
-
|
|
48306
|
-
|
|
48307
|
-
|
|
48308
|
-
|
|
48309
|
-
await index$1.fs.writeJSON(filePath,
|
|
48298
|
+
const importedConfig = await index$1.fs.readJSON(configPath);
|
|
48299
|
+
importedConfig.ffmpegPath = data.ffmpegPath;
|
|
48300
|
+
importedConfig.ffprobePath = data.ffprobePath;
|
|
48301
|
+
importedConfig.danmuFactoryPath = data.danmuFactoryPath;
|
|
48302
|
+
importedConfig.mesioPath = data.mesioPath;
|
|
48303
|
+
importedConfig.bililiveRecorderPath = data.bililiveRecorderPath;
|
|
48304
|
+
importedConfig.audiowaveformPath = data.audiowaveformPath;
|
|
48305
|
+
importedConfig.webhook.recoderFolder = data.webhook.recoderFolder;
|
|
48306
|
+
importedConfig.recorder.savePath = data.recorder.savePath;
|
|
48307
|
+
importedConfig.losslessCutPath = data.losslessCutPath;
|
|
48308
|
+
await index$1.fs.writeJSON(filePath, importedConfig);
|
|
48309
|
+
appConfig.getAll();
|
|
48310
48310
|
}
|
|
48311
48311
|
}
|
|
48312
48312
|
else if (filename === "app.db") {
|
|
@@ -62606,7 +62606,7 @@ class MultipartBody {
|
|
|
62606
62606
|
let fileFromPathWarned = false;
|
|
62607
62607
|
async function fileFromPath(path, ...args) {
|
|
62608
62608
|
// this import fails in environments that don't handle export maps correctly, like old versions of Jest
|
|
62609
|
-
const { fileFromPath: _fileFromPath } = await Promise.resolve().then(function () { return require('./fileFromPath-
|
|
62609
|
+
const { fileFromPath: _fileFromPath } = await Promise.resolve().then(function () { return require('./fileFromPath-DN6n6hnT.cjs'); });
|
|
62610
62610
|
if (!fileFromPathWarned) {
|
|
62611
62611
|
console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path)}) instead`);
|
|
62612
62612
|
fileFromPathWarned = true;
|
|
@@ -73737,6 +73737,28 @@ const getRecordDuration = (record) => {
|
|
|
73737
73737
|
return 0;
|
|
73738
73738
|
};
|
|
73739
73739
|
const toSessionKey = (record) => record.live_id || UNKNOWN_LIVE_ID;
|
|
73740
|
+
const parseDanmaTimeline = (value) => {
|
|
73741
|
+
if (!value)
|
|
73742
|
+
return undefined;
|
|
73743
|
+
try {
|
|
73744
|
+
const parsed = JSON.parse(value);
|
|
73745
|
+
const interval = parsed.danmaTimeline?.interval;
|
|
73746
|
+
const data = parsed.danmaTimeline?.data;
|
|
73747
|
+
if (typeof interval !== "number" ||
|
|
73748
|
+
!Number.isFinite(interval) ||
|
|
73749
|
+
interval <= 0 ||
|
|
73750
|
+
!Array.isArray(data)) {
|
|
73751
|
+
return undefined;
|
|
73752
|
+
}
|
|
73753
|
+
return {
|
|
73754
|
+
interval,
|
|
73755
|
+
data: data.map((item) => typeof item === "number" && Number.isFinite(item) && item >= 0 ? Math.round(item) : 0),
|
|
73756
|
+
};
|
|
73757
|
+
}
|
|
73758
|
+
catch {
|
|
73759
|
+
return undefined;
|
|
73760
|
+
}
|
|
73761
|
+
};
|
|
73740
73762
|
const toSessionCard = (records) => {
|
|
73741
73763
|
const sortedRecords = [...records].sort((left, right) => right.record_start_time - left.record_start_time);
|
|
73742
73764
|
const latestRecord = sortedRecords[0] || null;
|
|
@@ -73771,6 +73793,7 @@ const toSessionCard = (records) => {
|
|
|
73771
73793
|
video_duration: item.video_duration,
|
|
73772
73794
|
danma_num: item.danma_num,
|
|
73773
73795
|
interact_num: item.interact_num,
|
|
73796
|
+
danmaTimeline: parseDanmaTimeline(item.danma_stats_json),
|
|
73774
73797
|
quick_hash: item.quick_hash,
|
|
73775
73798
|
})),
|
|
73776
73799
|
};
|
|
@@ -73838,8 +73861,15 @@ function queryStreamerDetail(args) {
|
|
|
73838
73861
|
data: pagedCards,
|
|
73839
73862
|
};
|
|
73840
73863
|
}
|
|
73864
|
+
function queryRecordStartTimes(args) {
|
|
73865
|
+
const streamer = index$1.streamerService.query({ room_id: args.room_id, platform: args.platform });
|
|
73866
|
+
if (!streamer || args.startTime === undefined || args.endTime === undefined)
|
|
73867
|
+
return [];
|
|
73868
|
+
return index$1.recordHistoryService.getRecordStartTimes(streamer.id, args.startTime, args.endTime);
|
|
73869
|
+
}
|
|
73841
73870
|
var streamerDetailService = {
|
|
73842
73871
|
queryStreamerDetail,
|
|
73872
|
+
queryRecordStartTimes,
|
|
73843
73873
|
};
|
|
73844
73874
|
|
|
73845
73875
|
const router$b = new Router$1({
|
|
@@ -74030,6 +74060,43 @@ router$b.get("/detail", async (ctx) => {
|
|
|
74030
74060
|
},
|
|
74031
74061
|
};
|
|
74032
74062
|
});
|
|
74063
|
+
router$b.get("/calendar", (ctx) => {
|
|
74064
|
+
const recorderId = getSingleQueryValue$1(ctx.request.query.recorderId);
|
|
74065
|
+
const startTime = Number(getSingleQueryValue$1(ctx.request.query.startTime));
|
|
74066
|
+
const endTime = Number(getSingleQueryValue$1(ctx.request.query.endTime));
|
|
74067
|
+
if (!recorderId ||
|
|
74068
|
+
!Number.isSafeInteger(startTime) ||
|
|
74069
|
+
!Number.isSafeInteger(endTime) ||
|
|
74070
|
+
startTime < 0 ||
|
|
74071
|
+
endTime <= startTime ||
|
|
74072
|
+
endTime - startTime > 32 * 24 * 60 * 60 * 1000) {
|
|
74073
|
+
ctx.status = 400;
|
|
74074
|
+
ctx.body = { message: "录制器和有效的月份时间范围不能为空" };
|
|
74075
|
+
return;
|
|
74076
|
+
}
|
|
74077
|
+
let recorder;
|
|
74078
|
+
try {
|
|
74079
|
+
recorder = recorderService.getRecorder({ id: recorderId });
|
|
74080
|
+
}
|
|
74081
|
+
catch {
|
|
74082
|
+
ctx.status = 404;
|
|
74083
|
+
ctx.body = { message: "录制器不存在" };
|
|
74084
|
+
return;
|
|
74085
|
+
}
|
|
74086
|
+
if (!recorder) {
|
|
74087
|
+
ctx.status = 404;
|
|
74088
|
+
ctx.body = { message: "录制器不存在" };
|
|
74089
|
+
return;
|
|
74090
|
+
}
|
|
74091
|
+
ctx.body = {
|
|
74092
|
+
payload: streamerDetailService.queryRecordStartTimes({
|
|
74093
|
+
room_id: recorder.channelId,
|
|
74094
|
+
platform: recorder.providerId,
|
|
74095
|
+
startTime,
|
|
74096
|
+
endTime,
|
|
74097
|
+
}),
|
|
74098
|
+
};
|
|
74099
|
+
});
|
|
74033
74100
|
router$b.get("/ws/danma-test", async (ctx) => {
|
|
74034
74101
|
ctx.status = 426;
|
|
74035
74102
|
ctx.body = {
|
|
@@ -74046,7 +74113,7 @@ router$b.get("/ws/danma-test", async (ctx) => {
|
|
|
74046
74113
|
};
|
|
74047
74114
|
});
|
|
74048
74115
|
router$b.post("/add", async (ctx) => {
|
|
74049
|
-
const args = index$1.pick((ctx.request.body ?? {}), "providerId", "channelId", "remarks", "disableAutoCheck", "quality", "streamPriorities", "sourcePriorities", "extra", "noGlobalFollowFields", "line", "disableProvideCommentsWhenRecording", "saveGiftDanma", "saveSCDanma", "segment", "sendToWebhook", "uid", "saveCover", "convert2Mp4", "qualityRetry", "formatName", "useM3U8Proxy", "customHost", "codecName", "titleKeywords", "segmentOnTitleChange", "liveStartNotification", "chargeLiveNotification", "liveEndNotification", "weight", "source", "videoFormat", "recorderType", "cookie", "doubleScreen", "onlyAudio", "useServerTimestamp", "handleTime", "debugLevel", "api");
|
|
74116
|
+
const args = index$1.pick((ctx.request.body ?? {}), "providerId", "channelId", "remarks", "disableAutoCheck", "quality", "streamPriorities", "sourcePriorities", "extra", "noGlobalFollowFields", "line", "disableProvideCommentsWhenRecording", "saveGiftDanma", "saveSCDanma", "saveDanmaStats2DB", "segment", "sendToWebhook", "uid", "saveCover", "convert2Mp4", "qualityRetry", "formatName", "useM3U8Proxy", "customHost", "codecName", "titleKeywords", "segmentOnTitleChange", "liveStartNotification", "chargeLiveNotification", "liveEndNotification", "weight", "source", "videoFormat", "recorderType", "cookie", "doubleScreen", "cookieMode", "onlyAudio", "useServerTimestamp", "handleTime", "debugLevel", "api");
|
|
74050
74117
|
const data = await recorderService.addRecorder(args);
|
|
74051
74118
|
ctx.body = { payload: data };
|
|
74052
74119
|
});
|
|
@@ -74075,7 +74142,7 @@ router$b.post("/:id/stream", async (ctx) => {
|
|
|
74075
74142
|
});
|
|
74076
74143
|
router$b.put("/:id", (ctx) => {
|
|
74077
74144
|
const { id } = ctx.params;
|
|
74078
|
-
const patch = index$1.pick(ctx.request.body, "remarks", "disableAutoCheck", "quality", "streamPriorities", "sourcePriorities", "noGlobalFollowFields", "line", "disableProvideCommentsWhenRecording", "saveGiftDanma", "saveSCDanma", "saveCover", "segment", "sendToWebhook", "uid", "qualityRetry", "formatName", "useM3U8Proxy", "customHost", "codecName", "titleKeywords", "segmentOnTitleChange", "liveStartNotification", "chargeLiveNotification", "liveEndNotification", "weight", "source", "videoFormat", "recorderType", "cookie", "doubleScreen", "onlyAudio", "useServerTimestamp", "handleTime", "debugLevel", "convert2Mp4", "api");
|
|
74145
|
+
const patch = index$1.pick(ctx.request.body, "remarks", "disableAutoCheck", "quality", "streamPriorities", "sourcePriorities", "noGlobalFollowFields", "line", "disableProvideCommentsWhenRecording", "saveGiftDanma", "saveSCDanma", "saveDanmaStats2DB", "saveCover", "segment", "sendToWebhook", "uid", "qualityRetry", "formatName", "useM3U8Proxy", "customHost", "codecName", "titleKeywords", "segmentOnTitleChange", "liveStartNotification", "chargeLiveNotification", "liveEndNotification", "weight", "source", "videoFormat", "recorderType", "cookie", "doubleScreen", "cookieMode", "onlyAudio", "useServerTimestamp", "handleTime", "debugLevel", "convert2Mp4", "api");
|
|
74079
74146
|
ctx.body = { payload: recorderService.updateRecorder({ id, ...patch }) };
|
|
74080
74147
|
});
|
|
74081
74148
|
/**
|
|
@@ -74447,9 +74514,16 @@ router$a.post("/login", async (ctx) => {
|
|
|
74447
74514
|
});
|
|
74448
74515
|
tv.on("completed", async (res) => {
|
|
74449
74516
|
loginObj[id].res = JSON.stringify(res);
|
|
74450
|
-
|
|
74451
|
-
|
|
74452
|
-
|
|
74517
|
+
try {
|
|
74518
|
+
const data = res.data;
|
|
74519
|
+
await index$1.biliApi.addUser(data);
|
|
74520
|
+
loginObj[id].uid = data.mid;
|
|
74521
|
+
loginObj[id].status = "completed";
|
|
74522
|
+
}
|
|
74523
|
+
catch (error) {
|
|
74524
|
+
loginObj[id].failReason = error instanceof Error ? error.message : String(error);
|
|
74525
|
+
loginObj[id].status = "error";
|
|
74526
|
+
}
|
|
74453
74527
|
});
|
|
74454
74528
|
const url = await tv.login();
|
|
74455
74529
|
ctx.body = {
|
|
@@ -74495,6 +74569,20 @@ router$a.post("/formatTitle", async (ctx) => {
|
|
|
74495
74569
|
const title = index$1.formatTitle(data.options, template);
|
|
74496
74570
|
ctx.body = title;
|
|
74497
74571
|
});
|
|
74572
|
+
router$a.post("/formatSeasonTitle", async (ctx) => {
|
|
74573
|
+
const { template, mediaTitleTemplate } = ctx.request.body;
|
|
74574
|
+
const options = {
|
|
74575
|
+
title: "标题",
|
|
74576
|
+
username: "主播名",
|
|
74577
|
+
time: new Date().toISOString(),
|
|
74578
|
+
roomId: 123456,
|
|
74579
|
+
filename: "文件名",
|
|
74580
|
+
};
|
|
74581
|
+
ctx.body = index$1.formatSeasonTitle({
|
|
74582
|
+
...options,
|
|
74583
|
+
mediaTitle: index$1.formatTitle(options, mediaTitleTemplate || options.title),
|
|
74584
|
+
}, template);
|
|
74585
|
+
});
|
|
74498
74586
|
router$a.post("/formatPartTitle", async (ctx) => {
|
|
74499
74587
|
const data = ctx.request.body;
|
|
74500
74588
|
const template = (data.template || "");
|
|
@@ -74568,7 +74656,7 @@ router$9.get("/login/poll", async (ctx) => {
|
|
|
74568
74656
|
if (result.status === "completed") {
|
|
74569
74657
|
index$1.writeDouyuUser(result.user);
|
|
74570
74658
|
sessions.delete(id);
|
|
74571
|
-
ctx.body = { status: "completed" };
|
|
74659
|
+
ctx.body = { status: "completed", uid: result.user.uid };
|
|
74572
74660
|
return;
|
|
74573
74661
|
}
|
|
74574
74662
|
if (result.status === "error")
|
|
@@ -77251,6 +77339,7 @@ class ConfigManager {
|
|
|
77251
77339
|
const appConfigAll = this.getAppConfigAll();
|
|
77252
77340
|
const roomSetting = appConfigAll.webhook?.rooms?.[roomId];
|
|
77253
77341
|
const danmu = this.getRoomSetting("danmu", roomSetting) ?? false;
|
|
77342
|
+
const burnWithoutDanmu = this.getRoomSetting("burnWithoutDanmu", roomSetting) ?? false;
|
|
77254
77343
|
const mergePart = this.getRoomSetting("autoPartMerge", roomSetting) ?? false;
|
|
77255
77344
|
const minSize = this.getRoomSetting("minSize", roomSetting) ?? 10;
|
|
77256
77345
|
const uploadPresetId = this.getRoomSetting("uploadPresetId", roomSetting) || "default";
|
|
@@ -77312,6 +77401,7 @@ class ConfigManager {
|
|
|
77312
77401
|
const open = this.canRoomOpen(roomSetting, appConfigAll?.webhook?.blacklist, roomId);
|
|
77313
77402
|
return {
|
|
77314
77403
|
danmu,
|
|
77404
|
+
burnWithoutDanmu,
|
|
77315
77405
|
mergePart,
|
|
77316
77406
|
minSize,
|
|
77317
77407
|
uploadPresetId,
|
|
@@ -78428,7 +78518,8 @@ class WebhookHandler {
|
|
|
78428
78518
|
async processDanmuVideo(context, options, config, xmlFilePath) {
|
|
78429
78519
|
try {
|
|
78430
78520
|
// 验证弹幕文件
|
|
78431
|
-
|
|
78521
|
+
const hasDanmu = (await index$1.fs.pathExists(xmlFilePath)) && !(await index$1.isEmptyDanmu(xmlFilePath));
|
|
78522
|
+
if (!hasDanmu && !config.burnWithoutDanmu) {
|
|
78432
78523
|
context.part.recordStatus = "handled";
|
|
78433
78524
|
context.part.uploadStatus = "pending";
|
|
78434
78525
|
index$1.logObj.warn(`弹幕文件不存在或为空,跳过弹幕压制: ${xmlFilePath}`);
|
|
@@ -78453,6 +78544,7 @@ class WebhookHandler {
|
|
|
78453
78544
|
danmaOptions: danmuConfig.config,
|
|
78454
78545
|
ffmpegOptions: ffmpegPreset.config,
|
|
78455
78546
|
hasHotProgress: config.hotProgress,
|
|
78547
|
+
ignoreDanmu: !hasDanmu,
|
|
78456
78548
|
hotProgressOptions: {
|
|
78457
78549
|
interval: config.hotProgressSample || 30,
|
|
78458
78550
|
color: config.hotProgressColor || "#f9f5f3",
|
|
@@ -78465,7 +78557,7 @@ class WebhookHandler {
|
|
|
78465
78557
|
});
|
|
78466
78558
|
context.part.filePath = output;
|
|
78467
78559
|
context.part.recordStatus = "handled";
|
|
78468
|
-
return { conversionSuccessful: true, danmuConversionSuccessful:
|
|
78560
|
+
return { conversionSuccessful: true, danmuConversionSuccessful: hasDanmu };
|
|
78469
78561
|
}
|
|
78470
78562
|
catch (error) {
|
|
78471
78563
|
index$1.logObj.error(error);
|
|
@@ -79373,7 +79465,6 @@ let handler;
|
|
|
79373
79465
|
let appConfig;
|
|
79374
79466
|
let container;
|
|
79375
79467
|
const fileCache = createFileCache();
|
|
79376
|
-
path$3.dirname(urlLib.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-yHivC5bo.cjs', document.baseURI).href))));
|
|
79377
79468
|
const authMiddleware = (passKey) => {
|
|
79378
79469
|
return async (ctx, next) => {
|
|
79379
79470
|
const authHeader = ctx.headers["authorization"] || ctx.request.query.auth;
|