bililive-cli 3.13.1 → 3.14.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.
@@ -4,7 +4,7 @@ var path$7 = require('node:path');
4
4
  var require$$2$1 = require('node:http');
5
5
  var require$$1$2 = require('node:url');
6
6
  var a = require('node:https');
7
- var index = require('./index-CgpPN0zA.cjs');
7
+ var index = require('./index-DnN22ZAd.cjs');
8
8
  var require$$0$4 = require('tty');
9
9
  var require$$1$3 = require('util');
10
10
  var require$$0$b = require('assert');
@@ -13968,9 +13968,9 @@ for (const method of methods$1) {
13968
13968
 
13969
13969
  Router.prototype.del = Router.prototype['delete'];
13970
13970
 
13971
- var router$h = Router;
13971
+ var router$i = Router;
13972
13972
 
13973
- var Router$1 = /*@__PURE__*/index.getDefaultExportFromCjs(router$h);
13973
+ var Router$1 = /*@__PURE__*/index.getDefaultExportFromCjs(router$i);
13974
13974
 
13975
13975
  const vary = varyExports;
13976
13976
 
@@ -30882,11 +30882,11 @@ var recorderService = {
30882
30882
  resolve,
30883
30883
  };
30884
30884
 
30885
- const router$g = new Router$1();
30886
- router$g.get("/webhook", async (ctx) => {
30885
+ const router$h = new Router$1();
30886
+ router$h.get("/webhook", async (ctx) => {
30887
30887
  ctx.body = "webhook 服务器已启动";
30888
30888
  });
30889
- router$g.post("/webhook/bililiverecorder", async (ctx) => {
30889
+ router$h.post("/webhook/bililiverecorder", async (ctx) => {
30890
30890
  const config = exports.appConfig.getAll();
30891
30891
  index.logObj.info("录播姬:", ctx.request.body);
30892
30892
  const event = ctx.request.body;
@@ -30915,7 +30915,7 @@ router$g.post("/webhook/bililiverecorder", async (ctx) => {
30915
30915
  }
30916
30916
  ctx.body = "ok";
30917
30917
  });
30918
- router$g.post("/webhook/blrec", async (ctx) => {
30918
+ router$h.post("/webhook/blrec", async (ctx) => {
30919
30919
  const webhook = exports.appConfig.get("webhook");
30920
30920
  index.logObj.info("blrec webhook:", ctx.request.body);
30921
30921
  const event = ctx.request.body;
@@ -30950,7 +30950,7 @@ router$g.post("/webhook/blrec", async (ctx) => {
30950
30950
  * OneLiveRec webhook事件处理
30951
30951
  * 由于只有在结束后才能从文件的备注中获取到,只处理结束事件获取信息后模拟开始和结束事件
30952
30952
  */
30953
- router$g.post("/webhook/oneliverec", async (ctx) => {
30953
+ router$h.post("/webhook/oneliverec", async (ctx) => {
30954
30954
  const webhook = exports.appConfig.get("webhook");
30955
30955
  index.logObj.info("oneliverec webhook:", ctx.request.body);
30956
30956
  const event = ctx.request.body;
@@ -30986,7 +30986,7 @@ router$g.post("/webhook/oneliverec", async (ctx) => {
30986
30986
  }
30987
30987
  ctx.body = "ok";
30988
30988
  });
30989
- router$g.post("/webhook/ddtv", async (ctx) => {
30989
+ router$h.post("/webhook/ddtv", async (ctx) => {
30990
30990
  const webhook = exports.appConfig.get("webhook");
30991
30991
  const event = ctx.request.body;
30992
30992
  if (webhook?.open && (event.cmd === "RecordingEnd" || event.cmd === "StartRecording")) {
@@ -31044,7 +31044,7 @@ const getDDTVTrueFile = (event) => {
31044
31044
  danmuFile: danmuFileTruePath,
31045
31045
  };
31046
31046
  };
31047
- router$g.post("/webhook/custom", async (ctx) => {
31047
+ router$h.post("/webhook/custom", async (ctx) => {
31048
31048
  const webhook = exports.appConfig.get("webhook");
31049
31049
  index.logObj.info("custom: webhook", ctx.request.body);
31050
31050
  const event = ctx.request.body;
@@ -31093,7 +31093,7 @@ async function checkFileInterval() {
31093
31093
  }
31094
31094
  }, 1000 * 60);
31095
31095
  }
31096
- router$g.get("/bili/stream", async (ctx) => {
31096
+ router$h.get("/bili/stream", async (ctx) => {
31097
31097
  const { id } = ctx.query;
31098
31098
  try {
31099
31099
  const m3u8Content = await recorderService.getBiliStream(id);
@@ -49108,21 +49108,21 @@ function makePromise(multer, name) {
49108
49108
  multer.diskStorage = originalMulter.diskStorage;
49109
49109
  multer.memoryStorage = originalMulter.memoryStorage;
49110
49110
 
49111
- const router$f = new Router$1({
49111
+ const router$g = new Router$1({
49112
49112
  prefix: "/config",
49113
49113
  });
49114
49114
  const upload$1 = multer({ dest: os$1.tmpdir() });
49115
- router$f.get("/", async (ctx) => {
49115
+ router$g.get("/", async (ctx) => {
49116
49116
  const config = exports.appConfig.getAll();
49117
49117
  ctx.body = config;
49118
49118
  });
49119
- router$f.post("/", async (ctx) => {
49119
+ router$g.post("/", async (ctx) => {
49120
49120
  const data = ctx.request.body;
49121
49121
  // @ts-ignore
49122
49122
  exports.appConfig.setAll(data);
49123
49123
  ctx.body = "success";
49124
49124
  });
49125
- router$f.post("/set", async (ctx) => {
49125
+ router$g.post("/set", async (ctx) => {
49126
49126
  const data = ctx.request.body;
49127
49127
  if (!data.key || !data.value) {
49128
49128
  ctx.body = "key and value is required";
@@ -49132,7 +49132,7 @@ router$f.post("/set", async (ctx) => {
49132
49132
  exports.appConfig.set(data.key, data.value);
49133
49133
  ctx.body = "success";
49134
49134
  });
49135
- router$f.post("/verifyBiliKey", async (ctx) => {
49135
+ router$g.post("/verifyBiliKey", async (ctx) => {
49136
49136
  try {
49137
49137
  const serverKey = process.env.BILILIVE_TOOLS_BILIKEY;
49138
49138
  const configured = typeof serverKey === "string" && serverKey.trim().length > 0;
@@ -49176,7 +49176,7 @@ router$f.post("/verifyBiliKey", async (ctx) => {
49176
49176
  ctx.body = response;
49177
49177
  }
49178
49178
  });
49179
- router$f.post("/resetBin", async (ctx) => {
49179
+ router$g.post("/resetBin", async (ctx) => {
49180
49180
  const data = ctx.request.body;
49181
49181
  const type = data.type;
49182
49182
  if (!type) {
@@ -49233,7 +49233,7 @@ async function exportConfig(opts) {
49233
49233
  const content = zip.generateNodeStream({ type: "nodebuffer" });
49234
49234
  return content;
49235
49235
  }
49236
- router$f.get("/export", async (ctx) => {
49236
+ router$g.get("/export", async (ctx) => {
49237
49237
  try {
49238
49238
  const globalConfig = exports.container.resolve("globalConfig");
49239
49239
  const { configPath, videoPresetPath, danmuPresetPath, ffmpegPresetPath, userDataPath } = globalConfig;
@@ -49266,7 +49266,7 @@ router$f.get("/export", async (ctx) => {
49266
49266
  ctx.body = "export error";
49267
49267
  }
49268
49268
  });
49269
- router$f.post("/import", upload$1.single("file"), async (ctx) => {
49269
+ router$g.post("/import", upload$1.single("file"), async (ctx) => {
49270
49270
  const file = ctx.request?.file?.path;
49271
49271
  if (!file) {
49272
49272
  ctx.status = 400;
@@ -49325,7 +49325,7 @@ router$f.post("/import", upload$1.single("file"), async (ctx) => {
49325
49325
  }));
49326
49326
  ctx.body = "success";
49327
49327
  });
49328
- router$f.post("/notifyTest", async (ctx) => {
49328
+ router$g.post("/notifyTest", async (ctx) => {
49329
49329
  const { title, desp, options, notifyType } = ctx.request.body;
49330
49330
  await index._send(title, desp, options, notifyType);
49331
49331
  ctx.body = "success";
@@ -54117,15 +54117,15 @@ async function handleSrt(input, output) {
54117
54117
  return nodes;
54118
54118
  }
54119
54119
 
54120
- const router$e = new Router$1({
54120
+ const router$f = new Router$1({
54121
54121
  prefix: "/llm",
54122
54122
  });
54123
- router$e.get("/ollama/modelList", async (ctx) => {
54123
+ router$f.get("/ollama/modelList", async (ctx) => {
54124
54124
  const data = ctx.request.query;
54125
54125
  const models = (await ollama.getModelList(data.baseUrl)).models.map((item) => item.name);
54126
54126
  ctx.body = models;
54127
54127
  });
54128
- router$e.post("/translate", async (ctx) => {
54128
+ router$f.post("/translate", async (ctx) => {
54129
54129
  const data = ctx.request.body;
54130
54130
  console.log(data);
54131
54131
  const content = await addTranslateTask(data.input, data.output);
@@ -56436,11 +56436,10 @@ var semver = {
56436
56436
 
56437
56437
  var semver$1 = /*@__PURE__*/index.getDefaultExportFromCjs(semver);
56438
56438
 
56439
- const router$d = new Router$1({
56439
+ const router$e = new Router$1({
56440
56440
  prefix: "/common",
56441
56441
  });
56442
- const upload = multer({ dest: os$1.tmpdir() });
56443
- router$d.get("/version", (ctx) => {
56442
+ router$e.get("/version", (ctx) => {
56444
56443
  ctx.body = exports.config.version;
56445
56444
  });
56446
56445
  function getDriveLetters() {
@@ -56462,7 +56461,7 @@ function getDriveLetters() {
56462
56461
  function isDriveLetter(letter) {
56463
56462
  return /^[a-zA-Z]:\\$/.test(letter);
56464
56463
  }
56465
- router$d.get("/files", async (ctx) => {
56464
+ router$e.get("/files", async (ctx) => {
56466
56465
  const params = ctx.request.query;
56467
56466
  let root = params.path;
56468
56467
  const filterExts = (params.exts || "")
@@ -56518,56 +56517,26 @@ router$d.get("/files", async (ctx) => {
56518
56517
  return;
56519
56518
  }
56520
56519
  });
56521
- router$d.post("/fileJoin", async (ctx) => {
56522
- const { dir, name } = ctx.request.body;
56523
- if (!index.fs.existsSync(dir)) {
56524
- ctx.status = 400;
56525
- ctx.body = "文件夹不存在";
56526
- return;
56527
- }
56528
- const filePath = path$7.join(dir, name);
56529
- ctx.body = filePath;
56530
- });
56531
- router$d.post("/danma/timestamp", async (ctx) => {
56520
+ router$e.post("/danma/timestamp", async (ctx) => {
56532
56521
  const { filepath } = ctx.request.body;
56533
56522
  ctx.body = await index.readXmlTimestamp(filepath);
56534
56523
  });
56535
- router$d.post("/parseVideoMetadata", async (ctx) => {
56524
+ router$e.post("/parseVideoMetadata", async (ctx) => {
56536
56525
  const files = ctx.request.body;
56537
56526
  ctx.body = await index.parseMeta(files);
56538
56527
  });
56539
56528
  /**
56540
56529
  * @api {get} /common/fonts 获取系统字体列表
56541
56530
  */
56542
- router$d.get("/fonts", async (ctx) => {
56531
+ router$e.get("/fonts", async (ctx) => {
56543
56532
  const { getFontsList } = await Promise.resolve().then(function () { return require('./fonts-DxTEygXH.cjs'); });
56544
56533
  ctx.body = await getFontsList();
56545
56534
  });
56546
- router$d.post("/cover/upload", upload.single("file"), async (ctx) => {
56547
- const file = ctx.request?.file?.path;
56548
- if (!file) {
56549
- ctx.status = 400;
56550
- ctx.body = "No file selected";
56551
- return;
56552
- }
56553
- const originalname = ctx.request?.file?.originalname;
56554
- const ext = path$7.extname(originalname);
56555
- const coverPath = path$7.join(exports.config.userDataPath, "cover");
56556
- const outputName = `${index.uuid()}${ext}`;
56557
- // 将图片复制到指定目录
56558
- await index.fs.ensureDir(coverPath);
56559
- await index.fs.copyFile(file, path$7.join(coverPath, outputName));
56560
- await index.fs.remove(file).catch(() => { });
56561
- ctx.body = {
56562
- name: outputName,
56563
- path: `/assets/cover/${outputName}`,
56564
- };
56565
- });
56566
- router$d.get("/appStartTime", async (ctx) => {
56535
+ router$e.get("/appStartTime", async (ctx) => {
56567
56536
  const data = index.statisticsService.query("start_time");
56568
56537
  ctx.body = data?.value;
56569
56538
  });
56570
- router$d.get("/statistics", async (ctx) => {
56539
+ router$e.get("/statistics", async (ctx) => {
56571
56540
  const startTime = index.statisticsService.query("start_time");
56572
56541
  const videoTotalDuaration = index.recordHistoryService.getTotalDuration();
56573
56542
  const recordingNum = recorderService.getRecorderNum(true);
@@ -56579,16 +56548,16 @@ router$d.get("/statistics", async (ctx) => {
56579
56548
  recorderNum,
56580
56549
  };
56581
56550
  });
56582
- router$d.get("/exportLogs", async (ctx) => {
56551
+ router$e.get("/exportLogs", async (ctx) => {
56583
56552
  const logFilePath = exports.config.logPath;
56584
56553
  ctx.body = index.fs.createReadStream(logFilePath);
56585
56554
  });
56586
- router$d.get("/getLogContent", async (ctx) => {
56555
+ router$e.get("/getLogContent", async (ctx) => {
56587
56556
  const logFilePath = exports.config.logPath;
56588
56557
  const content = await index.fs.readFile(logFilePath, "utf-8");
56589
56558
  ctx.body = content;
56590
56559
  });
56591
- router$d.post("/readDanma", async (ctx) => {
56560
+ router$e.post("/readDanma", async (ctx) => {
56592
56561
  const { filepath } = ctx.request.body;
56593
56562
  // 只允许读取ass或xml文件
56594
56563
  if (!filepath.endsWith(".ass") && !filepath.endsWith(".xml") && !filepath.endsWith(".srt")) {
@@ -56604,7 +56573,7 @@ router$d.post("/readDanma", async (ctx) => {
56604
56573
  const content = await index.fs.readFile(filepath, "utf-8");
56605
56574
  ctx.body = content;
56606
56575
  });
56607
- router$d.post("/readLLC", async (ctx) => {
56576
+ router$e.post("/readLLC", async (ctx) => {
56608
56577
  const { filepath } = ctx.request.body;
56609
56578
  if (!(await index.fs.pathExists(filepath))) {
56610
56579
  ctx.status = 400;
@@ -56619,7 +56588,7 @@ router$d.post("/readLLC", async (ctx) => {
56619
56588
  }
56620
56589
  ctx.body = content;
56621
56590
  });
56622
- router$d.post("/writeLLC", async (ctx) => {
56591
+ router$e.post("/writeLLC", async (ctx) => {
56623
56592
  const { filepath, content } = ctx.request.body;
56624
56593
  if (!content.includes("cutSegments")) {
56625
56594
  ctx.status = 400;
@@ -56629,18 +56598,13 @@ router$d.post("/writeLLC", async (ctx) => {
56629
56598
  await index.fs.writeFile(filepath, content, "utf-8");
56630
56599
  ctx.body = "success";
56631
56600
  });
56632
- router$d.post("/fileExists", async (ctx) => {
56633
- const { filepath } = ctx.request.body;
56634
- const exists = await index.fs.pathExists(filepath);
56635
- ctx.body = exists;
56636
- });
56637
- router$d.post("/genTimeData", async (ctx) => {
56601
+ router$e.post("/genTimeData", async (ctx) => {
56638
56602
  const { filepath } = ctx.request.body;
56639
56603
  const data = await index.genTimeData(filepath);
56640
56604
  ctx.body = data;
56641
56605
  });
56642
56606
  // 申请视频ID接口
56643
- router$d.post("/apply-video-id", async (ctx) => {
56607
+ router$e.post("/applyVideoId", async (ctx) => {
56644
56608
  const { videoPath } = ctx.request.body;
56645
56609
  if (!(await index.fs.pathExists(videoPath))) {
56646
56610
  ctx.status = 404;
@@ -56682,6 +56646,7 @@ router$d.post("/apply-video-id", async (ctx) => {
56682
56646
  const expireAt = Date.now() + 24 * 60 * 60 * 1000;
56683
56647
  // 存储ID和视频路径的映射关系
56684
56648
  fileCache.set(videoId, { path: videoPath, expireAt });
56649
+ // 这玩意不能轻易改,空就是默认值
56685
56650
  let type = "";
56686
56651
  switch (extname) {
56687
56652
  case ".flv":
@@ -56697,7 +56662,7 @@ router$d.post("/apply-video-id", async (ctx) => {
56697
56662
  type,
56698
56663
  };
56699
56664
  });
56700
- router$d.get("/video/:videoId", async (ctx) => {
56665
+ router$e.get("/video/:videoId", async (ctx) => {
56701
56666
  const videoId = ctx.params.videoId;
56702
56667
  // 从映射表中获取视频路径
56703
56668
  const videoInfo = fileCache.get(videoId);
@@ -56766,12 +56731,12 @@ router$d.get("/video/:videoId", async (ctx) => {
56766
56731
  ctx.body = index.fs.createReadStream(videoPath);
56767
56732
  }
56768
56733
  });
56769
- router$d.post("/parseDanmu", async (ctx) => {
56734
+ router$e.post("/parseDanmu", async (ctx) => {
56770
56735
  const { filepath } = ctx.request.body;
56771
56736
  const data = await index.parseDanmu(filepath);
56772
56737
  ctx.body = data;
56773
56738
  });
56774
- router$d.post("/testWebhook", async (ctx) => {
56739
+ router$e.post("/testWebhook", async (ctx) => {
56775
56740
  const list = [];
56776
56741
  // 检查所有live数据,如果存在同一个live中,前一个part还在录制中,但是后面的part已经是其他状态,则返回相关id以及文件
56777
56742
  const liveList = exports.handler.liveData;
@@ -56793,7 +56758,7 @@ router$d.post("/testWebhook", async (ctx) => {
56793
56758
  }
56794
56759
  ctx.body = list;
56795
56760
  });
56796
- router$d.post("/handleWebhook", async (ctx) => {
56761
+ router$e.post("/handleWebhook", async (ctx) => {
56797
56762
  const { data } = ctx.request.body;
56798
56763
  const liveList = exports.handler.liveData;
56799
56764
  for (const live of liveList) {
@@ -56809,7 +56774,7 @@ router$d.post("/handleWebhook", async (ctx) => {
56809
56774
  }
56810
56775
  ctx.body = "success";
56811
56776
  });
56812
- router$d.post("/webhook", async (ctx) => {
56777
+ router$e.post("/webhook", async (ctx) => {
56813
56778
  const liveList = exports.handler.liveData;
56814
56779
  ctx.body = liveList;
56815
56780
  });
@@ -56819,7 +56784,7 @@ router$d.post("/webhook", async (ctx) => {
56819
56784
  * 如果不是,检查全局webhook配置,判断是否开启全局开关,判断是否在黑名单,判断配置是否配置了上传预设,上传账号
56820
56785
  * 返回{hasError:boolean,errorInfo:string}
56821
56786
  */
56822
- router$d.get("/whyUploadFailed", async (ctx) => {
56787
+ router$e.get("/whyUploadFailed", async (ctx) => {
56823
56788
  const { roomId } = ctx.request.query;
56824
56789
  if (!roomId) {
56825
56790
  ctx.status = 400;
@@ -56976,7 +56941,7 @@ router$d.get("/whyUploadFailed", async (ctx) => {
56976
56941
  * @apiSuccess {boolean} needUpdate 是否需要更新
56977
56942
  * @apiSuccess {string} [downloadUrl] 下载地址
56978
56943
  */
56979
- router$d.get("/checkUpdate", async (ctx) => {
56944
+ router$e.get("/checkUpdate", async (ctx) => {
56980
56945
  try {
56981
56946
  const res = await fetch("https://githubraw.irenmu.com/renmu123/biliLive-tools/master/package.json");
56982
56947
  const data = await res.json();
@@ -57001,31 +56966,15 @@ router$d.get("/checkUpdate", async (ctx) => {
57001
56966
  };
57002
56967
  }
57003
56968
  });
57004
- /**
57005
- * @api {get} /common/tempPath 获取缓存文件夹路径
57006
- * @apiDescription 获取当前配置的缓存文件夹路径
57007
- * @apiSuccess {string} path 缓存文件夹路径
57008
- */
57009
- router$d.get("/tempPath", async (ctx) => {
57010
- try {
57011
- const tempPath = index.getTempPath();
57012
- ctx.body = tempPath;
57013
- }
57014
- catch (error) {
57015
- console.error("获取缓存路径失败:", error);
57016
- ctx.status = 500;
57017
- ctx.body = "获取缓存路径失败";
57018
- }
57019
- });
57020
56969
  /**
57021
56970
  * @api {get} /common/diskSpace 获取磁盘空间信息
57022
- * @apiDescription 获取录播姬文件夹所在磁盘的空间信息
56971
+ * @apiDescription 获取录制文件夹所在磁盘的空间信息
57023
56972
  * @apiSuccess {number} total 总空间(GB)
57024
56973
  * @apiSuccess {number} free 可用空间(GB)
57025
56974
  * @apiSuccess {number} used 已用空间(GB)
57026
56975
  * @apiSuccess {number} usedPercentage 使用百分比
57027
56976
  */
57028
- router$d.get("/diskSpace", async (ctx) => {
56977
+ router$e.get("/diskSpace", async (ctx) => {
57029
56978
  try {
57030
56979
  const config = exports.appConfig.getAll();
57031
56980
  const recoderFolder = config?.recorder?.savePath;
@@ -57059,10 +57008,10 @@ router$d.get("/diskSpace", async (ctx) => {
57059
57008
  }
57060
57009
  });
57061
57010
 
57062
- const router$c = new Router$1({
57011
+ const router$d = new Router$1({
57063
57012
  prefix: "/user",
57064
57013
  });
57065
- router$c.get("/list", async (ctx) => {
57014
+ router$d.get("/list", async (ctx) => {
57066
57015
  const list = index.biliApi.readUserList();
57067
57016
  ctx.body = list.map((item) => {
57068
57017
  return {
@@ -57073,22 +57022,22 @@ router$c.get("/list", async (ctx) => {
57073
57022
  };
57074
57023
  });
57075
57024
  });
57076
- router$c.post("/delete", async (ctx) => {
57025
+ router$d.post("/delete", async (ctx) => {
57077
57026
  const { uid } = ctx.request.body;
57078
57027
  await index.biliApi.deleteUser(uid);
57079
57028
  ctx.status = 200;
57080
57029
  });
57081
- router$c.post("/update", async (ctx) => {
57030
+ router$d.post("/update", async (ctx) => {
57082
57031
  const { uid } = ctx.request.body;
57083
57032
  await index.biliApi.updateUserInfo(uid);
57084
57033
  ctx.status = 200;
57085
57034
  });
57086
- router$c.post("/update_auth", async (ctx) => {
57035
+ router$d.post("/update_auth", async (ctx) => {
57087
57036
  const { uid } = ctx.request.body;
57088
57037
  await index.biliApi.updateAuth(uid);
57089
57038
  ctx.status = 200;
57090
57039
  });
57091
- router$c.post("/get_cookie", async (ctx) => {
57040
+ router$d.post("/get_cookie", async (ctx) => {
57092
57041
  const { uid, timestamp, signature } = ctx.request.body;
57093
57042
  const currentTimestamp = Math.floor(Date.now() / 1000);
57094
57043
  if (Math.abs(currentTimestamp - timestamp) > 10) {
@@ -57119,11 +57068,11 @@ router$c.post("/get_cookie", async (ctx) => {
57119
57068
  ctx.body = "获取失败,请重试";
57120
57069
  }
57121
57070
  });
57122
- router$c.get("/export", async (ctx) => {
57071
+ router$d.get("/export", async (ctx) => {
57123
57072
  const list = index.biliApi.readUserList();
57124
57073
  ctx.body = list;
57125
57074
  });
57126
- router$c.post("/export_single", async (ctx) => {
57075
+ router$d.post("/export_single", async (ctx) => {
57127
57076
  const { uid } = ctx.request.body;
57128
57077
  const user = index.biliApi.readUser(uid);
57129
57078
  if (!user) {
@@ -57133,7 +57082,7 @@ router$c.post("/export_single", async (ctx) => {
57133
57082
  }
57134
57083
  ctx.body = user;
57135
57084
  });
57136
- router$c.post("/import", async (ctx) => {
57085
+ router$d.post("/import", async (ctx) => {
57137
57086
  const { users } = ctx.request.body;
57138
57087
  if (!Array.isArray(users)) {
57139
57088
  ctx.status = 400;
@@ -57150,7 +57099,7 @@ router$c.post("/import", async (ctx) => {
57150
57099
  }
57151
57100
  ctx.status = 200;
57152
57101
  });
57153
- router$c.post("/import_single", async (ctx) => {
57102
+ router$d.post("/import_single", async (ctx) => {
57154
57103
  const { user } = ctx.request.body;
57155
57104
  if (!user?.mid || !user?.accessToken || !user?.refreshToken || !user?.cookie) {
57156
57105
  ctx.status = 400;
@@ -57161,103 +57110,103 @@ router$c.post("/import_single", async (ctx) => {
57161
57110
  ctx.status = 200;
57162
57111
  });
57163
57112
 
57164
- const router$b = new Router$1({
57113
+ const router$c = new Router$1({
57165
57114
  prefix: "/preset",
57166
57115
  });
57167
57116
  ////////////////// 弹幕预设 ///////////////////////////////
57168
- router$b.get("/danmu", async (ctx) => {
57117
+ router$c.get("/danmu", async (ctx) => {
57169
57118
  const danmuPreset = exports.container.resolve("danmuPreset");
57170
57119
  ctx.body = await danmuPreset.list();
57171
57120
  });
57172
- router$b.get("/danmu/:id", async (ctx) => {
57121
+ router$c.get("/danmu/:id", async (ctx) => {
57173
57122
  const danmuPreset = exports.container.resolve("danmuPreset");
57174
57123
  ctx.body = await danmuPreset.get(ctx.params.id);
57175
57124
  });
57176
- router$b.post("/danmu", async (ctx) => {
57125
+ router$c.post("/danmu", async (ctx) => {
57177
57126
  const danmuPreset = exports.container.resolve("danmuPreset");
57178
57127
  const data = ctx.request.body;
57179
57128
  ctx.body = await danmuPreset.save(data);
57180
57129
  });
57181
- router$b.del("/danmu/:id", async (ctx) => {
57130
+ router$c.del("/danmu/:id", async (ctx) => {
57182
57131
  const danmuPreset = exports.container.resolve("danmuPreset");
57183
57132
  ctx.body = await danmuPreset.delete(ctx.params.id);
57184
57133
  });
57185
- router$b.put("/danmu/:id", async (ctx) => {
57134
+ router$c.put("/danmu/:id", async (ctx) => {
57186
57135
  const danmuPreset = exports.container.resolve("danmuPreset");
57187
57136
  const data = ctx.request.body;
57188
57137
  ctx.body = await danmuPreset.save({ ...data, id: ctx.params.id });
57189
57138
  });
57190
57139
  ////////////////// 视频上传预设 ///////////////////////////////
57191
- router$b.get("/video", async (ctx) => {
57140
+ router$c.get("/video", async (ctx) => {
57192
57141
  const preset = exports.container.resolve("videoPreset");
57193
57142
  ctx.body = await preset.list();
57194
57143
  });
57195
- router$b.get("/video/:id", async (ctx) => {
57144
+ router$c.get("/video/:id", async (ctx) => {
57196
57145
  const preset = exports.container.resolve("videoPreset");
57197
57146
  ctx.body = await preset.get(ctx.params.id);
57198
57147
  });
57199
- router$b.post("/video", async (ctx) => {
57148
+ router$c.post("/video", async (ctx) => {
57200
57149
  const preset = exports.container.resolve("videoPreset");
57201
57150
  const data = ctx.request.body;
57202
57151
  data.config = index.omit(data.config, ["dtime"]);
57203
57152
  ctx.body = await preset.save(data);
57204
57153
  });
57205
- router$b.del("/video/:id", async (ctx) => {
57154
+ router$c.del("/video/:id", async (ctx) => {
57206
57155
  const preset = exports.container.resolve("videoPreset");
57207
57156
  ctx.body = await preset.delete(ctx.params.id);
57208
57157
  });
57209
- router$b.put("/video/:id", async (ctx) => {
57158
+ router$c.put("/video/:id", async (ctx) => {
57210
57159
  const preset = exports.container.resolve("videoPreset");
57211
57160
  const data = ctx.request.body;
57212
57161
  data.config = index.omit(data.config, ["dtime"]);
57213
57162
  ctx.body = await preset.save({ ...data, id: ctx.params.id });
57214
57163
  });
57215
57164
  ////////////////// ffmpeg预设 ///////////////////////////////
57216
- router$b.get("/ffmpeg", async (ctx) => {
57165
+ router$c.get("/ffmpeg", async (ctx) => {
57217
57166
  const preset = exports.container.resolve("ffmpegPreset");
57218
57167
  ctx.body = await preset.list();
57219
57168
  });
57220
- router$b.get("/ffmpeg/options", async (ctx) => {
57169
+ router$c.get("/ffmpeg/options", async (ctx) => {
57221
57170
  const preset = exports.container.resolve("ffmpegPreset");
57222
57171
  ctx.body = await preset.getFfmpegPresetOptions();
57223
57172
  });
57224
- router$b.get("/ffmpeg/:id", async (ctx) => {
57173
+ router$c.get("/ffmpeg/:id", async (ctx) => {
57225
57174
  const preset = exports.container.resolve("ffmpegPreset");
57226
57175
  ctx.body = await preset.get(ctx.params.id);
57227
57176
  });
57228
- router$b.post("/ffmpeg", async (ctx) => {
57177
+ router$c.post("/ffmpeg", async (ctx) => {
57229
57178
  const preset = exports.container.resolve("ffmpegPreset");
57230
57179
  const data = ctx.request.body;
57231
57180
  ctx.body = await preset.save(data);
57232
57181
  });
57233
- router$b.del("/ffmpeg/:id", async (ctx) => {
57182
+ router$c.del("/ffmpeg/:id", async (ctx) => {
57234
57183
  const preset = exports.container.resolve("ffmpegPreset");
57235
57184
  ctx.body = await preset.delete(ctx.params.id);
57236
57185
  });
57237
- router$b.put("/ffmpeg/:id", async (ctx) => {
57186
+ router$c.put("/ffmpeg/:id", async (ctx) => {
57238
57187
  const preset = exports.container.resolve("ffmpegPreset");
57239
57188
  const data = ctx.request.body;
57240
57189
  ctx.body = await preset.save({ ...data, id: ctx.params.id });
57241
57190
  });
57242
57191
  ////////////////// 字幕样式预设 ///////////////////////////////
57243
- router$b.get("/subtitle-style", async (ctx) => {
57192
+ router$c.get("/subtitle-style", async (ctx) => {
57244
57193
  const preset = exports.container.resolve("subtitleStylePreset");
57245
57194
  ctx.body = await preset.list();
57246
57195
  });
57247
- router$b.get("/subtitle-style/:id", async (ctx) => {
57196
+ router$c.get("/subtitle-style/:id", async (ctx) => {
57248
57197
  const preset = exports.container.resolve("subtitleStylePreset");
57249
57198
  ctx.body = await preset.get(ctx.params.id);
57250
57199
  });
57251
- router$b.post("/subtitle-style", async (ctx) => {
57200
+ router$c.post("/subtitle-style", async (ctx) => {
57252
57201
  const preset = exports.container.resolve("subtitleStylePreset");
57253
57202
  const data = ctx.request.body;
57254
57203
  ctx.body = await preset.save(data);
57255
57204
  });
57256
- router$b.del("/subtitle-style/:id", async (ctx) => {
57205
+ router$c.del("/subtitle-style/:id", async (ctx) => {
57257
57206
  const preset = exports.container.resolve("subtitleStylePreset");
57258
57207
  ctx.body = await preset.delete(ctx.params.id);
57259
57208
  });
57260
- router$b.put("/subtitle-style/:id", async (ctx) => {
57209
+ router$c.put("/subtitle-style/:id", async (ctx) => {
57261
57210
  const preset = exports.container.resolve("subtitleStylePreset");
57262
57211
  const data = ctx.request.body;
57263
57212
  ctx.body = await preset.save({ ...data, id: ctx.params.id });
@@ -61698,7 +61647,7 @@ var picomatch$1 = picomatch_1;
61698
61647
  * Released under the MIT License.
61699
61648
  */
61700
61649
 
61701
- var normalizePath$2 = function(path, stripTrailing) {
61650
+ var normalizePath$3 = function(path, stripTrailing) {
61702
61651
  if (typeof path !== 'string') {
61703
61652
  throw new TypeError('expected path to be a string');
61704
61653
  }
@@ -61732,7 +61681,7 @@ var anymatch_1 = anymatch$2.exports;
61732
61681
  Object.defineProperty(anymatch_1, "__esModule", { value: true });
61733
61682
 
61734
61683
  const picomatch = picomatch$1;
61735
- const normalizePath$1 = normalizePath$2;
61684
+ const normalizePath$2 = normalizePath$3;
61736
61685
 
61737
61686
  /**
61738
61687
  * @typedef {(testString: string) => boolean} AnymatchFn
@@ -61776,7 +61725,7 @@ const matchPatterns = (patterns, negPatterns, args, returnIndex) => {
61776
61725
  throw new TypeError('anymatch: second argument must be a string: got ' +
61777
61726
  Object.prototype.toString.call(_path))
61778
61727
  }
61779
- const path = normalizePath$1(_path, false);
61728
+ const path = normalizePath$2(_path, false);
61780
61729
 
61781
61730
  for (let index = 0; index < negPatterns.length; index++) {
61782
61731
  const nglob = negPatterns[index];
@@ -63364,7 +63313,7 @@ const anymatch = anymatchExports.default;
63364
63313
  const globParent = index.globParent;
63365
63314
  const isGlob = index.isGlob;
63366
63315
  const braces = index.braces_1;
63367
- const normalizePath = normalizePath$2;
63316
+ const normalizePath$1 = normalizePath$3;
63368
63317
 
63369
63318
  const NodeFsHandler = nodefsHandler;
63370
63319
  const FsEventsHandler = fseventsHandlerExports;
@@ -63772,7 +63721,7 @@ add(paths_, _origAdd, _internal) {
63772
63721
  if (disableGlobbing || !isGlob(path)) {
63773
63722
  return absPath;
63774
63723
  }
63775
- return normalizePath(absPath);
63724
+ return normalizePath$1(absPath);
63776
63725
  });
63777
63726
  }
63778
63727
 
@@ -65090,19 +65039,23 @@ class BCutASRAdapter {
65090
65039
  async recognize() {
65091
65040
  throw new Error("B接口 ASR 不支持识别 URL,请使用 recognizeLocalFile");
65092
65041
  }
65093
- async recognizeLocalFile(filePath) {
65042
+ async recognizeLocalFile(filePath, opts) {
65094
65043
  // 这里直接返回一个模拟结果,实际使用时需要替换为调用 B接口 ASR 的代码
65095
65044
  const asr = new index.BcutASR(filePath);
65096
65045
  const result = await asr.recognize();
65097
65046
  const data = result.getRawData();
65098
- return this.transformBCutResult(data);
65047
+ return this.transformBCutResult(data, opts);
65099
65048
  }
65100
65049
  /**
65101
65050
  * 转换 B接口 ASR 格式为标准格式
65102
65051
  */
65103
- transformBCutResult(data) {
65104
- // 这里需要根据 B接口 ASR 的实际返回格式进行转换,以下是一个示例结构
65105
- const segments = data.utterances.map((utterance, index) => ({
65052
+ transformBCutResult(data, opts) {
65053
+ let list = data.utterances;
65054
+ if (opts?.filterMusic) {
65055
+ // @ts-expect-error
65056
+ list = list.filter((s) => s.music <= 0.9); // 过滤掉标记为音乐的段落
65057
+ }
65058
+ let segments = list.map((utterance, index) => ({
65106
65059
  id: index,
65107
65060
  start: utterance.start_time / 1000,
65108
65061
  end: utterance.end_time / 1000,
@@ -65260,9 +65213,9 @@ function createASRProvider(modelId) {
65260
65213
  * @param modelId 模型id
65261
65214
  * @returns
65262
65215
  */
65263
- function recognize$1(file, modelId) {
65216
+ function recognize$1(file, modelId, opts) {
65264
65217
  const asrProvider = createASRProvider(modelId);
65265
- return asrProvider.recognizeLocalFile(file);
65218
+ return asrProvider.recognizeLocalFile(file, opts);
65266
65219
  }
65267
65220
 
65268
65221
  const default_format = 'RFC3986';
@@ -76657,13 +76610,13 @@ async function songRecognize(file, audioStartTime = 0) {
76657
76610
  };
76658
76611
  }
76659
76612
 
76660
- const router$a = new Router$1({
76613
+ const router$b = new Router$1({
76661
76614
  prefix: "/sse",
76662
76615
  });
76663
76616
  /**
76664
76617
  * 流式查询日志
76665
76618
  */
76666
- router$a.get("/streamLogs", sse({
76619
+ router$b.get("/streamLogs", sse({
76667
76620
  maxClients: 5000,
76668
76621
  pingInterval: 60 * 60 * 1000,
76669
76622
  }), async (ctx) => {
@@ -76702,7 +76655,7 @@ router$a.get("/streamLogs", sse({
76702
76655
  /**
76703
76656
  * 获取弹幕流
76704
76657
  */
76705
- router$a.get("/recorder/danma", sse({
76658
+ router$b.get("/recorder/danma", sse({
76706
76659
  maxClients: 5000,
76707
76660
  pingInterval: 30000,
76708
76661
  }), async (ctx) => {
@@ -76715,7 +76668,7 @@ router$a.get("/recorder/danma", sse({
76715
76668
  }
76716
76669
  });
76717
76670
  });
76718
- router$a.get("/task/runningNum", sse({
76671
+ router$b.get("/task/runningNum", sse({
76719
76672
  maxClients: 5000,
76720
76673
  pingInterval: 30000,
76721
76674
  }), async (ctx) => {
@@ -76748,7 +76701,7 @@ router$a.get("/task/runningNum", sse({
76748
76701
  /**
76749
76702
  * 波形分析进度流
76750
76703
  */
76751
- router$a.get("/analyzerWaveform", sse({
76704
+ router$b.get("/analyzerWaveform", sse({
76752
76705
  maxClients: 100,
76753
76706
  pingInterval: 30000,
76754
76707
  }), async (ctx) => {
@@ -76807,7 +76760,7 @@ router$a.get("/analyzerWaveform", sse({
76807
76760
  });
76808
76761
  });
76809
76762
 
76810
- const router$9 = new Router$1({
76763
+ const router$a = new Router$1({
76811
76764
  prefix: "/recorder",
76812
76765
  });
76813
76766
  /**
@@ -76823,12 +76776,12 @@ const router$9 = new Router$1({
76823
76776
  * @param sortDirection 排序方向 asc: 升序 desc: 降序
76824
76777
  * @returns 录制任务列表
76825
76778
  */
76826
- router$9.get("/list", async (ctx) => {
76779
+ router$a.get("/list", async (ctx) => {
76827
76780
  const query = ctx.request.query;
76828
76781
  ctx.body = { payload: await recorderService.getRecorders(query) };
76829
76782
  });
76830
- router$9.post("/add", async (ctx) => {
76831
- const args = index.pick((ctx.request.body ?? {}), "providerId", "channelId", "remarks", "disableAutoCheck", "quality", "streamPriorities", "sourcePriorities", "extra", "noGlobalFollowFields", "line", "disableProvideCommentsWhenRecording", "saveGiftDanma", "saveSCDanma", "segment", "sendToWebhook", "uid", "saveCover", "qualityRetry", "formatName", "useM3U8Proxy", "customHost", "codecName", "titleKeywords", "liveStartNotification", "liveEndNotification", "weight", "source", "videoFormat", "recorderType", "cookie", "doubleScreen", "onlyAudio", "useServerTimestamp", "handleTime", "debugLevel", "api");
76783
+ router$a.post("/add", async (ctx) => {
76784
+ const args = index.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", "liveStartNotification", "liveEndNotification", "weight", "source", "videoFormat", "recorderType", "cookie", "doubleScreen", "onlyAudio", "useServerTimestamp", "handleTime", "debugLevel", "api");
76832
76785
  const data = await recorderService.addRecorder(args);
76833
76786
  ctx.body = { payload: data };
76834
76787
  });
@@ -76838,13 +76791,13 @@ router$9.post("/add", async (ctx) => {
76838
76791
  * @param recorderId 直播间ID
76839
76792
  * @returns 录制器配置信息
76840
76793
  */
76841
- router$9.get("/:id", (ctx) => {
76794
+ router$a.get("/:id", (ctx) => {
76842
76795
  const { id } = ctx.params;
76843
76796
  ctx.body = { payload: recorderService.getRecorder({ id }) };
76844
76797
  });
76845
- router$9.put("/:id", (ctx) => {
76798
+ router$a.put("/:id", (ctx) => {
76846
76799
  const { id } = ctx.params;
76847
- const patch = index.pick(ctx.request.body, "remarks", "disableAutoCheck", "quality", "streamPriorities", "sourcePriorities", "noGlobalFollowFields", "line", "disableProvideCommentsWhenRecording", "saveGiftDanma", "saveSCDanma", "saveCover", "segment", "sendToWebhook", "uid", "qualityRetry", "formatName", "useM3U8Proxy", "customHost", "codecName", "titleKeywords", "liveStartNotification", "liveEndNotification", "weight", "source", "videoFormat", "recorderType", "cookie", "doubleScreen", "onlyAudio", "useServerTimestamp", "handleTime", "debugLevel", "api");
76800
+ const patch = index.pick(ctx.request.body, "remarks", "disableAutoCheck", "quality", "streamPriorities", "sourcePriorities", "noGlobalFollowFields", "line", "disableProvideCommentsWhenRecording", "saveGiftDanma", "saveSCDanma", "saveCover", "segment", "sendToWebhook", "uid", "qualityRetry", "formatName", "useM3U8Proxy", "customHost", "codecName", "titleKeywords", "liveStartNotification", "liveEndNotification", "weight", "source", "videoFormat", "recorderType", "cookie", "doubleScreen", "onlyAudio", "useServerTimestamp", "handleTime", "debugLevel", "convert2Mp4", "api");
76848
76801
  ctx.body = { payload: recorderService.updateRecorder({ id, ...patch }) };
76849
76802
  });
76850
76803
  /**
@@ -76854,7 +76807,7 @@ router$9.put("/:id", (ctx) => {
76854
76807
  * @param removeHistory 是否删除录制历史,默认false
76855
76808
  * @returns null
76856
76809
  */
76857
- router$9.delete("/:id", (ctx) => {
76810
+ router$a.delete("/:id", (ctx) => {
76858
76811
  const { id } = ctx.params;
76859
76812
  const { removeHistory } = ctx.request.query;
76860
76813
  ctx.body = {
@@ -76867,7 +76820,7 @@ router$9.delete("/:id", (ctx) => {
76867
76820
  * @param recorderId 直播间ID
76868
76821
  * @returns 录制任务信息
76869
76822
  */
76870
- router$9.post("/:id/start_record", async (ctx) => {
76823
+ router$a.post("/:id/start_record", async (ctx) => {
76871
76824
  const { id } = ctx.params;
76872
76825
  ctx.body = { payload: await recorderService.startRecord({ id }) };
76873
76826
  });
@@ -76877,7 +76830,7 @@ router$9.post("/:id/start_record", async (ctx) => {
76877
76830
  * @param recorderId 直播间ID
76878
76831
  * @returns 录制任务信息
76879
76832
  */
76880
- router$9.post("/:id/stop_record", async (ctx) => {
76833
+ router$a.post("/:id/stop_record", async (ctx) => {
76881
76834
  const { id } = ctx.params;
76882
76835
  ctx.body = { payload: await recorderService.stopRecord({ id }) };
76883
76836
  });
@@ -76887,7 +76840,7 @@ router$9.post("/:id/stop_record", async (ctx) => {
76887
76840
  * @param recorderId 直播间ID
76888
76841
  * @returns 录制任务信息
76889
76842
  */
76890
- router$9.post("/:id/cut", async (ctx) => {
76843
+ router$a.post("/:id/cut", async (ctx) => {
76891
76844
  const { id } = ctx.params;
76892
76845
  ctx.body = { payload: await recorderService.cutRecord({ id }) };
76893
76846
  });
@@ -76897,7 +76850,7 @@ router$9.post("/:id/cut", async (ctx) => {
76897
76850
  * @param ids 直播间ID列表
76898
76851
  * @returns 批量操作结果
76899
76852
  */
76900
- router$9.post("/manager/batch_start_record", async (ctx) => {
76853
+ router$a.post("/manager/batch_start_record", async (ctx) => {
76901
76854
  const { ids } = ctx.request.body;
76902
76855
  ctx.body = { payload: await recorderService.batchStartRecord(ids) };
76903
76856
  });
@@ -76907,7 +76860,7 @@ router$9.post("/manager/batch_start_record", async (ctx) => {
76907
76860
  * @param ids 直播间ID列表
76908
76861
  * @returns 批量操作结果
76909
76862
  */
76910
- router$9.post("/manager/batch_stop_record", async (ctx) => {
76863
+ router$a.post("/manager/batch_stop_record", async (ctx) => {
76911
76864
  const { ids } = ctx.request.body;
76912
76865
  ctx.body = { payload: await recorderService.batchStopRecord(ids) };
76913
76866
  });
@@ -76917,7 +76870,7 @@ router$9.post("/manager/batch_stop_record", async (ctx) => {
76917
76870
  * @param url 直播间地址
76918
76871
  * @returns 直播间信息
76919
76872
  */
76920
- router$9.get("/manager/resolveChannel", async (ctx) => {
76873
+ router$a.get("/manager/resolveChannel", async (ctx) => {
76921
76874
  const { url } = ctx.query;
76922
76875
  const data = await recorderService.resolveChannel(url);
76923
76876
  ctx.body = { payload: data };
@@ -76928,7 +76881,7 @@ router$9.get("/manager/resolveChannel", async (ctx) => {
76928
76881
  * @param url 直播间地址
76929
76882
  * @returns 直播间信息
76930
76883
  */
76931
- router$9.get("/manager/resolve", async (ctx) => {
76884
+ router$a.get("/manager/resolve", async (ctx) => {
76932
76885
  const { url } = ctx.query;
76933
76886
  const data = await recorderService.resolve(url);
76934
76887
  ctx.body = { payload: data };
@@ -76939,7 +76892,7 @@ router$9.get("/manager/resolve", async (ctx) => {
76939
76892
  * @param channelURLs 直播间地址数组
76940
76893
  * @returns 批量解析结果
76941
76894
  */
76942
- router$9.post("/manager/batchResolveChannel", async (ctx) => {
76895
+ router$a.post("/manager/batchResolveChannel", async (ctx) => {
76943
76896
  const { channelURLs } = ctx.request.body;
76944
76897
  const data = await recorderService.batchResolveChannel(channelURLs);
76945
76898
  ctx.body = { payload: data };
@@ -76951,7 +76904,7 @@ router$9.post("/manager/batchResolveChannel", async (ctx) => {
76951
76904
  * @param forceRequest 强制查询直播间信息,不受配置限制,默认true
76952
76905
  * @returns 直播间实时信息列表
76953
76906
  */
76954
- router$9.post("/manager/liveInfo", async (ctx) => {
76907
+ router$a.post("/manager/liveInfo", async (ctx) => {
76955
76908
  const { ids } = ctx.request.body;
76956
76909
  const forceRequest = ctx.request.body.forceRequest ?? true;
76957
76910
  let requestInfoForRecord = true;
@@ -76967,11 +76920,11 @@ router$9.post("/manager/liveInfo", async (ctx) => {
76967
76920
  };
76968
76921
  });
76969
76922
 
76970
- const router$8 = new Router$1({
76923
+ const router$9 = new Router$1({
76971
76924
  prefix: "/bili",
76972
76925
  });
76973
76926
  // 验证视频上传参数
76974
- router$8.post("/validUploadParams", async (ctx) => {
76927
+ router$9.post("/validUploadParams", async (ctx) => {
76975
76928
  const params = ctx.request.body;
76976
76929
  // @ts-ignore
76977
76930
  const [status, msg] = await index.validateBiliupConfig(params);
@@ -76985,7 +76938,7 @@ router$8.post("/validUploadParams", async (ctx) => {
76985
76938
  /**
76986
76939
  * 投稿中心视频列表
76987
76940
  */
76988
- router$8.get("/archives", async (ctx) => {
76941
+ router$9.get("/archives", async (ctx) => {
76989
76942
  const params = ctx.request.query;
76990
76943
  const { uid } = params;
76991
76944
  const data = await index.biliApi.getArchives(params, uid);
@@ -76994,45 +76947,45 @@ router$8.get("/archives", async (ctx) => {
76994
76947
  /**
76995
76948
  * 用户视频详情
76996
76949
  */
76997
- router$8.get("/user/archive/:bvid", async (ctx) => {
76950
+ router$9.get("/user/archive/:bvid", async (ctx) => {
76998
76951
  const params = ctx.request.query;
76999
76952
  const { uid } = params;
77000
76953
  const { bvid } = ctx.params;
77001
76954
  const data = await index.biliApi.getArchiveDetail(bvid, uid);
77002
76955
  ctx.body = data;
77003
76956
  });
77004
- router$8.post("/checkTag", async (ctx) => {
76957
+ router$9.post("/checkTag", async (ctx) => {
77005
76958
  const { tag, uid, } = ctx.request.body;
77006
76959
  const data = await index.biliApi.checkTag(tag, uid);
77007
76960
  ctx.body = data;
77008
76961
  });
77009
- router$8.get("/searchTopic", async (ctx) => {
76962
+ router$9.get("/searchTopic", async (ctx) => {
77010
76963
  const { keyword, uid } = ctx.request.query;
77011
76964
  const data = await index.biliApi.searchTopic(keyword, uid);
77012
76965
  ctx.body = data;
77013
76966
  });
77014
- router$8.get("/seasons", async (ctx) => {
76967
+ router$9.get("/seasons", async (ctx) => {
77015
76968
  const { uid } = ctx.request.query;
77016
76969
  const data = await index.biliApi.getSeasonList(uid);
77017
76970
  ctx.body = data;
77018
76971
  });
77019
- router$8.get("/season/:aid", async (ctx) => {
76972
+ router$9.get("/season/:aid", async (ctx) => {
77020
76973
  const { uid } = ctx.request.query;
77021
76974
  const { aid } = ctx.params;
77022
76975
  const data = await index.biliApi.getSessionId(Number(aid), uid);
77023
76976
  ctx.body = data;
77024
76977
  });
77025
- router$8.get("/platformArchiveDetail", async (ctx) => {
76978
+ router$9.get("/platformArchiveDetail", async (ctx) => {
77026
76979
  const { aid, uid } = ctx.request.query;
77027
76980
  const data = await index.biliApi.getPlatformArchiveDetail(aid, uid);
77028
76981
  ctx.body = data;
77029
76982
  });
77030
- router$8.get("/platformPre", async (ctx) => {
76983
+ router$9.get("/platformPre", async (ctx) => {
77031
76984
  const { uid } = ctx.request.query;
77032
76985
  const data = await index.biliApi.getPlatformPre(uid);
77033
76986
  ctx.body = data;
77034
76987
  });
77035
- router$8.get("/typeDesc", async (ctx) => {
76988
+ router$9.get("/typeDesc", async (ctx) => {
77036
76989
  const { tid, uid } = ctx.request.query;
77037
76990
  const data = await index.biliApi.getTypeDesc(tid, uid);
77038
76991
  ctx.body = data;
@@ -77040,7 +76993,7 @@ router$8.get("/typeDesc", async (ctx) => {
77040
76993
  /**
77041
76994
  * 上传以及续传视频
77042
76995
  */
77043
- router$8.post("/upload", async (ctx) => {
76996
+ router$9.post("/upload", async (ctx) => {
77044
76997
  const data = ctx.request.body;
77045
76998
  if (!data.uid) {
77046
76999
  ctx.body = "uid required";
@@ -77080,7 +77033,7 @@ router$8.post("/upload", async (ctx) => {
77080
77033
  });
77081
77034
  // 登录相关
77082
77035
  const loginObj = {};
77083
- router$8.post("/login", async (ctx) => {
77036
+ router$9.post("/login", async (ctx) => {
77084
77037
  const tv = new index.TvQrcodeLogin();
77085
77038
  const id = index.uuid();
77086
77039
  loginObj[id] = {
@@ -77112,7 +77065,7 @@ router$8.post("/login", async (ctx) => {
77112
77065
  id,
77113
77066
  };
77114
77067
  });
77115
- router$8.post("/login/cancel", async (ctx) => {
77068
+ router$9.post("/login/cancel", async (ctx) => {
77116
77069
  const { id } = ctx.request.body;
77117
77070
  if (!id) {
77118
77071
  ctx.body = "id required";
@@ -77129,7 +77082,7 @@ router$8.post("/login/cancel", async (ctx) => {
77129
77082
  tv.interrupt();
77130
77083
  ctx.body = "success";
77131
77084
  });
77132
- router$8.get("/login/poll", async (ctx) => {
77085
+ router$9.get("/login/poll", async (ctx) => {
77133
77086
  const { id } = ctx.request.query;
77134
77087
  if (!id) {
77135
77088
  ctx.body = "id required";
@@ -77144,13 +77097,13 @@ router$8.get("/login/poll", async (ctx) => {
77144
77097
  }
77145
77098
  ctx.body = index.omit(loginInfo, ["client"]);
77146
77099
  });
77147
- router$8.post("/formatTitle", async (ctx) => {
77100
+ router$9.post("/formatTitle", async (ctx) => {
77148
77101
  const data = ctx.request.body;
77149
77102
  const template = (data.template || "");
77150
77103
  const title = index.formatTitle(data.options, template);
77151
77104
  ctx.body = title;
77152
77105
  });
77153
- router$8.post("/formatPartTitle", async (ctx) => {
77106
+ router$9.post("/formatPartTitle", async (ctx) => {
77154
77107
  const data = ctx.request.body;
77155
77108
  const template = (data.template || "");
77156
77109
  const title = index.formatPartTitle(data.options ?? {
@@ -77163,7 +77116,7 @@ router$8.post("/formatPartTitle", async (ctx) => {
77163
77116
  }, template);
77164
77117
  ctx.body = title;
77165
77118
  });
77166
- router$8.post("/formatDesc", async (ctx) => {
77119
+ router$9.post("/formatDesc", async (ctx) => {
77167
77120
  const data = ctx.request.body;
77168
77121
  const template = (data.template || "");
77169
77122
  const desc = index.formatDesc(data.options ?? {
@@ -77434,10 +77387,10 @@ const generateWaveformData = async (videoFilePath) => {
77434
77387
  }
77435
77388
  };
77436
77389
 
77437
- const router$7 = new Router$1({
77390
+ const router$8 = new Router$1({
77438
77391
  prefix: "/task",
77439
77392
  });
77440
- router$7.get("/", async (ctx) => {
77393
+ router$8.get("/", async (ctx) => {
77441
77394
  const type = ctx.query.type;
77442
77395
  let data = index.handleListTask();
77443
77396
  if (type) {
@@ -77448,42 +77401,42 @@ router$7.get("/", async (ctx) => {
77448
77401
  runningTaskNum: data.filter((item) => item.status === "running").length,
77449
77402
  };
77450
77403
  });
77451
- router$7.get("/:id", async (ctx) => {
77404
+ router$8.get("/:id", async (ctx) => {
77452
77405
  const { id } = ctx.params;
77453
77406
  ctx.body = index.handleQueryTask(id);
77454
77407
  });
77455
- router$7.post("/:id/pause", async (ctx) => {
77408
+ router$8.post("/:id/pause", async (ctx) => {
77456
77409
  const { id } = ctx.params;
77457
77410
  console.log(id);
77458
77411
  index.handlePauseTask(id);
77459
77412
  ctx.body = { code: 0 };
77460
77413
  });
77461
- router$7.post("/:id/resume", async (ctx) => {
77414
+ router$8.post("/:id/resume", async (ctx) => {
77462
77415
  const { id } = ctx.params;
77463
77416
  index.handleResumeTask(id);
77464
77417
  ctx.body = { code: 0 };
77465
77418
  });
77466
- router$7.post("/:id/kill", async (ctx) => {
77419
+ router$8.post("/:id/kill", async (ctx) => {
77467
77420
  const { id } = ctx.params;
77468
77421
  index.handleKillTask(id);
77469
77422
  ctx.body = { code: 0 };
77470
77423
  });
77471
- router$7.post("/:id/interrupt", async (ctx) => {
77424
+ router$8.post("/:id/interrupt", async (ctx) => {
77472
77425
  const { id } = ctx.params;
77473
77426
  index.hanldeInterruptTask(id);
77474
77427
  ctx.body = { code: 0 };
77475
77428
  });
77476
- router$7.post("/:id/removeRecord", async (ctx) => {
77429
+ router$8.post("/:id/removeRecord", async (ctx) => {
77477
77430
  const { id } = ctx.params;
77478
77431
  index.handleRemoveTask(id);
77479
77432
  ctx.body = { code: 0 };
77480
77433
  });
77481
- router$7.post("/:id/restart", async (ctx) => {
77434
+ router$8.post("/:id/restart", async (ctx) => {
77482
77435
  const { id } = ctx.params;
77483
77436
  index.handleRestartTask(id);
77484
77437
  ctx.body = { code: 0 };
77485
77438
  });
77486
- router$7.post("/:id/removeFile", async (ctx) => {
77439
+ router$8.post("/:id/removeFile", async (ctx) => {
77487
77440
  const { id } = ctx.params;
77488
77441
  const task = index.taskQueue.queryTask(id);
77489
77442
  if (!task) {
@@ -77501,17 +77454,17 @@ router$7.post("/:id/removeFile", async (ctx) => {
77501
77454
  await index.trashItem(task.output);
77502
77455
  ctx.body = { code: 0 };
77503
77456
  });
77504
- router$7.post("/:id/start", async (ctx) => {
77457
+ router$8.post("/:id/start", async (ctx) => {
77505
77458
  const { id } = ctx.params;
77506
77459
  index.handleStartTask(id);
77507
77460
  ctx.body = { code: 0 };
77508
77461
  });
77509
- router$7.post("/removeBatch", async (ctx) => {
77462
+ router$8.post("/removeBatch", async (ctx) => {
77510
77463
  const { ids } = ctx.request.body;
77511
77464
  ids.forEach((id) => index.handleRemoveTask(id));
77512
77465
  ctx.body = { code: 0 };
77513
77466
  });
77514
- router$7.post("/videoMeta", async (ctx) => {
77467
+ router$8.post("/videoMeta", async (ctx) => {
77515
77468
  const { file } = ctx.request.body;
77516
77469
  console.log(ctx.params);
77517
77470
  if (!file) {
@@ -77522,7 +77475,7 @@ router$7.post("/videoMeta", async (ctx) => {
77522
77475
  const data = await index.readVideoMeta(file, {});
77523
77476
  ctx.body = data;
77524
77477
  });
77525
- router$7.post("/convertXml2Ass", async (ctx) => {
77478
+ router$8.post("/convertXml2Ass", async (ctx) => {
77526
77479
  const { input, output, preset, options } = ctx.request.body;
77527
77480
  if (!input || !output) {
77528
77481
  ctx.status = 400;
@@ -77556,12 +77509,12 @@ router$7.post("/convertXml2Ass", async (ctx) => {
77556
77509
  ctx.body = { taskId: task.taskId, output: task.output };
77557
77510
  }
77558
77511
  });
77559
- router$7.post("/checkMergeVideos", async (ctx) => {
77512
+ router$8.post("/checkMergeVideos", async (ctx) => {
77560
77513
  const { inputVideos } = ctx.request.body;
77561
77514
  const result = await index.checkMergeVideos(inputVideos);
77562
77515
  ctx.body = result;
77563
77516
  });
77564
- router$7.post("/mergeVideo", async (ctx) => {
77517
+ router$8.post("/mergeVideo", async (ctx) => {
77565
77518
  const { inputVideos, options } = ctx.request.body;
77566
77519
  if (!inputVideos || inputVideos.length < 2) {
77567
77520
  ctx.status = 400;
@@ -77579,7 +77532,7 @@ router$7.post("/mergeVideo", async (ctx) => {
77579
77532
  });
77580
77533
  ctx.body = { taskId: task.taskId };
77581
77534
  });
77582
- router$7.post("/transcode", async (ctx) => {
77535
+ router$8.post("/transcode", async (ctx) => {
77583
77536
  const { input, outputName, ffmpegOptions, options } = ctx.request.body;
77584
77537
  if (!input) {
77585
77538
  ctx.status = 400;
@@ -77597,7 +77550,7 @@ router$7.post("/transcode", async (ctx) => {
77597
77550
  /**
77598
77551
  * 烧录
77599
77552
  */
77600
- router$7.post("/burn", async (ctx) => {
77553
+ router$8.post("/burn", async (ctx) => {
77601
77554
  const { files, output, options } = ctx.request.body;
77602
77555
  if (options?.uploadOptions?.upload && !options?.uploadOptions?.aid) {
77603
77556
  const [status, msg] = index.validateBiliupConfig(options?.uploadOptions?.config || {});
@@ -77626,7 +77579,7 @@ router$7.post("/burn", async (ctx) => {
77626
77579
  /**
77627
77580
  * flv修复
77628
77581
  */
77629
- router$7.post("/flvRepair", async (ctx) => {
77582
+ router$8.post("/flvRepair", async (ctx) => {
77630
77583
  const { input, output, options } = ctx.request.body;
77631
77584
  const task = await flvRepair(input, output, options);
77632
77585
  ctx.body = { taskId: task.taskId };
@@ -77634,7 +77587,7 @@ router$7.post("/flvRepair", async (ctx) => {
77634
77587
  /**
77635
77588
  * 切片
77636
77589
  */
77637
- router$7.post("/cut", async (ctx) => {
77590
+ router$8.post("/cut", async (ctx) => {
77638
77591
  const { files, output, options, ffmpegOptions } = ctx.request.body;
77639
77592
  // 处理srt字幕切割
77640
77593
  const srtContent = files.srtContent;
@@ -77679,7 +77632,7 @@ router$7.post("/cut", async (ctx) => {
77679
77632
  * 字幕分割
77680
77633
  * 输入:srt字幕内容
77681
77634
  */
77682
- router$7.post("/cutSubtitle", async (ctx) => {
77635
+ router$8.post("/cutSubtitle", async (ctx) => {
77683
77636
  const data = ctx.request.body;
77684
77637
  const nodeList = parseSync(data.srtContent);
77685
77638
  // console.log("解析后的节点数量:", nodeList.length, nodeList);
@@ -77718,22 +77671,22 @@ router$7.post("/cutSubtitle", async (ctx) => {
77718
77671
  }
77719
77672
  ctx.body = "success";
77720
77673
  });
77721
- router$7.post("/addExtraVideoTask", async (ctx) => {
77674
+ router$8.post("/addExtraVideoTask", async (ctx) => {
77722
77675
  const { taskId, filePath, partName } = ctx.request.body;
77723
77676
  index.biliApi.addExtraVideoTask(taskId, filePath, partName);
77724
77677
  ctx.body = { code: 0 };
77725
77678
  });
77726
- router$7.post("/editVideoPartName", async (ctx) => {
77679
+ router$8.post("/editVideoPartName", async (ctx) => {
77727
77680
  const { taskId, partName } = ctx.request.body;
77728
77681
  index.biliApi.editVideoPartName(taskId, partName);
77729
77682
  ctx.body = { code: 0 };
77730
77683
  });
77731
- router$7.post("/queryVideoStatus", async (ctx) => {
77684
+ router$8.post("/queryVideoStatus", async (ctx) => {
77732
77685
  const { taskId } = ctx.request.body;
77733
77686
  const res = await index.biliApi.queryVideoStatus(taskId);
77734
77687
  ctx.body = res;
77735
77688
  });
77736
- router$7.get("/:id/download", async (ctx) => {
77689
+ router$8.get("/:id/download", async (ctx) => {
77737
77690
  const { id } = ctx.params;
77738
77691
  const task = index.taskQueue.queryTask(id);
77739
77692
  if (!task) {
@@ -77754,7 +77707,7 @@ router$7.get("/:id/download", async (ctx) => {
77754
77707
  const fileId = fileCache.setFile(task.output);
77755
77708
  ctx.body = fileId;
77756
77709
  });
77757
- router$7.post("/testVirtualRecord", async (ctx) => {
77710
+ router$8.post("/testVirtualRecord", async (ctx) => {
77758
77711
  const { config, folderPath, startTime } = ctx.request.body;
77759
77712
  if (!config) {
77760
77713
  ctx.status = 400;
@@ -77795,7 +77748,7 @@ router$7.post("/testVirtualRecord", async (ctx) => {
77795
77748
  ctx.body = error instanceof Error ? error.message : "Internal server error";
77796
77749
  }
77797
77750
  });
77798
- router$7.post("/executeVirtualRecord", async (ctx) => {
77751
+ router$8.post("/executeVirtualRecord", async (ctx) => {
77799
77752
  const { config, folderPath, startTime } = ctx.request.body;
77800
77753
  if (!config) {
77801
77754
  ctx.status = 400;
@@ -77839,7 +77792,7 @@ router$7.post("/executeVirtualRecord", async (ctx) => {
77839
77792
  /**
77840
77793
  * 生成waveform数据
77841
77794
  */
77842
- router$7.post("/extractPeaks", async (ctx) => {
77795
+ router$8.post("/extractPeaks", async (ctx) => {
77843
77796
  const { input } = ctx.request.body;
77844
77797
  if (!input) {
77845
77798
  ctx.status = 400;
@@ -77857,7 +77810,7 @@ router$7.post("/extractPeaks", async (ctx) => {
77857
77810
  /**
77858
77811
  * 分析波形数据,主要用于检测唱歌边界点
77859
77812
  */
77860
- router$7.post("/analyzerWaveform", async (ctx) => {
77813
+ router$8.post("/analyzerWaveform", async (ctx) => {
77861
77814
  const { input, config } = ctx.request.body;
77862
77815
  if (!input) {
77863
77816
  ctx.status = 400;
@@ -77868,10 +77821,10 @@ router$7.post("/analyzerWaveform", async (ctx) => {
77868
77821
  ctx.body = { output: data };
77869
77822
  });
77870
77823
 
77871
- const router$6 = new Router$1({
77824
+ const router$7 = new Router$1({
77872
77825
  prefix: "/assets",
77873
77826
  });
77874
- router$6.get("/cover/:filename", async (ctx) => {
77827
+ router$7.get("/cover/:filename", async (ctx) => {
77875
77828
  const { filename } = ctx.params;
77876
77829
  const coverPath = path$7.join(exports.config.userDataPath, "cover", filename);
77877
77830
  if (await index.fs.pathExists(coverPath)) {
@@ -77883,7 +77836,7 @@ router$6.get("/cover/:filename", async (ctx) => {
77883
77836
  ctx.body = "Cover not found";
77884
77837
  }
77885
77838
  });
77886
- router$6.get("/download/:id", async (ctx) => {
77839
+ router$7.get("/download/:id", async (ctx) => {
77887
77840
  const { id } = ctx.params;
77888
77841
  const file = fileCache.get(id);
77889
77842
  if (!file) {
@@ -78017,10 +77970,10 @@ var douyin = {
78017
77970
  download,
78018
77971
  };
78019
77972
 
78020
- const router$5 = new Router$1({
77973
+ const router$6 = new Router$1({
78021
77974
  prefix: "/video",
78022
77975
  });
78023
- router$5.post("/parse", async (ctx) => {
77976
+ router$6.post("/parse", async (ctx) => {
78024
77977
  let url = ctx.request.body.url;
78025
77978
  if (!url) {
78026
77979
  throw new Error("url is required");
@@ -78028,11 +77981,11 @@ router$5.post("/parse", async (ctx) => {
78028
77981
  url = url.trim();
78029
77982
  ctx.body = await parseVideo({ url });
78030
77983
  });
78031
- router$5.post("/download", async (ctx) => {
77984
+ router$6.post("/download", async (ctx) => {
78032
77985
  let options = ctx.request.body;
78033
77986
  ctx.body = await downloadVideo(options);
78034
77987
  });
78035
- router$5.post("/sub/parse", async (ctx) => {
77988
+ router$6.post("/sub/parse", async (ctx) => {
78036
77989
  let data = ctx.request.body;
78037
77990
  if (!data.url) {
78038
77991
  throw new Error("url is required");
@@ -78040,12 +77993,12 @@ router$5.post("/sub/parse", async (ctx) => {
78040
77993
  const res = await index.videoSub.parse(data.url);
78041
77994
  ctx.body = res;
78042
77995
  });
78043
- router$5.post("/sub/add", async (ctx) => {
77996
+ router$6.post("/sub/add", async (ctx) => {
78044
77997
  let data = ctx.request.body;
78045
77998
  const res = index.videoSub.add(data);
78046
77999
  ctx.body = res;
78047
78000
  });
78048
- router$5.post("/sub/remove", async (ctx) => {
78001
+ router$6.post("/sub/remove", async (ctx) => {
78049
78002
  let data = ctx.request.body;
78050
78003
  if (!data.id) {
78051
78004
  throw new Error("id is required");
@@ -78053,7 +78006,7 @@ router$5.post("/sub/remove", async (ctx) => {
78053
78006
  const res = index.videoSub.remove(data.id);
78054
78007
  ctx.body = res;
78055
78008
  });
78056
- router$5.post("/sub/update", async (ctx) => {
78009
+ router$6.post("/sub/update", async (ctx) => {
78057
78010
  let data = ctx.request.body;
78058
78011
  if (!data.id || !data.name || !data.platform || !data.subId) {
78059
78012
  throw new Error("id, name, platform, subId is required");
@@ -78061,11 +78014,11 @@ router$5.post("/sub/update", async (ctx) => {
78061
78014
  const res = index.videoSub.update(data);
78062
78015
  ctx.body = res;
78063
78016
  });
78064
- router$5.get("/sub/list", async (ctx) => {
78017
+ router$6.get("/sub/list", async (ctx) => {
78065
78018
  const res = index.videoSub.list();
78066
78019
  ctx.body = res;
78067
78020
  });
78068
- router$5.post("/sub/check", async (ctx) => {
78021
+ router$6.post("/sub/check", async (ctx) => {
78069
78022
  const data = ctx.request.body;
78070
78023
  const res = await index.videoSub.check(data.id);
78071
78024
  ctx.body = res;
@@ -78388,7 +78341,7 @@ function extractBVNumber(videoUrl) {
78388
78341
  }
78389
78342
  }
78390
78343
 
78391
- const router$4 = new Router$1({
78344
+ const router$5 = new Router$1({
78392
78345
  prefix: "/record-history",
78393
78346
  });
78394
78347
  /**
@@ -78402,7 +78355,7 @@ const router$4 = new Router$1({
78402
78355
  * @param {number} [endTime] - 结束时间(时间戳)
78403
78356
  * @returns
78404
78357
  */
78405
- router$4.get("/list", async (ctx) => {
78358
+ router$5.get("/list", async (ctx) => {
78406
78359
  const { room_id, platform, page, pageSize, startTime, endTime } = ctx.query;
78407
78360
  if (!room_id || !platform) {
78408
78361
  ctx.status = 400;
@@ -78448,7 +78401,7 @@ router$4.get("/list", async (ctx) => {
78448
78401
  * @route DELETE /record-history/:id
78449
78402
  * @param {number} id - 记录ID
78450
78403
  */
78451
- router$4.delete("/:id", async (ctx) => {
78404
+ router$5.delete("/:id", async (ctx) => {
78452
78405
  const { id } = ctx.params;
78453
78406
  if (!id || isNaN(parseInt(id))) {
78454
78407
  ctx.status = 400;
@@ -78521,12 +78474,24 @@ const getDanmaFile = async (videoFile) => {
78521
78474
  }
78522
78475
  return null;
78523
78476
  };
78477
+ const createDanmaFileResponse = async (videoFile) => {
78478
+ const danmaFile = await getDanmaFile(videoFile);
78479
+ let danmaFileId = null;
78480
+ if (danmaFile) {
78481
+ danmaFileId = fileCache.setFile(danmaFile.file);
78482
+ }
78483
+ return {
78484
+ danmaFilePath: danmaFile?.file || null,
78485
+ danmaFileId,
78486
+ danmaFileExt: danmaFile?.ext || null,
78487
+ };
78488
+ };
78524
78489
  /**
78525
- * 获取记录文件信息
78490
+ * 获取历史记录文件信息
78526
78491
  * @route GET /record-history/file/:id
78527
78492
  * @param {number} id - 记录ID
78528
78493
  */
78529
- router$4.get("/file/:id", async (ctx) => {
78494
+ router$5.get("/file/:id", async (ctx) => {
78530
78495
  const { id } = ctx.params;
78531
78496
  if (!id || isNaN(parseInt(id))) {
78532
78497
  ctx.status = 400;
@@ -78549,18 +78514,276 @@ router$4.get("/file/:id", async (ctx) => {
78549
78514
  videoFileExt = "ts";
78550
78515
  break;
78551
78516
  }
78552
- const danmaFile = await getDanmaFile(videoFile);
78553
- let danmaFileId = null;
78554
- if (danmaFile) {
78555
- danmaFileId = fileCache.setFile(danmaFile.file);
78556
- }
78517
+ const danmaInfo = await createDanmaFileResponse(videoFile);
78557
78518
  ctx.body = {
78558
78519
  videoFilePath: videoFile,
78559
78520
  videoFileId,
78560
78521
  videoFileExt,
78561
- danmaFilePath: danmaFile?.file || null,
78562
- danmaFileId,
78563
- danmaFileExt: danmaFile?.ext || null,
78522
+ ...danmaInfo,
78523
+ };
78524
+ });
78525
+ router$5.post("/danma-file", async (ctx) => {
78526
+ const { videoFilePath } = ctx.request.body;
78527
+ if (!videoFilePath) {
78528
+ ctx.status = 400;
78529
+ ctx.body = {
78530
+ code: 400,
78531
+ message: "videoFilePath不能为空",
78532
+ };
78533
+ return;
78534
+ }
78535
+ if (!(await index.fs.pathExists(videoFilePath))) {
78536
+ ctx.status = 404;
78537
+ ctx.body = {
78538
+ code: 404,
78539
+ message: "视频文件不存在",
78540
+ };
78541
+ return;
78542
+ }
78543
+ ctx.body = await createDanmaFileResponse(videoFilePath);
78544
+ });
78545
+
78546
+ const upload = multer({ dest: os$1.tmpdir() });
78547
+ const router$4 = new Router$1({
78548
+ prefix: "/files",
78549
+ });
78550
+ const DELETE_DIRS_ENV = "BILILIVE_TOOLS_DELETE_DIRS";
78551
+ const videoExts = new Set([".flv", ".mp4", ".ts", ".mkv", ".webm", ".m4v", ".m4s"]);
78552
+ const danmakuExts = new Set([".ass", ".xml", ".srt"]);
78553
+ function normalizePath(inputPath) {
78554
+ return path$7.resolve(inputPath);
78555
+ }
78556
+ function normalizeForCompare(inputPath) {
78557
+ const resolved = normalizePath(inputPath);
78558
+ return process.platform === "win32" ? resolved.toLowerCase() : resolved;
78559
+ }
78560
+ function isSubPath(targetPath, rootPath) {
78561
+ const normalizedTarget = normalizeForCompare(targetPath);
78562
+ const normalizedRoot = normalizeForCompare(rootPath);
78563
+ if (normalizedTarget === normalizedRoot) {
78564
+ return true;
78565
+ }
78566
+ const relative = path$7.relative(normalizedRoot, normalizedTarget);
78567
+ return relative !== "" && !relative.startsWith("..") && !path$7.isAbsolute(relative);
78568
+ }
78569
+ function getRootPath() {
78570
+ const webhookConfig = exports.appConfig.get("webhook");
78571
+ const recorderConfig = exports.appConfig.get("recorder");
78572
+ const rootPath = webhookConfig?.recoderFolder || recorderConfig?.savePath;
78573
+ if (!rootPath) {
78574
+ throw new Error("未配置录制目录");
78575
+ }
78576
+ return normalizePath(rootPath);
78577
+ }
78578
+ function getAllowedDeleteDirs() {
78579
+ const envValue = process.env[DELETE_DIRS_ENV] || "";
78580
+ return envValue
78581
+ .split(",")
78582
+ .map((item) => item.trim())
78583
+ .filter(Boolean)
78584
+ .map((item) => normalizePath(item));
78585
+ }
78586
+ function getFileKind(filePath) {
78587
+ const ext = path$7.extname(filePath).toLowerCase();
78588
+ if (videoExts.has(ext)) {
78589
+ return "video";
78590
+ }
78591
+ if (danmakuExts.has(ext)) {
78592
+ return "danmaku";
78593
+ }
78594
+ return null;
78595
+ }
78596
+ function canDeleteFile(filePath) {
78597
+ const fileKind = getFileKind(filePath);
78598
+ if (!fileKind) {
78599
+ return false;
78600
+ }
78601
+ const allowedDeleteDirs = getAllowedDeleteDirs();
78602
+ if (allowedDeleteDirs.length === 0) {
78603
+ return false;
78604
+ }
78605
+ return allowedDeleteDirs.some((dir) => isSubPath(filePath, dir));
78606
+ }
78607
+ async function ensureDirectory(dirPath) {
78608
+ if (!(await index.fs.pathExists(dirPath))) {
78609
+ throw new Error("录制目录不存在");
78610
+ }
78611
+ const stat = await index.fs.stat(dirPath);
78612
+ if (!stat.isDirectory()) {
78613
+ throw new Error("录制目录无效");
78614
+ }
78615
+ }
78616
+ async function resolveBrowsePath(inputPath) {
78617
+ const rootPath = getRootPath();
78618
+ await ensureDirectory(rootPath);
78619
+ const currentPath = inputPath ? normalizePath(inputPath) : rootPath;
78620
+ if (!isSubPath(currentPath, rootPath)) {
78621
+ throw new Error("访问路径超出录制目录范围");
78622
+ }
78623
+ const stat = await index.fs.stat(currentPath).catch(() => null);
78624
+ if (!stat || !stat.isDirectory()) {
78625
+ throw new Error("目录不存在");
78626
+ }
78627
+ return {
78628
+ rootPath,
78629
+ currentPath,
78630
+ };
78631
+ }
78632
+ router$4.get("/list", async (ctx) => {
78633
+ const inputPath = ctx.query.path;
78634
+ const { rootPath, currentPath } = await resolveBrowsePath(inputPath);
78635
+ const names = await index.fs.readdir(currentPath);
78636
+ const items = [];
78637
+ for (const name of names) {
78638
+ const filePath = path$7.join(currentPath, name);
78639
+ const stat = await index.fs.stat(filePath).catch(() => null);
78640
+ if (!stat) {
78641
+ continue;
78642
+ }
78643
+ if (stat.isDirectory()) {
78644
+ items.push({
78645
+ name,
78646
+ path: filePath,
78647
+ type: "directory",
78648
+ mtimeMs: stat.mtimeMs,
78649
+ canDelete: false,
78650
+ });
78651
+ continue;
78652
+ }
78653
+ const fileKind = getFileKind(filePath);
78654
+ if (!fileKind) {
78655
+ continue;
78656
+ }
78657
+ items.push({
78658
+ name,
78659
+ path: filePath,
78660
+ type: "file",
78661
+ size: stat.size,
78662
+ mtimeMs: stat.mtimeMs,
78663
+ canDelete: canDeleteFile(filePath),
78664
+ fileKind,
78665
+ });
78666
+ }
78667
+ items.sort((left, right) => {
78668
+ if (left.type !== right.type) {
78669
+ return left.type === "directory" ? -1 : 1;
78670
+ }
78671
+ return left.name.localeCompare(right.name, "zh-CN");
78672
+ });
78673
+ ctx.body = {
78674
+ rootPath,
78675
+ currentPath,
78676
+ parentPath: currentPath === rootPath ? null : path$7.dirname(currentPath),
78677
+ deleteEnabled: getAllowedDeleteDirs().length > 0,
78678
+ list: items,
78679
+ };
78680
+ });
78681
+ router$4.post("/download", async (ctx) => {
78682
+ const { path: filePath } = ctx.request.body;
78683
+ if (!filePath) {
78684
+ ctx.status = 400;
78685
+ ctx.body = { message: "文件路径不能为空" };
78686
+ return;
78687
+ }
78688
+ const { rootPath } = await resolveBrowsePath(path$7.dirname(filePath));
78689
+ const resolvedFilePath = normalizePath(filePath);
78690
+ if (!isSubPath(resolvedFilePath, rootPath)) {
78691
+ throw new Error("访问路径超出录制目录范围");
78692
+ }
78693
+ const stat = await index.fs.stat(resolvedFilePath).catch(() => null);
78694
+ if (!stat || !stat.isFile()) {
78695
+ throw new Error("文件不存在");
78696
+ }
78697
+ const fileKind = getFileKind(resolvedFilePath);
78698
+ if (!fileKind) {
78699
+ throw new Error("不支持下载该文件类型");
78700
+ }
78701
+ const fileId = fileCache.setFile(resolvedFilePath);
78702
+ ctx.body = {
78703
+ fileId,
78704
+ fileName: path$7.basename(resolvedFilePath),
78705
+ fileKind,
78706
+ };
78707
+ });
78708
+ router$4.post("/delete", async (ctx) => {
78709
+ const { path: filePath } = ctx.request.body;
78710
+ if (!filePath) {
78711
+ ctx.status = 400;
78712
+ ctx.body = { message: "文件路径不能为空" };
78713
+ return;
78714
+ }
78715
+ const resolvedFilePath = normalizePath(filePath);
78716
+ const { rootPath } = await resolveBrowsePath(path$7.dirname(resolvedFilePath));
78717
+ if (!isSubPath(resolvedFilePath, rootPath)) {
78718
+ throw new Error("访问路径超出录制目录范围");
78719
+ }
78720
+ const stat = await index.fs.stat(resolvedFilePath).catch(() => null);
78721
+ if (!stat || !stat.isFile()) {
78722
+ throw new Error("文件不存在");
78723
+ }
78724
+ const fileKind = getFileKind(resolvedFilePath);
78725
+ if (!fileKind) {
78726
+ throw new Error("仅支持删除视频和弹幕文件");
78727
+ }
78728
+ if (!canDeleteFile(resolvedFilePath)) {
78729
+ throw new Error(`当前未开启删除,或文件不在 ${DELETE_DIRS_ENV} 白名单目录中`);
78730
+ }
78731
+ await index.trashItem(resolvedFilePath);
78732
+ ctx.body = {
78733
+ message: "删除成功",
78734
+ path: resolvedFilePath,
78735
+ fileKind,
78736
+ };
78737
+ });
78738
+ router$4.post("/exists", async (ctx) => {
78739
+ const { filepath } = ctx.request.body;
78740
+ const exists = await index.fs.pathExists(filepath);
78741
+ ctx.body = exists;
78742
+ });
78743
+ router$4.post("/join", async (ctx) => {
78744
+ const { dir, name } = ctx.request.body;
78745
+ if (!index.fs.existsSync(dir)) {
78746
+ ctx.status = 400;
78747
+ ctx.body = "文件夹不存在";
78748
+ return;
78749
+ }
78750
+ const filePath = path$7.join(dir, name);
78751
+ ctx.body = filePath;
78752
+ });
78753
+ /**
78754
+ * @api {get} /files/temp 获取缓存文件夹路径
78755
+ * @apiDescription 获取当前配置的缓存文件夹路径
78756
+ * @apiSuccess {string} path 缓存文件夹路径
78757
+ */
78758
+ router$4.get("/temp", async (ctx) => {
78759
+ try {
78760
+ const tempPath = index.getTempPath();
78761
+ ctx.body = tempPath;
78762
+ }
78763
+ catch (error) {
78764
+ console.error("获取缓存路径失败:", error);
78765
+ ctx.status = 500;
78766
+ ctx.body = "获取缓存路径失败";
78767
+ }
78768
+ });
78769
+ router$4.post("/cover/upload", upload.single("file"), async (ctx) => {
78770
+ const file = ctx.request?.file?.path;
78771
+ if (!file) {
78772
+ ctx.status = 400;
78773
+ ctx.body = "No file selected";
78774
+ return;
78775
+ }
78776
+ const originalname = ctx.request?.file?.originalname;
78777
+ const ext = path$7.extname(originalname);
78778
+ const coverPath = path$7.join(exports.config.userDataPath, "cover");
78779
+ const outputName = `${index.uuid()}${ext}`;
78780
+ // 将图片复制到指定目录
78781
+ await index.fs.ensureDir(coverPath);
78782
+ await index.fs.copyFile(file, path$7.join(coverPath, outputName));
78783
+ await index.fs.remove(file).catch(() => { });
78784
+ ctx.body = {
78785
+ name: outputName,
78786
+ path: `/assets/cover/${outputName}`,
78564
78787
  };
78565
78788
  });
78566
78789
 
@@ -78579,8 +78802,7 @@ function int2HexColor(color) {
78579
78802
  }
78580
78803
  return `#${hex}`;
78581
78804
  }
78582
- router$3.post("/parseForArtPlayer", async (ctx) => {
78583
- const { filepath } = ctx.request.body;
78805
+ async function parseForArtPlayerData(filepath) {
78584
78806
  const data = await index.parseDanmu(filepath);
78585
78807
  const danmuList = [];
78586
78808
  for (const item of data.danmu) {
@@ -78614,7 +78836,42 @@ router$3.post("/parseForArtPlayer", async (ctx) => {
78614
78836
  style: {},
78615
78837
  });
78616
78838
  }
78617
- ctx.body = danmuList;
78839
+ return danmuList;
78840
+ }
78841
+ router$3.get("/content/:id", async (ctx) => {
78842
+ const { id } = ctx.params;
78843
+ const file = fileCache.get(id);
78844
+ if (!file) {
78845
+ ctx.status = 404;
78846
+ ctx.body = { message: "弹幕文件不存在" };
78847
+ return;
78848
+ }
78849
+ if (!(await index.fs.pathExists(file.path))) {
78850
+ ctx.status = 404;
78851
+ ctx.body = { message: "弹幕文件不存在" };
78852
+ return;
78853
+ }
78854
+ const ext = path$7.extname(file.path).toLowerCase();
78855
+ if (ext === ".ass") {
78856
+ ctx.body = {
78857
+ danmaType: "ass",
78858
+ content: await index.fs.readFile(file.path, "utf-8"),
78859
+ };
78860
+ return;
78861
+ }
78862
+ if (ext === ".xml") {
78863
+ ctx.body = {
78864
+ danmaType: "xml",
78865
+ content: await parseForArtPlayerData(file.path),
78866
+ };
78867
+ return;
78868
+ }
78869
+ ctx.status = 400;
78870
+ ctx.body = { message: "不支持的弹幕格式" };
78871
+ });
78872
+ router$3.post("/parseForArtPlayer", async (ctx) => {
78873
+ const { filepath } = ctx.request.body;
78874
+ ctx.body = await parseForArtPlayerData(filepath);
78618
78875
  });
78619
78876
 
78620
78877
  const getConfig = (type) => {
@@ -79044,20 +79301,23 @@ async function subtitleRecognize(file, modelId, options) {
79044
79301
  timeGapThreshold,
79045
79302
  fillGap,
79046
79303
  disableCache,
79304
+ song: options?.song,
79047
79305
  });
79048
79306
  try {
79049
79307
  // 生成缓存路径
79050
79308
  const cachePath = index.getTempPath();
79051
79309
  const fileHash = await index.calculateFileQuickHash(file);
79052
- // TODO:缓存有bug,第一个是多模型切换、第二个是不同参数热词参数不同
79310
+ // TODO:缓存有bug,第二个是不同参数热词参数不同
79053
79311
  const cacheFileName = `asr_subtitle_cache_${fileHash}_${modelId}.json`;
79054
79312
  const cacheFilePath = path$7.join(cachePath, cacheFileName);
79055
79313
  let asrResult = null;
79056
79314
  // 尝试从缓存读取
79057
79315
  if (!disableCache && (await index.fs.pathExists(cacheFilePath))) ;
79058
79316
  if (!asrResult) {
79059
- // 调用 ASR 识别(使用新的统一接口)
79060
- asrResult = await recognize$1(file, modelId);
79317
+ // 调用 ASR 识别
79318
+ asrResult = await recognize$1(file, modelId, {
79319
+ filterMusic: options?.song ? false : true, // 启用音乐过滤
79320
+ });
79061
79321
  // 保存到缓存(如果未禁用缓存)
79062
79322
  if (!disableCache) ;
79063
79323
  }
@@ -79186,6 +79446,7 @@ router$1.post("/subtitle", async (ctx) => {
79186
79446
  const srt = await subtitleRecognize(audioFile, asrModelId, {
79187
79447
  offset: data.offset,
79188
79448
  disableCache: true,
79449
+ song: data.song,
79189
79450
  });
79190
79451
  // 清理临时音频文件
79191
79452
  if (needCleanup) {
@@ -80318,11 +80579,12 @@ class WebhookHandler {
80318
80579
  index.logObj.info(`[EventBuffer] 处理匹配的事件对: ${pair.open.filePath}`);
80319
80580
  const config = this.configManager.getConfig(pair.open.roomId);
80320
80581
  if (!config.open) {
80321
- index.logObj.info(`${pair.open.roomId} is not open`);
80582
+ index.logObj.warn(`${pair.open.roomId} is not open`);
80322
80583
  return;
80323
80584
  }
80324
80585
  // 检查文件大小
80325
80586
  if (!(await this.validateFileSize(config, pair.close))) {
80587
+ index.logObj.warn("文件大小不符合要求,跳过处理", pair.close.filePath);
80326
80588
  return;
80327
80589
  }
80328
80590
  // 先处理 open 事件
@@ -80456,6 +80718,12 @@ class WebhookHandler {
80456
80718
  * 验证文件大小
80457
80719
  */
80458
80720
  async validateFileSize(config, options) {
80721
+ if (!config.minSize)
80722
+ return true;
80723
+ if (!(await index.fs.pathExists(options.filePath))) {
80724
+ index.logObj.warn(`文件不存在: ${options.filePath}`);
80725
+ return true;
80726
+ }
80459
80727
  const fileSize = await index.getFileSize(options.filePath);
80460
80728
  const fileSizeMB = fileSize / 1024 / 1024;
80461
80729
  if (fileSizeMB >= config.minSize) {
@@ -81465,7 +81733,7 @@ exports.handler = void 0;
81465
81733
  exports.appConfig = void 0;
81466
81734
  exports.container = void 0;
81467
81735
  const fileCache = createFileCache();
81468
- path$7.dirname(require$$1$2.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-DG03bxlI.cjs', document.baseURI).href))));
81736
+ path$7.dirname(require$$1$2.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-BxJPCbAG.cjs', document.baseURI).href))));
81469
81737
  const authMiddleware = (passKey) => {
81470
81738
  return async (ctx, next) => {
81471
81739
  const authHeader = ctx.headers["authorization"] || ctx.request.query.auth;
@@ -81502,8 +81770,8 @@ app.use(errorMiddleware);
81502
81770
  app.use(cors$1());
81503
81771
  app.use(bodyParserWrapper());
81504
81772
  app.use(router.routes());
81505
- app.use(router$g.routes());
81506
- app.use(router$6.routes());
81773
+ app.use(router$h.routes());
81774
+ app.use(router$7.routes());
81507
81775
  async function serverStart(options, axContainer) {
81508
81776
  exports.container = axContainer;
81509
81777
  exports.config = exports.container.resolve("globalConfig");
@@ -81514,20 +81782,21 @@ async function serverStart(options, axContainer) {
81514
81782
  const auth = authMiddleware(passKey);
81515
81783
  app.use(auth);
81516
81784
  }
81785
+ app.use(router$g.routes());
81517
81786
  app.use(router$f.routes());
81787
+ app.use(router$d.routes());
81518
81788
  app.use(router$e.routes());
81519
81789
  app.use(router$c.routes());
81520
- app.use(router$d.routes());
81521
- app.use(router$b.routes());
81790
+ app.use(router$a.routes());
81522
81791
  app.use(router$9.routes());
81523
81792
  app.use(router$8.routes());
81524
- app.use(router$7.routes());
81793
+ app.use(router$6.routes());
81525
81794
  app.use(router$5.routes());
81526
81795
  app.use(router$4.routes());
81527
81796
  app.use(router$3.routes());
81528
81797
  app.use(router$2.routes());
81529
81798
  app.use(router$1.routes());
81530
- app.use(router$a.routes());
81799
+ app.use(router$b.routes());
81531
81800
  app.use(router.allowedMethods());
81532
81801
  await createServer(options);
81533
81802
  return app;