karin-plugin-kkk 2.20.1 → 2.20.3
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/CHANGELOG.md +47 -0
- package/config/default_config/app.yaml +1 -7
- package/lib/apps/admin.js +3 -3
- package/lib/apps/help.js +3 -3
- package/lib/apps/push.js +3 -3
- package/lib/apps/qrlogin.js +3 -3
- package/lib/apps/tools.js +3 -3
- package/lib/apps/update.js +3 -3
- package/lib/build-metadata.json +5 -5
- package/lib/core_chunk/{main-C6bm6hYZ.js → main-CXz1QLHw.js} +478 -315
- package/lib/core_chunk/{template-CQ-u6h09.js → template-Bo8XmVaD.js} +370 -168
- package/lib/core_chunk/template.d.mts +8 -1
- package/lib/core_chunk/template.js +2 -2
- package/lib/core_chunk/{vendor-B3KhGHI_.js → vendor-DrIRnh5C.js} +191 -104
- package/lib/index.js +3 -3
- package/lib/karin-plugin-kkk.css +36 -0
- package/lib/root.js +1 -1
- package/lib/web.config.js +3 -3
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as __esmMin, o as __toESM, r as __export } from "./rolldown-runtime-BMXAG3ag.js";
|
|
2
|
-
import { E as zhCN, T as init_locale, _n as zod_default, a as init_lib, cn as require_protobufjs, dn as AxiosError$1, et as init_date_fns, fn as init_axios, gn as init_zod, hn as
|
|
3
|
-
import { n as init_client, r as reactServerRender } from "./template-
|
|
2
|
+
import { E as zhCN, T as init_locale, _n as zod_default, a as init_lib, cn as require_protobufjs, dn as AxiosError$1, et as init_date_fns, fn as init_axios, gn as init_zod, hn as init_dist, i as require_qr_code_styling, it as differenceInSeconds, ln as Chalk, mn as Xhshow, n as require_dist, nt as formatDistanceToNow, o as Window, on as require_jsQR, pn as axios_default, r as require_lib, rt as format, sn as require_express, t as require_heic_convert, tt as fromUnixTime, un as init_source } from "./vendor-DrIRnh5C.js";
|
|
3
|
+
import { n as init_client, r as reactServerRender } from "./template-Bo8XmVaD.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import karin$1, { BOT_CONNECT, app, authMiddleware, checkPkgUpdate, checkPort, common, components, config, copyConfigSync, createBadRequestResponse, createNotFoundResponse, createServerErrorResponse, createSuccessResponse, db, defineConfig, ffmpeg, ffprobe, filesByExt, getBot, hooks, karin, karinPathHtml, karinPathTemp, logger, logs, mkdirSync, range, render, requireFileSync, restart, segment, updatePkg, watch } from "node-karin";
|
|
6
6
|
import fs from "node:fs";
|
|
@@ -15,8 +15,8 @@ import YAML from "node-karin/yaml";
|
|
|
15
15
|
import util from "node:util";
|
|
16
16
|
import { Transformer } from "@napi-rs/image";
|
|
17
17
|
import axios, { AxiosError } from "node-karin/axios";
|
|
18
|
-
import { pipeline } from "node:stream/promises";
|
|
19
18
|
import { Transform } from "node:stream";
|
|
19
|
+
import { pipeline } from "node:stream/promises";
|
|
20
20
|
import express from "node-karin/express";
|
|
21
21
|
import template from "node-karin/template";
|
|
22
22
|
import _ from "node-karin/lodash";
|
|
@@ -905,7 +905,7 @@ var init_kuaishou$2 = __esmMin(() => {
|
|
|
905
905
|
});
|
|
906
906
|
var xiaohongshuSign;
|
|
907
907
|
var init_sign$1 = __esmMin(() => {
|
|
908
|
-
|
|
908
|
+
init_dist();
|
|
909
909
|
xiaohongshuSign = class {
|
|
910
910
|
static client = new Xhshow();
|
|
911
911
|
static generateXSGet(path$1, a1Cookie, clientType = "xhs-pc-web", params = {}) {
|
|
@@ -2207,8 +2207,8 @@ var init_sign = __esmMin(() => {
|
|
|
2207
2207
|
douyinSign = class {
|
|
2208
2208
|
static Mstoken(length) {
|
|
2209
2209
|
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
2210
|
-
const randomBytes = crypto.randomBytes(length ?? 116);
|
|
2211
|
-
return Array.from(randomBytes, (byte) => characters[byte % 62]).join("");
|
|
2210
|
+
const randomBytes$1 = crypto.randomBytes(length ?? 116);
|
|
2211
|
+
return Array.from(randomBytes$1, (byte) => characters[byte % 62]).join("");
|
|
2212
2212
|
}
|
|
2213
2213
|
static AB(url, userAgent) {
|
|
2214
2214
|
return a_bogus_default(url, userAgent ?? defaultUserAgent);
|
|
@@ -5768,7 +5768,7 @@ var init_src = __esmMin(() => {
|
|
|
5768
5768
|
init_server();
|
|
5769
5769
|
init_types$1();
|
|
5770
5770
|
init_api_spec();
|
|
5771
|
-
getVersion = () => "6.0.0-beta.
|
|
5771
|
+
getVersion = () => "6.0.0-beta.3";
|
|
5772
5772
|
VERSION = getVersion();
|
|
5773
5773
|
Object.defineProperty(CreateAmagiApp, "version", {
|
|
5774
5774
|
value: VERSION,
|
|
@@ -6149,7 +6149,7 @@ var init_Config = __esmMin(() => {
|
|
|
6149
6149
|
return getConfigInstance()[prop];
|
|
6150
6150
|
} });
|
|
6151
6151
|
});
|
|
6152
|
-
var Base,
|
|
6152
|
+
var Base, Count, uploadFile, downloadVideo, downloadFile, processFilename;
|
|
6153
6153
|
var init_Base = __esmMin(() => {
|
|
6154
6154
|
init_utils$1();
|
|
6155
6155
|
init_Config();
|
|
@@ -6163,50 +6163,6 @@ var init_Base = __esmMin(() => {
|
|
|
6163
6163
|
this.headers = BASE_HEADERS;
|
|
6164
6164
|
}
|
|
6165
6165
|
};
|
|
6166
|
-
statBotId$1 = (pushList) => {
|
|
6167
|
-
const platformBotCount = {
|
|
6168
|
-
douyin: /* @__PURE__ */ new Map(),
|
|
6169
|
-
bilibili: /* @__PURE__ */ new Map()
|
|
6170
|
-
};
|
|
6171
|
-
pushList.douyin.forEach((item) => {
|
|
6172
|
-
item.group_id.forEach((gid) => {
|
|
6173
|
-
const botId = gid.split(":")[1];
|
|
6174
|
-
platformBotCount.douyin.set(botId, (platformBotCount.douyin.get(botId) ?? 0) + 1);
|
|
6175
|
-
});
|
|
6176
|
-
});
|
|
6177
|
-
pushList.bilibili.forEach((item) => {
|
|
6178
|
-
item.group_id.forEach((gid) => {
|
|
6179
|
-
const botId = gid.split(":")[1];
|
|
6180
|
-
platformBotCount.bilibili.set(botId, (platformBotCount.bilibili.get(botId) ?? 0) + 1);
|
|
6181
|
-
});
|
|
6182
|
-
});
|
|
6183
|
-
let douyinMaxCount = 0;
|
|
6184
|
-
let douyinMostFrequentBot = "";
|
|
6185
|
-
platformBotCount.douyin.forEach((count, botId) => {
|
|
6186
|
-
if (count > douyinMaxCount) {
|
|
6187
|
-
douyinMaxCount = count;
|
|
6188
|
-
douyinMostFrequentBot = botId;
|
|
6189
|
-
}
|
|
6190
|
-
});
|
|
6191
|
-
let biliMaxCount = 0;
|
|
6192
|
-
let biliMostFrequentBot = "";
|
|
6193
|
-
platformBotCount.bilibili.forEach((count, botId) => {
|
|
6194
|
-
if (count > biliMaxCount) {
|
|
6195
|
-
biliMaxCount = count;
|
|
6196
|
-
biliMostFrequentBot = botId;
|
|
6197
|
-
}
|
|
6198
|
-
});
|
|
6199
|
-
return {
|
|
6200
|
-
douyin: {
|
|
6201
|
-
botId: douyinMostFrequentBot,
|
|
6202
|
-
count: douyinMaxCount
|
|
6203
|
-
},
|
|
6204
|
-
bilibili: {
|
|
6205
|
-
botId: biliMostFrequentBot,
|
|
6206
|
-
count: biliMaxCount
|
|
6207
|
-
}
|
|
6208
|
-
};
|
|
6209
|
-
};
|
|
6210
6166
|
Count = (count) => {
|
|
6211
6167
|
if (count >= 1e8) return (count / 1e8).toFixed(1) + "亿";
|
|
6212
6168
|
else if (count >= 1e4) return (count / 1e4).toFixed(1) + "万";
|
|
@@ -6532,94 +6488,109 @@ var init_QRCodeScanner = __esmMin(() => {
|
|
|
6532
6488
|
const { width, height } = imageData;
|
|
6533
6489
|
const dataSizeMB = (width * height * 4 / 1024 / 1024).toFixed(2);
|
|
6534
6490
|
logger.debug(`图片数据: ${width}x${height}, 内存占用: ${dataSizeMB}MB`);
|
|
6535
|
-
if (width <=
|
|
6536
|
-
logger.debug("
|
|
6491
|
+
if (width <= 1024 && height <= 1024) {
|
|
6492
|
+
logger.debug("图片尺寸较小,使用全图识别策略");
|
|
6537
6493
|
const result = this.tryRecognizeInRegion(imageData, "全图");
|
|
6538
6494
|
if (result) return result;
|
|
6539
6495
|
}
|
|
6540
|
-
logger.debug(
|
|
6496
|
+
logger.debug(`使用分块扫描策略 (${width}x${height})`);
|
|
6541
6497
|
const scanRegions = [];
|
|
6542
|
-
const blockSize =
|
|
6498
|
+
const blockSize = Math.min(800, Math.floor(Math.max(width, height) * .6));
|
|
6499
|
+
const blockW = Math.min(blockSize, width);
|
|
6500
|
+
const blockH = Math.min(blockSize, height);
|
|
6543
6501
|
logger.debug("添加四角扫描区域");
|
|
6544
6502
|
scanRegions.push({
|
|
6545
6503
|
name: "左上角",
|
|
6546
6504
|
x: 0,
|
|
6547
6505
|
y: 0,
|
|
6548
|
-
w:
|
|
6549
|
-
h:
|
|
6506
|
+
w: blockW,
|
|
6507
|
+
h: blockH
|
|
6550
6508
|
});
|
|
6551
|
-
|
|
6509
|
+
scanRegions.push({
|
|
6552
6510
|
name: "右上角",
|
|
6553
|
-
x:
|
|
6511
|
+
x: Math.max(0, width - blockW),
|
|
6554
6512
|
y: 0,
|
|
6555
|
-
w:
|
|
6556
|
-
h:
|
|
6513
|
+
w: blockW,
|
|
6514
|
+
h: blockH
|
|
6557
6515
|
});
|
|
6558
|
-
|
|
6516
|
+
scanRegions.push({
|
|
6559
6517
|
name: "左下角",
|
|
6560
6518
|
x: 0,
|
|
6561
|
-
y:
|
|
6562
|
-
w:
|
|
6563
|
-
h:
|
|
6519
|
+
y: Math.max(0, height - blockH),
|
|
6520
|
+
w: blockW,
|
|
6521
|
+
h: blockH
|
|
6564
6522
|
});
|
|
6565
|
-
|
|
6523
|
+
scanRegions.push({
|
|
6566
6524
|
name: "右下角",
|
|
6567
|
-
x:
|
|
6568
|
-
y:
|
|
6569
|
-
w:
|
|
6570
|
-
h:
|
|
6525
|
+
x: Math.max(0, width - blockW),
|
|
6526
|
+
y: Math.max(0, height - blockH),
|
|
6527
|
+
w: blockW,
|
|
6528
|
+
h: blockH
|
|
6571
6529
|
});
|
|
6572
|
-
if (width >
|
|
6530
|
+
if (width > blockW * 1.5) {
|
|
6573
6531
|
logger.debug("添加顶部/底部中间扫描区域");
|
|
6574
6532
|
scanRegions.push({
|
|
6575
6533
|
name: "顶部中",
|
|
6576
|
-
x: Math.floor((width -
|
|
6534
|
+
x: Math.floor((width - blockW) / 2),
|
|
6577
6535
|
y: 0,
|
|
6578
|
-
w:
|
|
6579
|
-
h:
|
|
6536
|
+
w: blockW,
|
|
6537
|
+
h: blockH
|
|
6580
6538
|
});
|
|
6581
|
-
if (height >
|
|
6539
|
+
if (height > blockH * 1.5) scanRegions.push({
|
|
6582
6540
|
name: "底部中",
|
|
6583
|
-
x: Math.floor((width -
|
|
6584
|
-
y: height -
|
|
6585
|
-
w:
|
|
6586
|
-
h:
|
|
6541
|
+
x: Math.floor((width - blockW) / 2),
|
|
6542
|
+
y: Math.max(0, height - blockH),
|
|
6543
|
+
w: blockW,
|
|
6544
|
+
h: blockH
|
|
6587
6545
|
});
|
|
6588
6546
|
}
|
|
6589
|
-
if (height >
|
|
6547
|
+
if (height > blockH * 1.5) {
|
|
6590
6548
|
logger.debug("添加左右中间扫描区域");
|
|
6591
|
-
const middleY = Math.floor((height -
|
|
6549
|
+
const middleY = Math.floor((height - blockH) / 2);
|
|
6592
6550
|
scanRegions.push({
|
|
6593
6551
|
name: "左中",
|
|
6594
6552
|
x: 0,
|
|
6595
6553
|
y: middleY,
|
|
6596
|
-
w:
|
|
6597
|
-
h:
|
|
6554
|
+
w: blockW,
|
|
6555
|
+
h: blockH
|
|
6598
6556
|
});
|
|
6599
|
-
if (width >
|
|
6557
|
+
if (width > blockW * 1.5) scanRegions.push({
|
|
6600
6558
|
name: "右中",
|
|
6601
|
-
x: width -
|
|
6559
|
+
x: Math.max(0, width - blockW),
|
|
6602
6560
|
y: middleY,
|
|
6603
|
-
w:
|
|
6604
|
-
h:
|
|
6561
|
+
w: blockW,
|
|
6562
|
+
h: blockH
|
|
6605
6563
|
});
|
|
6606
6564
|
}
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
let slidingWindowCount = 0;
|
|
6610
|
-
for (let y = 0; y < height - blockSize; y += step) {
|
|
6565
|
+
if (width > blockW && height > blockH) {
|
|
6566
|
+
logger.debug("添加中心区域");
|
|
6611
6567
|
scanRegions.push({
|
|
6612
|
-
name:
|
|
6613
|
-
x:
|
|
6614
|
-
y,
|
|
6615
|
-
w:
|
|
6616
|
-
h:
|
|
6568
|
+
name: "中心",
|
|
6569
|
+
x: Math.floor((width - blockW) / 2),
|
|
6570
|
+
y: Math.floor((height - blockH) / 2),
|
|
6571
|
+
w: blockW,
|
|
6572
|
+
h: blockH
|
|
6617
6573
|
});
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6574
|
+
}
|
|
6575
|
+
logger.debug("添加滑动窗口扫描区域");
|
|
6576
|
+
const step = Math.floor(blockSize * .6);
|
|
6577
|
+
let slidingWindowCount = 0;
|
|
6578
|
+
for (let y = 0; y <= height - blockH; y += step) {
|
|
6579
|
+
for (let x = 0; x <= width - blockW; x += step) {
|
|
6580
|
+
scanRegions.push({
|
|
6581
|
+
name: `滑动-${slidingWindowCount}`,
|
|
6582
|
+
x,
|
|
6583
|
+
y,
|
|
6584
|
+
w: blockW,
|
|
6585
|
+
h: blockH
|
|
6586
|
+
});
|
|
6587
|
+
slidingWindowCount++;
|
|
6588
|
+
if (scanRegions.length > 40) {
|
|
6589
|
+
logger.debug(`滑动窗口数量达到上限,停止添加 (已添加 ${slidingWindowCount} 个)`);
|
|
6590
|
+
break;
|
|
6591
|
+
}
|
|
6622
6592
|
}
|
|
6593
|
+
if (scanRegions.length > 40) break;
|
|
6623
6594
|
}
|
|
6624
6595
|
logger.debug(`共生成 ${scanRegions.length} 个扫描区域,开始逐个扫描`);
|
|
6625
6596
|
for (let i = 0; i < scanRegions.length; i++) {
|
|
@@ -6810,6 +6781,123 @@ var init_Common = __esmMin(async () => {
|
|
|
6810
6781
|
};
|
|
6811
6782
|
Common = new Tools();
|
|
6812
6783
|
});
|
|
6784
|
+
function getEmojiId(e, type) {
|
|
6785
|
+
return (PLATFORM_EMOJI_IDS[e.bot?.adapter?.platform || "other"] || PLATFORM_EMOJI_IDS.other)[type];
|
|
6786
|
+
}
|
|
6787
|
+
async function setEmojiReaction(e, emojiId, isSet = true) {
|
|
6788
|
+
if (!Config.app.EmojiReply) return false;
|
|
6789
|
+
if (e.isPrivate) return false;
|
|
6790
|
+
try {
|
|
6791
|
+
await e.bot.setMsgReaction(e.contact, e.messageId, emojiId, isSet);
|
|
6792
|
+
return true;
|
|
6793
|
+
} catch (err) {
|
|
6794
|
+
logger.debug("[EmojiReaction] 设置表情回复失败(已忽略):", err);
|
|
6795
|
+
return false;
|
|
6796
|
+
}
|
|
6797
|
+
}
|
|
6798
|
+
var PLATFORM_EMOJI_IDS, EmojiReactionManager;
|
|
6799
|
+
var init_EmojiReaction = __esmMin(() => {
|
|
6800
|
+
init_Config();
|
|
6801
|
+
PLATFORM_EMOJI_IDS = {
|
|
6802
|
+
qq: {
|
|
6803
|
+
EYES: 128064,
|
|
6804
|
+
PROCESSING: 366,
|
|
6805
|
+
SUCCESS: 389,
|
|
6806
|
+
ERROR: 379
|
|
6807
|
+
},
|
|
6808
|
+
wechat: {
|
|
6809
|
+
EYES: "WECHAT_EYES_PLACEHOLDER",
|
|
6810
|
+
PROCESSING: "WECHAT_PROCESSING_PLACEHOLDER",
|
|
6811
|
+
SUCCESS: "WECHAT_SUCCESS_PLACEHOLDER",
|
|
6812
|
+
ERROR: "WECHAT_ERROR_PLACEHOLDER"
|
|
6813
|
+
},
|
|
6814
|
+
telegram: {
|
|
6815
|
+
EYES: "TELEGRAM_EYES_PLACEHOLDER",
|
|
6816
|
+
PROCESSING: "TELEGRAM_PROCESSING_PLACEHOLDER",
|
|
6817
|
+
SUCCESS: "TELEGRAM_SUCCESS_PLACEHOLDER",
|
|
6818
|
+
ERROR: "TELEGRAM_ERROR_PLACEHOLDER"
|
|
6819
|
+
},
|
|
6820
|
+
discord: {
|
|
6821
|
+
EYES: "👀",
|
|
6822
|
+
PROCESSING: "⏳",
|
|
6823
|
+
SUCCESS: "✅",
|
|
6824
|
+
ERROR: "❌"
|
|
6825
|
+
},
|
|
6826
|
+
koko: {
|
|
6827
|
+
EYES: "KOKO_EYES_PLACEHOLDER",
|
|
6828
|
+
PROCESSING: "KOKO_PROCESSING_PLACEHOLDER",
|
|
6829
|
+
SUCCESS: "KOKO_SUCCESS_PLACEHOLDER",
|
|
6830
|
+
ERROR: "KOKO_ERROR_PLACEHOLDER"
|
|
6831
|
+
},
|
|
6832
|
+
other: {
|
|
6833
|
+
EYES: "OTHER_EYES_PLACEHOLDER",
|
|
6834
|
+
PROCESSING: "OTHER_PROCESSING_PLACEHOLDER",
|
|
6835
|
+
SUCCESS: "OTHER_SUCCESS_PLACEHOLDER",
|
|
6836
|
+
ERROR: "OTHER_ERROR_PLACEHOLDER"
|
|
6837
|
+
}
|
|
6838
|
+
};
|
|
6839
|
+
PLATFORM_EMOJI_IDS.qq;
|
|
6840
|
+
EmojiReactionManager = class {
|
|
6841
|
+
e;
|
|
6842
|
+
emojiIds = /* @__PURE__ */ new Set();
|
|
6843
|
+
constructor(e) {
|
|
6844
|
+
this.e = e;
|
|
6845
|
+
}
|
|
6846
|
+
getPlatformEmojiId(type) {
|
|
6847
|
+
return getEmojiId(this.e, type);
|
|
6848
|
+
}
|
|
6849
|
+
normalizeEmojiId(emojiId) {
|
|
6850
|
+
return typeof emojiId === "string" && [
|
|
6851
|
+
"EYES",
|
|
6852
|
+
"PROCESSING",
|
|
6853
|
+
"SUCCESS",
|
|
6854
|
+
"ERROR"
|
|
6855
|
+
].includes(emojiId) ? this.getPlatformEmojiId(emojiId) : emojiId;
|
|
6856
|
+
}
|
|
6857
|
+
async add(emojiId) {
|
|
6858
|
+
const actualEmojiId = this.normalizeEmojiId(emojiId);
|
|
6859
|
+
const success = await setEmojiReaction(this.e, actualEmojiId, true);
|
|
6860
|
+
if (success) this.emojiIds.add(actualEmojiId);
|
|
6861
|
+
return success;
|
|
6862
|
+
}
|
|
6863
|
+
async remove(emojiId) {
|
|
6864
|
+
const actualEmojiId = this.normalizeEmojiId(emojiId);
|
|
6865
|
+
const success = await setEmojiReaction(this.e, actualEmojiId, false);
|
|
6866
|
+
if (success) this.emojiIds.delete(actualEmojiId);
|
|
6867
|
+
return success;
|
|
6868
|
+
}
|
|
6869
|
+
async replace(oldEmojiId, newEmojiId, delayMs = 2e3) {
|
|
6870
|
+
const addSuccess = await this.add(newEmojiId);
|
|
6871
|
+
await new Promise((resolve$1) => setTimeout(resolve$1, delayMs));
|
|
6872
|
+
await this.remove(oldEmojiId);
|
|
6873
|
+
return addSuccess;
|
|
6874
|
+
}
|
|
6875
|
+
async clearAll() {
|
|
6876
|
+
let count = 0;
|
|
6877
|
+
for (const emojiId of this.emojiIds) if (await setEmojiReaction(this.e, emojiId, false)) count++;
|
|
6878
|
+
this.emojiIds.clear();
|
|
6879
|
+
return count;
|
|
6880
|
+
}
|
|
6881
|
+
async keepOnly(keepEmojiIds) {
|
|
6882
|
+
const keepSet = new Set(keepEmojiIds);
|
|
6883
|
+
let removedCount = 0;
|
|
6884
|
+
for (const emojiId of this.emojiIds) if (!keepSet.has(emojiId)) {
|
|
6885
|
+
if (await this.remove(emojiId)) removedCount++;
|
|
6886
|
+
}
|
|
6887
|
+
for (const emojiId of keepEmojiIds) if (!this.emojiIds.has(emojiId)) await this.add(emojiId);
|
|
6888
|
+
return removedCount;
|
|
6889
|
+
}
|
|
6890
|
+
getCurrentEmojiIds() {
|
|
6891
|
+
return Array.from(this.emojiIds);
|
|
6892
|
+
}
|
|
6893
|
+
has(emojiId) {
|
|
6894
|
+
return this.emojiIds.has(emojiId);
|
|
6895
|
+
}
|
|
6896
|
+
count() {
|
|
6897
|
+
return this.emojiIds.size;
|
|
6898
|
+
}
|
|
6899
|
+
};
|
|
6900
|
+
});
|
|
6813
6901
|
async function detectEncoder$1(codec) {
|
|
6814
6902
|
if (cachedEncoders$1[codec]) return cachedEncoders$1[codec];
|
|
6815
6903
|
logger.debug(`[BiliDanmaku] 开始检测 ${codec.toUpperCase()} 编码器...`);
|
|
@@ -7509,10 +7597,26 @@ var init_danmaku = __esmMin(async () => {
|
|
|
7509
7597
|
};
|
|
7510
7598
|
MAX_OUTPUT_WIDTH = 2160;
|
|
7511
7599
|
});
|
|
7600
|
+
async function fixM4sFile(inputPath, outputPath) {
|
|
7601
|
+
const result = await ffmpeg(`-y -i "${inputPath}" -c copy -movflags +faststart "${outputPath}"`);
|
|
7602
|
+
if (result.status) logger.debug(`m4s 文件修复成功: ${outputPath}`);
|
|
7603
|
+
else logger.error("m4s 文件修复失败", result);
|
|
7604
|
+
return result.status;
|
|
7605
|
+
}
|
|
7512
7606
|
async function getMediaDuration(path$1) {
|
|
7513
7607
|
const { stdout } = await ffprobe(`-v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${path$1}"`);
|
|
7514
7608
|
return parseFloat(parseFloat(stdout.trim()).toFixed(2));
|
|
7515
7609
|
}
|
|
7610
|
+
async function loopVideo(inputPath, outputPath, loopCount) {
|
|
7611
|
+
if (loopCount <= 1) {
|
|
7612
|
+
fs.copyFileSync(inputPath, outputPath);
|
|
7613
|
+
return true;
|
|
7614
|
+
}
|
|
7615
|
+
const result = await ffmpeg(`-y -stream_loop ${loopCount - 1} -i "${inputPath}" -c copy "${outputPath}"`);
|
|
7616
|
+
if (result.status) logger.mark(`视频重放成功: ${outputPath}`);
|
|
7617
|
+
else logger.error("视频重放失败", result);
|
|
7618
|
+
return result.status;
|
|
7619
|
+
}
|
|
7516
7620
|
async function mergeVideoAudio(videoPath, audioPath, resultPath) {
|
|
7517
7621
|
const result = await ffmpeg(`-y -i "${videoPath}" -i "${audioPath}" -c copy "${resultPath}"`);
|
|
7518
7622
|
if (result.status) logger.mark(`视频合成成功: ${resultPath}`);
|
|
@@ -7566,38 +7670,6 @@ async function mergeLiveImageContinuous(options, context) {
|
|
|
7566
7670
|
}
|
|
7567
7671
|
};
|
|
7568
7672
|
}
|
|
7569
|
-
async function batchMergeLiveImages(videos, bgmPath, outputDir, mode = "independent", loopCount = 3) {
|
|
7570
|
-
const results = [];
|
|
7571
|
-
if (mode === "independent") for (const video of videos) {
|
|
7572
|
-
const outputPath = `${outputDir}${video.outputName}`;
|
|
7573
|
-
const success = await mergeLiveImageIndependent({
|
|
7574
|
-
videoPath: video.path,
|
|
7575
|
-
outputPath,
|
|
7576
|
-
loopCount
|
|
7577
|
-
}, bgmPath);
|
|
7578
|
-
results.push({
|
|
7579
|
-
success,
|
|
7580
|
-
outputPath
|
|
7581
|
-
});
|
|
7582
|
-
}
|
|
7583
|
-
else {
|
|
7584
|
-
let context = await createLiveImageContext(bgmPath);
|
|
7585
|
-
for (const video of videos) {
|
|
7586
|
-
const outputPath = `${outputDir}${video.outputName}`;
|
|
7587
|
-
const result = await mergeLiveImageContinuous({
|
|
7588
|
-
videoPath: video.path,
|
|
7589
|
-
outputPath,
|
|
7590
|
-
loopCount
|
|
7591
|
-
}, context);
|
|
7592
|
-
context = result.context;
|
|
7593
|
-
results.push({
|
|
7594
|
-
success: result.success,
|
|
7595
|
-
outputPath
|
|
7596
|
-
});
|
|
7597
|
-
}
|
|
7598
|
-
}
|
|
7599
|
-
return results;
|
|
7600
|
-
}
|
|
7601
7673
|
var init_FFmpeg = __esmMin(async () => {
|
|
7602
7674
|
await init_utils$1();
|
|
7603
7675
|
await init_danmaku$1();
|
|
@@ -7838,6 +7910,37 @@ var init_Downloader = __esmMin(() => {
|
|
|
7838
7910
|
});
|
|
7839
7911
|
const response = await this.axiosInstance(requestConfig);
|
|
7840
7912
|
clearTimeout(timeoutId);
|
|
7913
|
+
if (response.status === 416) {
|
|
7914
|
+
logger.warn("服务器返回 416,文件可能已下载完成,验证文件大小...");
|
|
7915
|
+
if (fs.existsSync(this.filepath)) {
|
|
7916
|
+
const stats = fs.statSync(this.filepath);
|
|
7917
|
+
logger.debug(`当前文件大小: ${formatBytes(stats.size)}`);
|
|
7918
|
+
if (stats.size > 1024) {
|
|
7919
|
+
logger.debug("文件大小合理,认为下载已完成");
|
|
7920
|
+
return {
|
|
7921
|
+
filepath: this.filepath,
|
|
7922
|
+
totalBytes: stats.size
|
|
7923
|
+
};
|
|
7924
|
+
} else {
|
|
7925
|
+
logger.warn("文件太小,删除并重新下载");
|
|
7926
|
+
fs.unlinkSync(this.filepath);
|
|
7927
|
+
return this.download(progressCallback, retryCount + 1);
|
|
7928
|
+
}
|
|
7929
|
+
}
|
|
7930
|
+
}
|
|
7931
|
+
if (response.status !== 200 && response.status !== 206) {
|
|
7932
|
+
logger.error(`下载失败: HTTP ${response.status}, URL: ${this.url}`);
|
|
7933
|
+
logger.error(`响应头: ${JSON.stringify(response.headers)}`);
|
|
7934
|
+
if (response.headers["content-length"] && parseInt(response.headers["content-length"]) < 10240) {
|
|
7935
|
+
let errorBody = "";
|
|
7936
|
+
response.data.on("data", (chunk) => {
|
|
7937
|
+
errorBody += chunk.toString();
|
|
7938
|
+
});
|
|
7939
|
+
await new Promise((resolve$1) => setTimeout(resolve$1, 100));
|
|
7940
|
+
logger.error(`响应内容: ${errorBody}`);
|
|
7941
|
+
}
|
|
7942
|
+
throw new Error(`HTTP ${response.status}: ${this.url}`);
|
|
7943
|
+
}
|
|
7841
7944
|
const supportsRange = response.status === 206;
|
|
7842
7945
|
if (startByte > 0 && !supportsRange) {
|
|
7843
7946
|
logger.warn("服务器不支持断点续传,将重新下载整个文件");
|
|
@@ -7865,18 +7968,36 @@ var init_Downloader = __esmMin(() => {
|
|
|
7865
7968
|
};
|
|
7866
7969
|
const interval = totalBytes > 0 && totalBytes < 10 * 1024 * 1024 ? 1e3 : 500;
|
|
7867
7970
|
intervalId = setInterval(printProgress, interval);
|
|
7868
|
-
const
|
|
7869
|
-
downloadedBytes +=
|
|
7870
|
-
|
|
7871
|
-
|
|
7971
|
+
const counterStream = new Transform({ transform(chunk, encoding, callback) {
|
|
7972
|
+
downloadedBytes += chunk.length;
|
|
7973
|
+
callback(null, chunk);
|
|
7974
|
+
} });
|
|
7872
7975
|
if (this.throttleConfig.enabled) {
|
|
7873
7976
|
throttleStream = new ThrottleStream(this.currentSpeed);
|
|
7874
7977
|
logger.debug(`启用限速下载: ${formatBytes(this.currentSpeed)}/s`);
|
|
7875
|
-
await pipeline(response.data, throttleStream, writer);
|
|
7876
|
-
} else await pipeline(response.data, writer);
|
|
7978
|
+
await pipeline(response.data, throttleStream, counterStream, writer);
|
|
7979
|
+
} else await pipeline(response.data, counterStream, writer);
|
|
7877
7980
|
if (intervalId) clearInterval(intervalId);
|
|
7878
|
-
|
|
7879
|
-
|
|
7981
|
+
logger.debug("文件下载并写入完成");
|
|
7982
|
+
if (fs.existsSync(this.filepath)) {
|
|
7983
|
+
const actualSize = fs.statSync(this.filepath).size;
|
|
7984
|
+
const expectedSize = totalBytes > 0 ? totalBytes : downloadedBytes;
|
|
7985
|
+
if (actualSize < 1024 && expectedSize < 1024) {
|
|
7986
|
+
logger.error(`下载的文件异常小 (${formatBytes(actualSize)}),可能是错误响应`);
|
|
7987
|
+
try {
|
|
7988
|
+
const content = fs.readFileSync(this.filepath, "utf-8");
|
|
7989
|
+
logger.error(`文件内容: ${content}`);
|
|
7990
|
+
} catch {
|
|
7991
|
+
logger.error("无法读取文件内容(可能是二进制文件)");
|
|
7992
|
+
}
|
|
7993
|
+
throw new Error(`下载的文件异常小: ${formatBytes(actualSize)},可能是错误响应或链接失效`);
|
|
7994
|
+
}
|
|
7995
|
+
if (actualSize < expectedSize) {
|
|
7996
|
+
logger.warn(`文件大小不匹配: 实际 ${formatBytes(actualSize)}, 预期 ${formatBytes(expectedSize)}`);
|
|
7997
|
+
logger.warn(`差异: ${formatBytes(expectedSize - actualSize)} (${((expectedSize - actualSize) / expectedSize * 100).toFixed(2)}%)`);
|
|
7998
|
+
if ((expectedSize - actualSize) / expectedSize > .01) throw new Error(`文件下载不完整: 实际 ${formatBytes(actualSize)}, 预期 ${formatBytes(expectedSize)}`);
|
|
7999
|
+
} else logger.debug(`文件大小验证通过: ${formatBytes(actualSize)}`);
|
|
8000
|
+
}
|
|
7880
8001
|
this.consecutiveResets = 0;
|
|
7881
8002
|
return {
|
|
7882
8003
|
filepath: this.filepath,
|
|
@@ -8142,12 +8263,12 @@ var init_Network$1 = __esmMin(() => {
|
|
|
8142
8263
|
};
|
|
8143
8264
|
});
|
|
8144
8265
|
var init_Network = __esmMin(() => {
|
|
8145
|
-
init_constants();
|
|
8146
8266
|
init_Downloader();
|
|
8147
8267
|
init_helpers();
|
|
8148
8268
|
init_Network$1();
|
|
8149
8269
|
init_ThrottleStream();
|
|
8150
8270
|
init_types();
|
|
8271
|
+
init_constants();
|
|
8151
8272
|
});
|
|
8152
8273
|
var init_Networks = __esmMin(() => {
|
|
8153
8274
|
init_Network();
|
|
@@ -8332,48 +8453,12 @@ var init_Render = __esmMin(async () => {
|
|
|
8332
8453
|
return ret;
|
|
8333
8454
|
};
|
|
8334
8455
|
});
|
|
8335
|
-
var utils_exports = __export({
|
|
8336
|
-
BASE_HEADERS: () => BASE_HEADERS,
|
|
8337
|
-
Base: () => Base,
|
|
8338
|
-
Common: () => Common,
|
|
8339
|
-
Count: () => Count,
|
|
8340
|
-
DEFAULT_THROTTLE_CONFIG: () => DEFAULT_THROTTLE_CONFIG,
|
|
8341
|
-
Downloader: () => Downloader,
|
|
8342
|
-
Network: () => Network,
|
|
8343
|
-
Networks: () => Network,
|
|
8344
|
-
QRCodeScanner: () => QRCodeScanner,
|
|
8345
|
-
Render: () => Render,
|
|
8346
|
-
Root: () => Root,
|
|
8347
|
-
ThrottleStream: () => ThrottleStream,
|
|
8348
|
-
baseHeaders: () => BASE_HEADERS,
|
|
8349
|
-
batchMergeLiveImages: () => batchMergeLiveImages,
|
|
8350
|
-
burnDanmakuToVideo: () => burnBiliDanmaku,
|
|
8351
|
-
burnDouyinDanmaku: () => burnDouyinDanmaku,
|
|
8352
|
-
compressVideo: () => compressVideo,
|
|
8353
|
-
createLiveImageContext: () => createLiveImageContext,
|
|
8354
|
-
danmakuToASS: () => generateBiliASS,
|
|
8355
|
-
downloadFile: () => downloadFile,
|
|
8356
|
-
downloadVideo: () => downloadVideo,
|
|
8357
|
-
formatBuildTime: () => formatBuildTime,
|
|
8358
|
-
formatBytes: () => formatBytes,
|
|
8359
|
-
getBuildMetadata: () => getBuildMetadata,
|
|
8360
|
-
getErrorDescription: () => getErrorDescription,
|
|
8361
|
-
getMediaDuration: () => getMediaDuration,
|
|
8362
|
-
isRecoverableNetworkError: () => isRecoverableNetworkError,
|
|
8363
|
-
isThrottlingError: () => isThrottlingError,
|
|
8364
|
-
mergeAndBurnDanmaku: () => mergeAndBurnBili,
|
|
8365
|
-
mergeLiveImageContinuous: () => mergeLiveImageContinuous,
|
|
8366
|
-
mergeLiveImageIndependent: () => mergeLiveImageIndependent,
|
|
8367
|
-
mergeVideoAudio: () => mergeVideoAudio,
|
|
8368
|
-
sanitizeHeaders: () => sanitizeHeaders,
|
|
8369
|
-
statBotId: () => statBotId$1,
|
|
8370
|
-
uploadFile: () => uploadFile
|
|
8371
|
-
}, 1);
|
|
8372
8456
|
var init_utils$1 = __esmMin(async () => {
|
|
8373
8457
|
init_root();
|
|
8374
8458
|
init_Base();
|
|
8375
8459
|
init_build_metadata();
|
|
8376
8460
|
init_Common();
|
|
8461
|
+
init_EmojiReaction();
|
|
8377
8462
|
init_FFmpeg();
|
|
8378
8463
|
init_Networks();
|
|
8379
8464
|
init_QRCodeScanner();
|
|
@@ -8541,6 +8626,14 @@ var init_bilibili = __esmMin(async () => {
|
|
|
8541
8626
|
async unsubscribeBilibiliUser(groupId, host_mid) {
|
|
8542
8627
|
const result = await this.runQuery("DELETE FROM GroupUserSubscriptions WHERE groupId = ? AND host_mid = ?", [groupId, host_mid]);
|
|
8543
8628
|
await this.runQuery("DELETE FROM DynamicCaches WHERE groupId = ? AND host_mid = ?", [groupId, host_mid]);
|
|
8629
|
+
const remainingSubscriptions = await this.getQuery("SELECT COUNT(*) as count FROM GroupUserSubscriptions WHERE host_mid = ?", [host_mid]);
|
|
8630
|
+
if (remainingSubscriptions && remainingSubscriptions.count === 0) {
|
|
8631
|
+
logger.info(`[BilibiliDB] 用户 ${host_mid} 已无任何群组订阅,清理相关数据`);
|
|
8632
|
+
await this.runQuery("DELETE FROM BilibiliUsers WHERE host_mid = ?", [host_mid]);
|
|
8633
|
+
await this.runQuery("DELETE FROM FilterWords WHERE host_mid = ?", [host_mid]);
|
|
8634
|
+
await this.runQuery("DELETE FROM FilterTags WHERE host_mid = ?", [host_mid]);
|
|
8635
|
+
await this.runQuery("DELETE FROM DynamicCaches WHERE host_mid = ?", [host_mid]);
|
|
8636
|
+
}
|
|
8544
8637
|
return result.changes > 0;
|
|
8545
8638
|
}
|
|
8546
8639
|
async addDynamicCache(dynamic_id, host_mid, groupId, dynamic_type) {
|
|
@@ -8919,11 +9012,24 @@ var init_douyin = __esmMin(async () => {
|
|
|
8919
9012
|
logger.info("[DouyinDB] 检测到 AwemeCaches 表缺少 pushType 字段,开始执行迁移...");
|
|
8920
9013
|
await this.runQuery("ALTER TABLE AwemeCaches ADD COLUMN pushType TEXT DEFAULT 'post'");
|
|
8921
9014
|
await this.runQuery("ALTER TABLE AwemeCaches RENAME TO AwemeCaches_old");
|
|
8922
|
-
await this.runQuery(`\n CREATE TABLE IF NOT EXISTS AwemeCaches (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n aweme_id TEXT NOT NULL,\n sec_uid TEXT NOT NULL,\n groupId TEXT NOT NULL,\n pushType TEXT DEFAULT 'post',\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (sec_uid) REFERENCES DouyinUsers(sec_uid),\n
|
|
9015
|
+
await this.runQuery(`\n CREATE TABLE IF NOT EXISTS AwemeCaches (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n aweme_id TEXT NOT NULL,\n sec_uid TEXT NOT NULL,\n groupId TEXT NOT NULL,\n pushType TEXT DEFAULT 'post',\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (sec_uid) REFERENCES DouyinUsers(sec_uid),\n UNIQUE(aweme_id, sec_uid, groupId, pushType)\n )\n `);
|
|
8923
9016
|
await this.runQuery(`\n INSERT INTO AwemeCaches (id, aweme_id, sec_uid, groupId, pushType, createdAt, updatedAt)\n SELECT id, aweme_id, sec_uid, groupId, pushType, createdAt, updatedAt\n FROM AwemeCaches_old\n `);
|
|
8924
9017
|
await this.runQuery("DROP TABLE AwemeCaches_old");
|
|
8925
9018
|
logger.info("[DouyinDB] AwemeCaches 表迁移完成");
|
|
8926
9019
|
}
|
|
9020
|
+
try {
|
|
9021
|
+
const tableInfo = await this.allQuery("SELECT sql FROM sqlite_master WHERE type='table' AND name='AwemeCaches'");
|
|
9022
|
+
if (tableInfo.length > 0 && tableInfo[0].sql.includes("FOREIGN KEY (groupId) REFERENCES Groups(id)")) {
|
|
9023
|
+
logger.info("[DouyinDB] 检测到 AwemeCaches 表存在错误的外键约束,开始修复...");
|
|
9024
|
+
await this.runQuery("ALTER TABLE AwemeCaches RENAME TO AwemeCaches_old");
|
|
9025
|
+
await this.runQuery(`\n CREATE TABLE IF NOT EXISTS AwemeCaches (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n aweme_id TEXT NOT NULL,\n sec_uid TEXT NOT NULL,\n groupId TEXT NOT NULL,\n pushType TEXT DEFAULT 'post',\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (sec_uid) REFERENCES DouyinUsers(sec_uid),\n UNIQUE(aweme_id, sec_uid, groupId, pushType)\n )\n `);
|
|
9026
|
+
await this.runQuery(`\n INSERT INTO AwemeCaches (id, aweme_id, sec_uid, groupId, pushType, createdAt, updatedAt)\n SELECT id, aweme_id, sec_uid, groupId, pushType, createdAt, updatedAt\n FROM AwemeCaches_old\n `);
|
|
9027
|
+
await this.runQuery("DROP TABLE AwemeCaches_old");
|
|
9028
|
+
logger.info("[DouyinDB] AwemeCaches 表外键约束修复完成");
|
|
9029
|
+
}
|
|
9030
|
+
} catch (error) {
|
|
9031
|
+
logger.debug("[DouyinDB] 外键约束检查/修复跳过:", error);
|
|
9032
|
+
}
|
|
8927
9033
|
} catch (error) {
|
|
8928
9034
|
logger.error("[DouyinDB] 数据库迁移失败:", error);
|
|
8929
9035
|
}
|
|
@@ -8934,7 +9040,7 @@ var init_douyin = __esmMin(async () => {
|
|
|
8934
9040
|
`CREATE TABLE IF NOT EXISTS Groups (\n id TEXT NOT NULL,\n botId TEXT NOT NULL,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id, botId),\n FOREIGN KEY (botId) REFERENCES Bots(id)\n )`,
|
|
8935
9041
|
`CREATE TABLE IF NOT EXISTS DouyinUsers (\n sec_uid TEXT PRIMARY KEY,\n short_id TEXT,\n remark TEXT,\n living INTEGER DEFAULT 0,\n filterMode TEXT DEFAULT 'blacklist',\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP\n )`,
|
|
8936
9042
|
`CREATE TABLE IF NOT EXISTS GroupUserSubscriptions (\n groupId TEXT,\n sec_uid TEXT,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (groupId, sec_uid),\n FOREIGN KEY (groupId) REFERENCES Groups(id),\n FOREIGN KEY (sec_uid) REFERENCES DouyinUsers(sec_uid)\n )`,
|
|
8937
|
-
`CREATE TABLE IF NOT EXISTS AwemeCaches (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n aweme_id TEXT NOT NULL,\n sec_uid TEXT NOT NULL,\n groupId TEXT NOT NULL,\n pushType TEXT DEFAULT 'post',\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (sec_uid) REFERENCES DouyinUsers(sec_uid),\n
|
|
9043
|
+
`CREATE TABLE IF NOT EXISTS AwemeCaches (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n aweme_id TEXT NOT NULL,\n sec_uid TEXT NOT NULL,\n groupId TEXT NOT NULL,\n pushType TEXT DEFAULT 'post',\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (sec_uid) REFERENCES DouyinUsers(sec_uid),\n UNIQUE(aweme_id, sec_uid, groupId, pushType)\n )`,
|
|
8938
9044
|
`CREATE TABLE IF NOT EXISTS FilterWords (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n sec_uid TEXT NOT NULL,\n word TEXT NOT NULL,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (sec_uid) REFERENCES DouyinUsers(sec_uid),\n UNIQUE(sec_uid, word)\n )`,
|
|
8939
9045
|
`CREATE TABLE IF NOT EXISTS FilterTags (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n sec_uid TEXT NOT NULL,\n tag TEXT NOT NULL,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (sec_uid) REFERENCES DouyinUsers(sec_uid),\n UNIQUE(sec_uid, tag)\n )`,
|
|
8940
9046
|
`CREATE TABLE IF NOT EXISTS ListSnapshots (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n sec_uid TEXT NOT NULL,\n pushType TEXT NOT NULL,\n aweme_id TEXT NOT NULL,\n createdAt TEXT DEFAULT CURRENT_TIMESTAMP,\n updatedAt TEXT DEFAULT CURRENT_TIMESTAMP,\n FOREIGN KEY (sec_uid) REFERENCES DouyinUsers(sec_uid),\n UNIQUE(sec_uid, pushType, aweme_id)\n )`
|
|
@@ -9077,6 +9183,14 @@ var init_douyin = __esmMin(async () => {
|
|
|
9077
9183
|
async unsubscribeDouyinUser(groupId, sec_uid) {
|
|
9078
9184
|
const result = await this.runQuery("DELETE FROM GroupUserSubscriptions WHERE groupId = ? AND sec_uid = ?", [groupId, sec_uid]);
|
|
9079
9185
|
await this.runQuery("DELETE FROM AwemeCaches WHERE groupId = ? AND sec_uid = ?", [groupId, sec_uid]);
|
|
9186
|
+
const remainingSubscriptions = await this.getQuery("SELECT COUNT(*) as count FROM GroupUserSubscriptions WHERE sec_uid = ?", [sec_uid]);
|
|
9187
|
+
if (remainingSubscriptions && remainingSubscriptions.count === 0) {
|
|
9188
|
+
logger.info(`[DouyinDB] 用户 ${sec_uid} 已无任何群组订阅,清理相关数据`);
|
|
9189
|
+
await this.runQuery("DELETE FROM DouyinUsers WHERE sec_uid = ?", [sec_uid]);
|
|
9190
|
+
await this.runQuery("DELETE FROM FilterWords WHERE sec_uid = ?", [sec_uid]);
|
|
9191
|
+
await this.runQuery("DELETE FROM FilterTags WHERE sec_uid = ?", [sec_uid]);
|
|
9192
|
+
await this.runQuery("DELETE FROM AwemeCaches WHERE sec_uid = ?", [sec_uid]);
|
|
9193
|
+
}
|
|
9080
9194
|
return result.changes > 0;
|
|
9081
9195
|
}
|
|
9082
9196
|
async addAwemeCache(aweme_id, sec_uid, groupId, pushType = "post") {
|
|
@@ -12813,6 +12927,7 @@ var init_sender = __esmMin(() => {
|
|
|
12813
12927
|
var handleBusinessError, wrapWithErrorHandler;
|
|
12814
12928
|
var init_handler = __esmMin(async () => {
|
|
12815
12929
|
await init_module();
|
|
12930
|
+
await init_EmojiReaction();
|
|
12816
12931
|
await init_render();
|
|
12817
12932
|
await init_sender();
|
|
12818
12933
|
await init_strategy();
|
|
@@ -12853,10 +12968,23 @@ var init_handler = __esmMin(async () => {
|
|
|
12853
12968
|
}
|
|
12854
12969
|
};
|
|
12855
12970
|
wrapWithErrorHandler = (fn, options) => async (e, next) => {
|
|
12971
|
+
const emojiManager = e ? new EmojiReactionManager(e) : void 0;
|
|
12972
|
+
if (emojiManager) {
|
|
12973
|
+
await emojiManager.add("EYES");
|
|
12974
|
+
setTimeout(() => {
|
|
12975
|
+
emojiManager.add("PROCESSING").catch(() => {});
|
|
12976
|
+
}, 1500);
|
|
12977
|
+
}
|
|
12856
12978
|
const ctx = logger.runContext(async () => fn(e, next));
|
|
12857
12979
|
try {
|
|
12858
|
-
|
|
12980
|
+
const result = await ctx.run();
|
|
12981
|
+
if (emojiManager) await emojiManager.replace("PROCESSING", "SUCCESS");
|
|
12982
|
+
return result;
|
|
12859
12983
|
} catch (error) {
|
|
12984
|
+
if (emojiManager) {
|
|
12985
|
+
await emojiManager.clearAll();
|
|
12986
|
+
await emojiManager.add("ERROR");
|
|
12987
|
+
}
|
|
12860
12988
|
await new Promise((resolve$1) => setTimeout(resolve$1, 100));
|
|
12861
12989
|
if (await handleBusinessError(error, options, parseLogsToStructured(ctx.logs()), e) === "handled") return void 0;
|
|
12862
12990
|
throw error;
|
|
@@ -14282,22 +14410,6 @@ const webConfig = defineConfig({
|
|
|
14282
14410
|
description: "在解析任务开始时添加表情回应,若适配器不支持需要关闭",
|
|
14283
14411
|
defaultSelected: all.app.EmojiReply
|
|
14284
14412
|
}),
|
|
14285
|
-
components.input.number("EmojiReplyID", {
|
|
14286
|
-
label: "表情 ID",
|
|
14287
|
-
isDisabled: !all.app.EmojiReply,
|
|
14288
|
-
description: "详情查看:https://koishi.js.org/QFace/#/qqnt 中调试信息的 emojiId 字段,Emoji则是 qcid ",
|
|
14289
|
-
defaultValue: all.app.EmojiReplyID.toString(),
|
|
14290
|
-
rules: [{
|
|
14291
|
-
min: 0,
|
|
14292
|
-
max: 1145141919810
|
|
14293
|
-
}]
|
|
14294
|
-
}),
|
|
14295
|
-
components.switch.create("EmojiReplyIgnoreError", {
|
|
14296
|
-
label: "忽略表情回应失败",
|
|
14297
|
-
description: "开启后表情回应失败时不会抛出错误,程序会继续执行",
|
|
14298
|
-
defaultSelected: all.app.EmojiReplyIgnoreError,
|
|
14299
|
-
isDisabled: !all.app.EmojiReply
|
|
14300
|
-
}),
|
|
14301
14413
|
components.checkbox.group("errorLogSendTo", {
|
|
14302
14414
|
label: "错误日志",
|
|
14303
14415
|
description: "遇到错误时谁会收到错误日志。注:推送任务只可发送给主人。「第一个主人」与「所有主人」互斥。",
|
|
@@ -14948,11 +15060,6 @@ var Bilibili = class extends Base {
|
|
|
14948
15060
|
this.headers.Cookie = Config.cookies.bilibili;
|
|
14949
15061
|
}
|
|
14950
15062
|
async BilibiliHandler(iddata) {
|
|
14951
|
-
if (Config.app.EmojiReply) try {
|
|
14952
|
-
await this.e.bot.setMsgReaction(this.e.contact, this.e.messageId, Config.app.EmojiReplyID, true);
|
|
14953
|
-
} catch (err) {
|
|
14954
|
-
if (!Config.app.EmojiReplyIgnoreError) throw err;
|
|
14955
|
-
}
|
|
14956
15063
|
Config.bilibili.tip && await this.e.reply("检测到B站链接,开始解析");
|
|
14957
15064
|
switch (this.Type) {
|
|
14958
15065
|
case "one_video": {
|
|
@@ -15376,6 +15483,22 @@ var Bilibili = class extends Base {
|
|
|
15376
15483
|
shareurl: "动态分享链接",
|
|
15377
15484
|
Resolution: null
|
|
15378
15485
|
}));
|
|
15486
|
+
let staff = void 0;
|
|
15487
|
+
if (INFODATA.data.data.staff && Array.isArray(INFODATA.data.data.staff)) {
|
|
15488
|
+
const currentMid = dynamicInfo.data.data.item.modules.module_author.mid;
|
|
15489
|
+
staff = INFODATA.data.data.staff.map((member) => ({
|
|
15490
|
+
mid: member.mid,
|
|
15491
|
+
title: member.title,
|
|
15492
|
+
name: member.name,
|
|
15493
|
+
face: member.face,
|
|
15494
|
+
follower: member.follower
|
|
15495
|
+
}));
|
|
15496
|
+
const currentUserIndex = staff.findIndex((member) => member.mid === currentMid);
|
|
15497
|
+
if (currentUserIndex > 0) {
|
|
15498
|
+
const currentUser = staff.splice(currentUserIndex, 1)[0];
|
|
15499
|
+
staff.unshift(currentUser);
|
|
15500
|
+
}
|
|
15501
|
+
}
|
|
15379
15502
|
img$1 = await Render("bilibili/dynamic/DYNAMIC_TYPE_AV", {
|
|
15380
15503
|
image_url: INFODATA.data.data.pic,
|
|
15381
15504
|
text: br$3(INFODATA.data.data.title),
|
|
@@ -15387,7 +15510,7 @@ var Bilibili = class extends Base {
|
|
|
15387
15510
|
coin: Count(dycrad.stat.coin),
|
|
15388
15511
|
duration_text: dynamicInfo.data.data.item.modules.module_dynamic.major.archive.duration_text,
|
|
15389
15512
|
create_time: TimeFormatter.toDateTime(INFODATA.data.data.ctime),
|
|
15390
|
-
avatar_url:
|
|
15513
|
+
avatar_url: userProfileData.data.data.card.face,
|
|
15391
15514
|
frame: dynamicInfo.data.data.item.modules.module_author.pendant.image,
|
|
15392
15515
|
share_url: "https://www.bilibili.com/video/" + bvid,
|
|
15393
15516
|
username: checkvip$2(userProfileData.data.data.card),
|
|
@@ -15397,7 +15520,8 @@ var Bilibili = class extends Base {
|
|
|
15397
15520
|
following_count: Count(userProfileData.data.data.card.attention),
|
|
15398
15521
|
render_time: TimeFormatter.now(),
|
|
15399
15522
|
dynamicTYPE: "视频动态",
|
|
15400
|
-
dynamic_id: dynamicInfo.data.data.item.id_str
|
|
15523
|
+
dynamic_id: dynamicInfo.data.data.item.id_str,
|
|
15524
|
+
staff
|
|
15401
15525
|
});
|
|
15402
15526
|
this.e.reply(img$1);
|
|
15403
15527
|
}
|
|
@@ -15520,15 +15644,39 @@ var Bilibili = class extends Base {
|
|
|
15520
15644
|
switch (this.islogin) {
|
|
15521
15645
|
case true: {
|
|
15522
15646
|
logger.debug("视频 URL:", this.Type === "one_video" ? playUrlData.data?.dash?.video[0].base_url : playUrlData.result.dash.video[0].base_url);
|
|
15523
|
-
const
|
|
15524
|
-
|
|
15525
|
-
|
|
15647
|
+
const downloadHeaders = {
|
|
15648
|
+
...this.headers,
|
|
15649
|
+
Referer: "https://www.bilibili.com"
|
|
15650
|
+
};
|
|
15651
|
+
const bmp4Raw = await downloadFile(this.Type === "one_video" ? playUrlData.data?.dash?.video[0].base_url : playUrlData.result.dash.video[0].base_url, {
|
|
15652
|
+
title: `Bil_V_${this.Type === "one_video" ? infoData && infoData.data.bvid : infoData && infoData.result.season_id}.m4s`,
|
|
15653
|
+
headers: downloadHeaders
|
|
15526
15654
|
});
|
|
15655
|
+
const videoPath = Common.tempDri.video + `Bil_V_${this.Type === "one_video" ? infoData && infoData.data.bvid : infoData && infoData.result.season_id}.mp4`;
|
|
15656
|
+
if (!await fixM4sFile(bmp4Raw.filepath, videoPath)) {
|
|
15657
|
+
logger.error("视频文件修复失败");
|
|
15658
|
+
return false;
|
|
15659
|
+
}
|
|
15660
|
+
await Common.removeFile(bmp4Raw.filepath, true);
|
|
15527
15661
|
logger.debug("音频 URL:", this.Type === "one_video" ? playUrlData.data?.dash?.audio[0].base_url : playUrlData.result.dash.audio[0].base_url);
|
|
15528
|
-
const
|
|
15529
|
-
title: `Bil_A_${this.Type === "one_video" ? infoData && infoData.data.bvid : infoData && infoData.result.season_id}.
|
|
15530
|
-
headers:
|
|
15662
|
+
const bmp3Raw = await downloadFile(this.Type === "one_video" ? playUrlData.data?.dash?.audio[0].base_url : playUrlData.result.dash.audio[0].base_url, {
|
|
15663
|
+
title: `Bil_A_${this.Type === "one_video" ? infoData && infoData.data.bvid : infoData && infoData.result.season_id}.m4s`,
|
|
15664
|
+
headers: downloadHeaders
|
|
15531
15665
|
});
|
|
15666
|
+
const audioPath = Common.tempDri.video + `Bil_A_${this.Type === "one_video" ? infoData && infoData.data.bvid : infoData && infoData.result.season_id}.m4a`;
|
|
15667
|
+
if (!await fixM4sFile(bmp3Raw.filepath, audioPath)) {
|
|
15668
|
+
logger.error("音频文件修复失败");
|
|
15669
|
+
return false;
|
|
15670
|
+
}
|
|
15671
|
+
await Common.removeFile(bmp3Raw.filepath, true);
|
|
15672
|
+
const bmp4 = {
|
|
15673
|
+
filepath: videoPath,
|
|
15674
|
+
totalBytes: bmp4Raw.totalBytes
|
|
15675
|
+
};
|
|
15676
|
+
const bmp3 = {
|
|
15677
|
+
filepath: audioPath,
|
|
15678
|
+
totalBytes: bmp3Raw.totalBytes
|
|
15679
|
+
};
|
|
15532
15680
|
if (bmp4.filepath && bmp3.filepath) {
|
|
15533
15681
|
const hasDanmaku = (this.forceBurnDanmaku || Config.bilibili.burnDanmaku) && danmakuList.length > 0;
|
|
15534
15682
|
const resultPath = Common.tempDri.video + `Bil_Result_${this.Type === "one_video" ? infoData && infoData.data.bvid : infoData && infoData.result.season_id}.mp4`;
|
|
@@ -16370,7 +16518,7 @@ await init_amagiClient();
|
|
|
16370
16518
|
await init_Config();
|
|
16371
16519
|
var bilibiliBaseHeaders = {
|
|
16372
16520
|
...BASE_HEADERS,
|
|
16373
|
-
Referer: "https://
|
|
16521
|
+
Referer: "https://www.bilibili.com",
|
|
16374
16522
|
Cookie: Config.cookies.bilibili
|
|
16375
16523
|
};
|
|
16376
16524
|
var Bilibilipush = class extends Base {
|
|
@@ -16517,6 +16665,22 @@ var Bilibilipush = class extends Base {
|
|
|
16517
16665
|
send_video = false;
|
|
16518
16666
|
logger.debug(`UP主:${INFODATA.data.data.owner.name} 的该动态类型为${logger.yellow("番剧或影视")},默认跳过不下载,直达:${logger.green(INFODATA.data.data.redirect_url)}`);
|
|
16519
16667
|
}
|
|
16668
|
+
let staff = void 0;
|
|
16669
|
+
if (INFODATA.data.data.staff && Array.isArray(INFODATA.data.data.staff)) {
|
|
16670
|
+
const currentMid = data$1[dynamicId].host_mid;
|
|
16671
|
+
staff = INFODATA.data.data.staff.map((member) => ({
|
|
16672
|
+
mid: member.mid,
|
|
16673
|
+
title: member.title,
|
|
16674
|
+
name: member.name,
|
|
16675
|
+
face: member.face,
|
|
16676
|
+
follower: member.follower
|
|
16677
|
+
}));
|
|
16678
|
+
const currentUserIndex = staff.findIndex((member) => member.mid === currentMid);
|
|
16679
|
+
if (currentUserIndex > 0) {
|
|
16680
|
+
const currentUser = staff.splice(currentUserIndex, 1)[0];
|
|
16681
|
+
staff.unshift(currentUser);
|
|
16682
|
+
}
|
|
16683
|
+
}
|
|
16520
16684
|
img$2 = await Render("bilibili/dynamic/DYNAMIC_TYPE_AV", {
|
|
16521
16685
|
image_url: INFODATA.data.data.pic,
|
|
16522
16686
|
text: br$1(INFODATA.data.data.title),
|
|
@@ -16528,7 +16692,7 @@ var Bilibilipush = class extends Base {
|
|
|
16528
16692
|
coin: Count(dycrad.stat.coin),
|
|
16529
16693
|
duration_text: data$1[dynamicId].Dynamic_Data.modules.module_dynamic.major?.archive?.duration_text ?? "0:00",
|
|
16530
16694
|
create_time: TimeFormatter.toDateTime(data$1[dynamicId].Dynamic_Data.modules.module_author.pub_ts),
|
|
16531
|
-
avatar_url:
|
|
16695
|
+
avatar_url: userINFO.data.data.card.face,
|
|
16532
16696
|
frame: data$1[dynamicId].Dynamic_Data.modules.module_author.pendant.image,
|
|
16533
16697
|
share_url: "https://www.bilibili.com/video/" + bvid,
|
|
16534
16698
|
username: checkvip(userINFO.data.data.card),
|
|
@@ -16538,7 +16702,8 @@ var Bilibilipush = class extends Base {
|
|
|
16538
16702
|
following_count: Count(userINFO.data.data.card.attention),
|
|
16539
16703
|
render_time: TimeFormatter.now(),
|
|
16540
16704
|
dynamicTYPE: "视频动态推送",
|
|
16541
|
-
dynamic_id: dynamicId
|
|
16705
|
+
dynamic_id: dynamicId,
|
|
16706
|
+
staff
|
|
16542
16707
|
});
|
|
16543
16708
|
}
|
|
16544
16709
|
break;
|
|
@@ -17228,11 +17393,6 @@ var DouYin = class extends Base {
|
|
|
17228
17393
|
this.hasProcessedLiveImage = false;
|
|
17229
17394
|
}
|
|
17230
17395
|
async DouyinHandler(data$1) {
|
|
17231
|
-
if (Config.app.EmojiReply && !this.e.isPrivate) try {
|
|
17232
|
-
await this.e.bot.setMsgReaction(this.e.contact, this.e.messageId, Config.app.EmojiReplyID, true);
|
|
17233
|
-
} catch (err) {
|
|
17234
|
-
if (!Config.app.EmojiReplyIgnoreError) throw err;
|
|
17235
|
-
}
|
|
17236
17396
|
if (Config.douyin.tip) this.e.reply("检测到抖音链接,开始解析");
|
|
17237
17397
|
switch (this.type) {
|
|
17238
17398
|
case "one_work": {
|
|
@@ -17260,17 +17420,20 @@ var DouYin = class extends Base {
|
|
|
17260
17420
|
const processedImages = [];
|
|
17261
17421
|
const temp = [];
|
|
17262
17422
|
g_title = VideoData.data.aweme_detail.preview_title.substring(0, 50).replace(/[\\/:*?"<>|\r\n]/g, " ");
|
|
17263
|
-
let
|
|
17264
|
-
if (VideoData.data.aweme_detail.music.play_url.uri === "") mp3Path = JSON.parse(VideoData.data.aweme_detail.music.extra).original_song_url;
|
|
17265
|
-
else mp3Path = VideoData.data.aweme_detail.music.play_url.uri;
|
|
17266
|
-
const liveimgbgm = await downloadFile(mp3Path, {
|
|
17267
|
-
title: `Douyin_tmp_A_${Date.now()}.mp3`,
|
|
17268
|
-
headers: this.headers
|
|
17269
|
-
});
|
|
17270
|
-
temp.push(liveimgbgm);
|
|
17271
|
-
const mergeMode = Config.douyin.liveImageMergeMode ?? "independent";
|
|
17423
|
+
let liveimgbgm = null;
|
|
17272
17424
|
let bgmContext = null;
|
|
17273
|
-
|
|
17425
|
+
const mergeMode = Config.douyin.liveImageMergeMode ?? "independent";
|
|
17426
|
+
if (VideoData.data.aweme_detail.music) {
|
|
17427
|
+
let mp3Path = "";
|
|
17428
|
+
if (VideoData.data.aweme_detail.music.play_url.uri === "") mp3Path = JSON.parse(VideoData.data.aweme_detail.music.extra).original_song_url;
|
|
17429
|
+
else mp3Path = VideoData.data.aweme_detail.music.play_url.uri;
|
|
17430
|
+
liveimgbgm = await downloadFile(mp3Path, {
|
|
17431
|
+
title: `Douyin_tmp_A_${Date.now()}.mp3`,
|
|
17432
|
+
headers: this.headers
|
|
17433
|
+
});
|
|
17434
|
+
temp.push(liveimgbgm);
|
|
17435
|
+
if (mergeMode === "continuous") bgmContext = await createLiveImageContext(liveimgbgm.filepath);
|
|
17436
|
+
}
|
|
17274
17437
|
for (const [index, imageItem] of images.entries()) {
|
|
17275
17438
|
imagenum++;
|
|
17276
17439
|
if (imageItem.clip_type === 2 || imageItem.clip_type === void 0) {
|
|
@@ -17294,7 +17457,12 @@ var DouYin = class extends Base {
|
|
|
17294
17457
|
const outputPath = Common.tempDri.video + `Douyin_Result_${Date.now()}.mp4`;
|
|
17295
17458
|
let success;
|
|
17296
17459
|
const loopCount = imageItem.clip_type === 4 ? 1 : 3;
|
|
17297
|
-
if (
|
|
17460
|
+
if (!liveimgbgm) if (loopCount > 1) success = await loopVideo(liveimg.filepath, outputPath, loopCount);
|
|
17461
|
+
else {
|
|
17462
|
+
fs.renameSync(liveimg.filepath, outputPath);
|
|
17463
|
+
success = true;
|
|
17464
|
+
}
|
|
17465
|
+
else if (mergeMode === "continuous" && bgmContext) {
|
|
17298
17466
|
const result = await mergeLiveImageContinuous({
|
|
17299
17467
|
videoPath: liveimg.filepath,
|
|
17300
17468
|
outputPath,
|
|
@@ -17367,22 +17535,25 @@ var DouYin = class extends Base {
|
|
|
17367
17535
|
case VideoData.data.aweme_detail.is_slides === true && VideoData.data.aweme_detail.images !== null: {
|
|
17368
17536
|
const images = [];
|
|
17369
17537
|
const temp = [];
|
|
17370
|
-
let
|
|
17371
|
-
|
|
17372
|
-
|
|
17373
|
-
|
|
17374
|
-
|
|
17375
|
-
|
|
17376
|
-
|
|
17377
|
-
|
|
17538
|
+
let liveimgbgm = null;
|
|
17539
|
+
let bgmContext = null;
|
|
17540
|
+
const mergeMode = Config.douyin.liveImageMergeMode ?? "independent";
|
|
17541
|
+
if (VideoData.data.aweme_detail.music) {
|
|
17542
|
+
let mp3Path = "";
|
|
17543
|
+
if (VideoData.data.aweme_detail.music.play_url.uri === "") mp3Path = JSON.parse(VideoData.data.aweme_detail.music.extra).original_song_url;
|
|
17544
|
+
else mp3Path = VideoData.data.aweme_detail.music.play_url.uri;
|
|
17545
|
+
liveimgbgm = await downloadFile(mp3Path, {
|
|
17546
|
+
title: `Douyin_tmp_A_${Date.now()}.mp3`,
|
|
17547
|
+
headers: this.headers
|
|
17548
|
+
});
|
|
17549
|
+
temp.push(liveimgbgm);
|
|
17550
|
+
if (mergeMode === "continuous") bgmContext = await createLiveImageContext(liveimgbgm.filepath);
|
|
17551
|
+
}
|
|
17378
17552
|
const images1 = VideoData.data.aweme_detail.images ?? [];
|
|
17379
17553
|
if (!images1.length) logger.debug("未获取到合辑的图片数据");
|
|
17380
|
-
const mergeMode = Config.douyin.liveImageMergeMode ?? "independent";
|
|
17381
|
-
let bgmContext = null;
|
|
17382
|
-
if (mergeMode === "continuous") bgmContext = await createLiveImageContext(liveimgbgm.filepath);
|
|
17383
17554
|
for (const item of images1) {
|
|
17384
17555
|
imagenum++;
|
|
17385
|
-
if (item.clip_type === 2) {
|
|
17556
|
+
if (item.clip_type === 2 || item.clip_type === void 0) {
|
|
17386
17557
|
images.push(segment.image(item.url_list[0]));
|
|
17387
17558
|
continue;
|
|
17388
17559
|
}
|
|
@@ -17394,7 +17565,12 @@ var DouYin = class extends Base {
|
|
|
17394
17565
|
const outputPath = Common.tempDri.video + `Douyin_Result_${Date.now()}.mp4`;
|
|
17395
17566
|
let success;
|
|
17396
17567
|
const loopCount = item.clip_type === 4 ? 1 : 3;
|
|
17397
|
-
if (
|
|
17568
|
+
if (!liveimgbgm) if (loopCount > 1) success = await loopVideo(liveimg.filepath, outputPath, loopCount);
|
|
17569
|
+
else {
|
|
17570
|
+
fs.renameSync(liveimg.filepath, outputPath);
|
|
17571
|
+
success = true;
|
|
17572
|
+
}
|
|
17573
|
+
else if (mergeMode === "continuous" && bgmContext) {
|
|
17398
17574
|
const result = await mergeLiveImageContinuous({
|
|
17399
17575
|
videoPath: liveimg.filepath,
|
|
17400
17576
|
outputPath,
|
|
@@ -17609,13 +17785,12 @@ var DouYin = class extends Base {
|
|
|
17609
17785
|
await Common.removeFile(videoFile.filepath, true);
|
|
17610
17786
|
const stats = fs.statSync(filePath);
|
|
17611
17787
|
const fileSizeInMB = Number((stats.size / (1024 * 1024)).toFixed(2));
|
|
17612
|
-
|
|
17613
|
-
if (fileSizeInMB > Config.upload.groupfilevalue) await uploadFile$1(this.e, {
|
|
17788
|
+
if (fileSizeInMB > Config.upload.groupfilevalue) await uploadFile(this.e, {
|
|
17614
17789
|
filepath: filePath,
|
|
17615
17790
|
totalBytes: fileSizeInMB,
|
|
17616
17791
|
originTitle: g_title || ""
|
|
17617
17792
|
}, "", { useGroupFile: true });
|
|
17618
|
-
else await uploadFile
|
|
17793
|
+
else await uploadFile(this.e, {
|
|
17619
17794
|
filepath: filePath,
|
|
17620
17795
|
totalBytes: fileSizeInMB,
|
|
17621
17796
|
originTitle: g_title || ""
|
|
@@ -18338,7 +18513,7 @@ var DouYinpush = class extends Base {
|
|
|
18338
18513
|
})()
|
|
18339
18514
|
});
|
|
18340
18515
|
}
|
|
18341
|
-
for (const target of pushItem.targets)
|
|
18516
|
+
for (const target of pushItem.targets) {
|
|
18342
18517
|
let status = { message_id: "" };
|
|
18343
18518
|
const { groupId, botId } = target;
|
|
18344
18519
|
if (!skip) {
|
|
@@ -18376,22 +18551,22 @@ var DouYinpush = class extends Base {
|
|
|
18376
18551
|
if (Detail_Data.is_slides === true && Detail_Data.images) {
|
|
18377
18552
|
const images = [];
|
|
18378
18553
|
const temp = [];
|
|
18379
|
-
let
|
|
18380
|
-
if (Detail_Data.music.play_url.uri === "") mp3Path = JSON.parse(Detail_Data.music.extra).original_song_url;
|
|
18381
|
-
else mp3Path = Detail_Data.music.play_url.uri;
|
|
18382
|
-
const liveimgbgm = await downloadFile(mp3Path, {
|
|
18383
|
-
title: `Douyin_tmp_A_${Date.now()}.mp3`,
|
|
18384
|
-
headers: douyinBaseHeaders
|
|
18385
|
-
});
|
|
18386
|
-
temp.push(liveimgbgm);
|
|
18387
|
-
const images1 = Detail_Data.images ?? [];
|
|
18388
|
-
if (!images1.length) logger.debug("未获取到合辑的图片数据");
|
|
18389
|
-
const mergeMode = Config.douyin.liveImageMergeMode ?? "independent";
|
|
18554
|
+
let liveimgbgm = null;
|
|
18390
18555
|
let bgmContext = null;
|
|
18391
|
-
|
|
18392
|
-
|
|
18393
|
-
|
|
18556
|
+
const mergeMode = Config.douyin.liveImageMergeMode ?? "independent";
|
|
18557
|
+
if (Detail_Data.music) {
|
|
18558
|
+
let mp3Path = "";
|
|
18559
|
+
if (Detail_Data.music.play_url.uri === "") mp3Path = JSON.parse(Detail_Data.music.extra).original_song_url;
|
|
18560
|
+
else mp3Path = Detail_Data.music.play_url.uri;
|
|
18561
|
+
liveimgbgm = await downloadFile(mp3Path, {
|
|
18562
|
+
title: `Douyin_tmp_A_${Date.now()}.mp3`,
|
|
18563
|
+
headers: douyinBaseHeaders
|
|
18564
|
+
});
|
|
18565
|
+
temp.push(liveimgbgm);
|
|
18566
|
+
if (mergeMode === "continuous") bgmContext = await createLiveImageContext(liveimgbgm.filepath);
|
|
18394
18567
|
}
|
|
18568
|
+
const images1 = Detail_Data.images ?? [];
|
|
18569
|
+
if (!images1.length) logger.debug("未获取到合辑的图片数据");
|
|
18395
18570
|
for (const item of images1) {
|
|
18396
18571
|
if (item.clip_type === 2 || item.clip_type === void 0) {
|
|
18397
18572
|
images.push(segment.image(item.url_list[0]));
|
|
@@ -18402,37 +18577,40 @@ var DouYinpush = class extends Base {
|
|
|
18402
18577
|
headers: douyinBaseHeaders
|
|
18403
18578
|
});
|
|
18404
18579
|
if (liveimg.filepath) {
|
|
18405
|
-
const
|
|
18406
|
-
const outputPath = Common$1.tempDri.video + `Douyin_Result_${Date.now()}.mp4`;
|
|
18580
|
+
const outputPath = Common.tempDri.video + `Douyin_Result_${Date.now()}.mp4`;
|
|
18407
18581
|
let success;
|
|
18408
18582
|
const loopCount = item.clip_type === 4 ? 1 : 3;
|
|
18409
|
-
if (
|
|
18410
|
-
|
|
18583
|
+
if (!liveimgbgm) if (loopCount > 1) success = await loopVideo(liveimg.filepath, outputPath, loopCount);
|
|
18584
|
+
else {
|
|
18585
|
+
fs.renameSync(liveimg.filepath, outputPath);
|
|
18586
|
+
success = true;
|
|
18587
|
+
}
|
|
18588
|
+
else if (mergeMode === "continuous" && bgmContext) {
|
|
18589
|
+
const result = await mergeLiveImageContinuous({
|
|
18411
18590
|
videoPath: liveimg.filepath,
|
|
18412
18591
|
outputPath,
|
|
18413
18592
|
loopCount
|
|
18414
18593
|
}, bgmContext);
|
|
18415
18594
|
success = result.success;
|
|
18416
18595
|
bgmContext = result.context;
|
|
18417
|
-
} else success = await mergeLiveImageIndependent
|
|
18596
|
+
} else success = await mergeLiveImageIndependent({
|
|
18418
18597
|
videoPath: liveimg.filepath,
|
|
18419
18598
|
outputPath,
|
|
18420
18599
|
loopCount
|
|
18421
18600
|
}, liveimgbgm.filepath);
|
|
18422
18601
|
if (success) {
|
|
18423
|
-
const
|
|
18424
|
-
|
|
18425
|
-
fs$1.default.renameSync(outputPath, filePath);
|
|
18602
|
+
const filePath = Common.tempDri.video + `tmp_${Date.now()}.mp4`;
|
|
18603
|
+
fs.renameSync(outputPath, filePath);
|
|
18426
18604
|
logger.mark(`视频文件重命名完成: ${outputPath.split("/").pop()} -> ${filePath.split("/").pop()}`);
|
|
18427
18605
|
logger.mark("正在尝试删除缓存文件");
|
|
18428
|
-
await Common
|
|
18606
|
+
await Common.removeFile(liveimg.filepath, true);
|
|
18429
18607
|
temp.push({
|
|
18430
18608
|
filepath: filePath,
|
|
18431
18609
|
totalBytes: 0
|
|
18432
18610
|
});
|
|
18433
18611
|
images.push(segment.video("file://" + filePath));
|
|
18434
18612
|
if (item.clip_type === 5 && item.url_list?.[0]) images.push(segment.image(item.url_list[0]));
|
|
18435
|
-
} else await Common
|
|
18613
|
+
} else await Common.removeFile(liveimg.filepath, true);
|
|
18436
18614
|
}
|
|
18437
18615
|
}
|
|
18438
18616
|
const bot = karin$1.getBot(botId);
|
|
@@ -18447,30 +18625,27 @@ var DouYinpush = class extends Base {
|
|
|
18447
18625
|
} catch (error) {
|
|
18448
18626
|
logger.error(`发送合辑失败: ${error}`);
|
|
18449
18627
|
} finally {
|
|
18450
|
-
for (const item of temp)
|
|
18451
|
-
const { Common: Common$1 } = await init_utils$1().then(() => utils_exports);
|
|
18452
|
-
await Common$1.removeFile(item.filepath, true);
|
|
18453
|
-
}
|
|
18628
|
+
for (const item of temp) await Common.removeFile(item.filepath, true);
|
|
18454
18629
|
}
|
|
18455
|
-
} else if (Detail_Data.images) if (Detail_Data.images.some((item) => item.clip_type !== 2)) {
|
|
18630
|
+
} else if (Detail_Data.images) if (Detail_Data.images.some((item) => item.clip_type !== 2 && item.clip_type !== void 0)) {
|
|
18456
18631
|
const processedImages = [];
|
|
18457
18632
|
const temp = [];
|
|
18458
|
-
let
|
|
18459
|
-
if (Detail_Data.music.play_url.uri === "") mp3Path = JSON.parse(Detail_Data.music.extra).original_song_url;
|
|
18460
|
-
else mp3Path = Detail_Data.music.play_url.uri;
|
|
18461
|
-
const liveimgbgm = await downloadFile(mp3Path, {
|
|
18462
|
-
title: `Douyin_tmp_A_${Date.now()}.mp3`,
|
|
18463
|
-
headers: douyinBaseHeaders
|
|
18464
|
-
});
|
|
18465
|
-
temp.push(liveimgbgm);
|
|
18466
|
-
const mergeMode = Config.douyin.liveImageMergeMode ?? "independent";
|
|
18633
|
+
let liveimgbgm = null;
|
|
18467
18634
|
let bgmContext = null;
|
|
18468
|
-
|
|
18469
|
-
|
|
18470
|
-
|
|
18635
|
+
const mergeMode = Config.douyin.liveImageMergeMode ?? "independent";
|
|
18636
|
+
if (Detail_Data.music) {
|
|
18637
|
+
let mp3Path = "";
|
|
18638
|
+
if (Detail_Data.music.play_url.uri === "") mp3Path = JSON.parse(Detail_Data.music.extra).original_song_url;
|
|
18639
|
+
else mp3Path = Detail_Data.music.play_url.uri;
|
|
18640
|
+
liveimgbgm = await downloadFile(mp3Path, {
|
|
18641
|
+
title: `Douyin_tmp_A_${Date.now()}.mp3`,
|
|
18642
|
+
headers: douyinBaseHeaders
|
|
18643
|
+
});
|
|
18644
|
+
temp.push(liveimgbgm);
|
|
18645
|
+
if (mergeMode === "continuous") bgmContext = await createLiveImageContext(liveimgbgm.filepath);
|
|
18471
18646
|
}
|
|
18472
18647
|
for (const item of Detail_Data.images) {
|
|
18473
|
-
if (item.clip_type === 2) {
|
|
18648
|
+
if (item.clip_type === 2 || item.clip_type === void 0) {
|
|
18474
18649
|
const image_url = item.url_list[2] ?? item.url_list[1];
|
|
18475
18650
|
processedImages.push(segment.image(image_url));
|
|
18476
18651
|
continue;
|
|
@@ -18480,37 +18655,40 @@ var DouYinpush = class extends Base {
|
|
|
18480
18655
|
headers: douyinBaseHeaders
|
|
18481
18656
|
});
|
|
18482
18657
|
if (liveimg.filepath) {
|
|
18483
|
-
const
|
|
18484
|
-
const outputPath = Common$1.tempDri.video + `Douyin_Result_${Date.now()}.mp4`;
|
|
18658
|
+
const outputPath = Common.tempDri.video + `Douyin_Result_${Date.now()}.mp4`;
|
|
18485
18659
|
let success;
|
|
18486
18660
|
const loopCount = item.clip_type === 4 ? 1 : 3;
|
|
18487
|
-
if (
|
|
18488
|
-
|
|
18661
|
+
if (!liveimgbgm) if (loopCount > 1) success = await loopVideo(liveimg.filepath, outputPath, loopCount);
|
|
18662
|
+
else {
|
|
18663
|
+
fs.renameSync(liveimg.filepath, outputPath);
|
|
18664
|
+
success = true;
|
|
18665
|
+
}
|
|
18666
|
+
else if (mergeMode === "continuous" && bgmContext) {
|
|
18667
|
+
const result = await mergeLiveImageContinuous({
|
|
18489
18668
|
videoPath: liveimg.filepath,
|
|
18490
18669
|
outputPath,
|
|
18491
18670
|
loopCount
|
|
18492
18671
|
}, bgmContext);
|
|
18493
18672
|
success = result.success;
|
|
18494
18673
|
bgmContext = result.context;
|
|
18495
|
-
} else success = await mergeLiveImageIndependent
|
|
18674
|
+
} else success = await mergeLiveImageIndependent({
|
|
18496
18675
|
videoPath: liveimg.filepath,
|
|
18497
18676
|
outputPath,
|
|
18498
18677
|
loopCount
|
|
18499
18678
|
}, liveimgbgm.filepath);
|
|
18500
18679
|
if (success) {
|
|
18501
|
-
const
|
|
18502
|
-
|
|
18503
|
-
fs$1.default.renameSync(outputPath, filePath);
|
|
18680
|
+
const filePath = Common.tempDri.video + `tmp_${Date.now()}.mp4`;
|
|
18681
|
+
fs.renameSync(outputPath, filePath);
|
|
18504
18682
|
logger.mark(`视频文件重命名完成: ${outputPath.split("/").pop()} -> ${filePath.split("/").pop()}`);
|
|
18505
18683
|
logger.mark("正在尝试删除缓存文件");
|
|
18506
|
-
await Common
|
|
18684
|
+
await Common.removeFile(liveimg.filepath, true);
|
|
18507
18685
|
temp.push({
|
|
18508
18686
|
filepath: filePath,
|
|
18509
18687
|
totalBytes: 0
|
|
18510
18688
|
});
|
|
18511
18689
|
processedImages.push(segment.video("file://" + filePath));
|
|
18512
18690
|
if (item.clip_type === 5 && item.url_list?.[0]) processedImages.push(segment.image(item.url_list[0]));
|
|
18513
|
-
} else await Common
|
|
18691
|
+
} else await Common.removeFile(liveimg.filepath, true);
|
|
18514
18692
|
}
|
|
18515
18693
|
}
|
|
18516
18694
|
const bot = karin$1.getBot(botId);
|
|
@@ -18525,10 +18703,7 @@ var DouYinpush = class extends Base {
|
|
|
18525
18703
|
} catch (error) {
|
|
18526
18704
|
logger.error(`发送图集失败: ${error}`);
|
|
18527
18705
|
} finally {
|
|
18528
|
-
for (const item of temp)
|
|
18529
|
-
const { Common: Common$1 } = await init_utils$1().then(() => utils_exports);
|
|
18530
|
-
await Common$1.removeFile(item.filepath, true);
|
|
18531
|
-
}
|
|
18706
|
+
for (const item of temp) await Common.removeFile(item.filepath, true);
|
|
18532
18707
|
}
|
|
18533
18708
|
} else {
|
|
18534
18709
|
const imageres = [];
|
|
@@ -18553,8 +18728,6 @@ var DouYinpush = class extends Base {
|
|
|
18553
18728
|
}
|
|
18554
18729
|
}
|
|
18555
18730
|
if (skip || pushItem.pushType !== "live" && status.message_id) await douyinDBInstance.addAwemeCache(actualAwemeId, pushItem.sec_uid, groupId, pushItem.pushType);
|
|
18556
|
-
} catch (error) {
|
|
18557
|
-
throw new Error(`${error}`);
|
|
18558
18731
|
}
|
|
18559
18732
|
}
|
|
18560
18733
|
return true;
|
|
@@ -18938,11 +19111,6 @@ var Kuaishou = class extends Base {
|
|
|
18938
19111
|
this.type = iddata?.type;
|
|
18939
19112
|
}
|
|
18940
19113
|
async KuaishouHandler(data$1) {
|
|
18941
|
-
if (Config.app.EmojiReply) try {
|
|
18942
|
-
await this.e.bot.setMsgReaction(this.e.contact, this.e.messageId, Config.app.EmojiReplyID, true);
|
|
18943
|
-
} catch (err) {
|
|
18944
|
-
if (!Config.app.EmojiReplyIgnoreError) throw err;
|
|
18945
|
-
}
|
|
18946
19114
|
if (data$1.VideoData.data.data.visionVideoDetail.status !== 1) {
|
|
18947
19115
|
await this.e.reply("不支持解析的视频");
|
|
18948
19116
|
return true;
|
|
@@ -20019,11 +20187,6 @@ var Xiaohongshu = class extends Base {
|
|
|
20019
20187
|
this.type = iddata?.type;
|
|
20020
20188
|
}
|
|
20021
20189
|
async XiaohongshuHandler(data$1) {
|
|
20022
|
-
if (Config.app.EmojiReply && !this.e.isPrivate) try {
|
|
20023
|
-
await this.e.bot.setMsgReaction(this.e.contact, this.e.messageId, Config.app.EmojiReplyID, true);
|
|
20024
|
-
} catch (err) {
|
|
20025
|
-
if (!Config.app.EmojiReplyIgnoreError) throw err;
|
|
20026
|
-
}
|
|
20027
20190
|
Config.xiaohongshu.tip && await this.e.reply("检测到小红书链接,开始解析");
|
|
20028
20191
|
const NoteData = await this.amagi.xiaohongshu.fetcher.fetchNoteDetail({
|
|
20029
20192
|
typeMode: "strict",
|