karin-plugin-kkk 2.17.0 → 2.17.1

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +12 -33
  3. package/config/default_config/bilibili.yaml +3 -0
  4. package/config/default_config/douyin.yaml +3 -0
  5. package/lib/apps/admin.js +3 -3
  6. package/lib/apps/help.js +3 -3
  7. package/lib/apps/push.js +3 -3
  8. package/lib/apps/tools.js +3 -3
  9. package/lib/apps/update.js +3 -3
  10. package/lib/build-metadata.json +5 -5
  11. package/lib/core_chunk/{main-B6qdbnVO.js → main-BxTu7Wbh.js} +61 -23
  12. package/lib/core_chunk/{template-Ci1msqvx.js → template-DrnOcKSr.js} +2 -2
  13. package/lib/core_chunk/template.js +2 -2
  14. package/lib/core_chunk/{vendor-D-0Q6ngg.js → vendor-DZc1p0vy.js} +3311 -77864
  15. package/lib/index.js +3 -3
  16. package/lib/root.js +1 -1
  17. package/lib/web.config.js +3 -3
  18. package/lib/web_chunk/assets/{Combination-D6JXGGTb.js → Combination-CybkPeYp.js} +1 -1
  19. package/lib/web_chunk/assets/{avatar-CjFcJGt8.js → avatar-CIavEj6Z.js} +1 -1
  20. package/lib/web_chunk/assets/core-fpxat5AM.js +1 -0
  21. package/lib/web_chunk/assets/{eye-BFyOZNGS.js → eye-tiaDxD4R.js} +1 -1
  22. package/lib/web_chunk/assets/{index--B6lJk3P.js → index-Bgi7PLyU.js} +2 -2
  23. package/lib/web_chunk/assets/{jszip.min-B7JWsnv2.js → jszip.min-CegdXk4G.js} +1 -1
  24. package/lib/web_chunk/assets/{page-CH7ajvam.js → page-B17tpzlv.js} +2 -2
  25. package/lib/web_chunk/assets/{page-DuNzERvC.js → page-B8Feq-UP.js} +4 -4
  26. package/lib/web_chunk/assets/{page-sNz-Tj8J.js → page-Clh3TZcl.js} +1 -1
  27. package/lib/web_chunk/assets/{page-BgdAfy-I.js → page-MSqwrvfd.js} +1 -1
  28. package/lib/web_chunk/assets/{page-DHXQyRNq.js → page-v9dpKc7S.js} +1 -1
  29. package/lib/web_chunk/assets/{parsers-a4uEy6FM.js → parsers-BEX9UO0Q.js} +1 -1
  30. package/lib/web_chunk/assets/{request-B4eyTTZB.js → request-CzpA_IL5.js} +1 -1
  31. package/lib/web_chunk/assets/{select-BJ4mbpXJ.js → select-DLv3zXPA.js} +1 -1
  32. package/lib/web_chunk/assets/{separator-BJQKMZb1.js → separator-Cmfje7Mz.js} +1 -1
  33. package/lib/web_chunk/index.html +1 -1
  34. package/lib/web_chunk/sw.js +1 -1
  35. package/package.json +3 -2
  36. package/lib/web_chunk/assets/core-CvORP6Z4.js +0 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [2.17.1](https://github.com/ikenxuan/karin-plugin-kkk/compare/v2.17.0...v2.17.1) (2025-12-25)
6
+
7
+
8
+ ### 🐛 错误修复
9
+
10
+ * 提高兼容性 close [#237](https://github.com/ikenxuan/karin-plugin-kkk/issues/237) ([4d06880](https://github.com/ikenxuan/karin-plugin-kkk/commit/4d0688011380beec9c8f71fad294af84ae8eb13a))
11
+
12
+
13
+ ### 📝 文档更新
14
+
15
+ * readme ([1866817](https://github.com/ikenxuan/karin-plugin-kkk/commit/1866817e7f91bd686754e412b9578c4223949144))
16
+
17
+
18
+ ### 📦 依赖更新
19
+
20
+ * peerDependencies ([734e8d7](https://github.com/ikenxuan/karin-plugin-kkk/commit/734e8d7b86db22c97fee2380b51652106a968ef0))
21
+ * peerDependencies ([c93b686](https://github.com/ikenxuan/karin-plugin-kkk/commit/c93b686c7489190b9c4a30ca132fd3f39afa125a))
22
+
23
+
24
+ ### ✨ 细节优化
25
+
26
+ * 增加 `#弹幕解析` ([177017b](https://github.com/ikenxuan/karin-plugin-kkk/commit/177017b3396fe85dd79392ebf1e10e48e2c10ad0))
27
+ * 添加弹幕清晰度配置 ([2fc794c](https://github.com/ikenxuan/karin-plugin-kkk/commit/2fc794c3bd0c0509461b58cb44f63d86f1069e82))
28
+
5
29
  ## [2.17.0](https://github.com/ikenxuan/karin-plugin-kkk/compare/v2.16.0...v2.17.0) (2025-12-19)
6
30
 
7
31
 
package/README.md CHANGED
@@ -2,51 +2,30 @@
2
2
 
3
3
  # karin-plugin-kkk
4
4
 
5
- [![npm](https://img.shields.io/npm/v/karin-plugin-kkk?style=flat&logo=npm)](https://www.npmjs.com/package/karin-plugin-kkk)
6
- [![npm downloads](https://img.shields.io/npm/dw/karin-plugin-kkk?style=flat&logo=npm)](https://www.npmjs.com/package/karin-plugin-kkk)
7
- [![GitHub stars](https://img.shields.io/github/stars/ikenxuan/karin-plugin-kkk?style=flat&logo=github)](https://github.com/ikenxuan/karin-plugin-kkk)
8
- [![GitHub issues](https://img.shields.io/github/issues/ikenxuan/karin-plugin-kkk?style=flat&logo=github)](https://github.com/ikenxuan/karin-plugin-kkk/issues)
5
+ [![npm](https://img.shields.io/npm/v/karin-plugin-kkk?style=flat-square&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/karin-plugin-kkk)
6
+ [![downloads](https://img.shields.io/npm/dw/karin-plugin-kkk?style=flat-square&logo=npm&logoColor=white&color=CB3837)](https://www.npmjs.com/package/karin-plugin-kkk)
7
+ [![stars](https://img.shields.io/github/stars/ikenxuan/karin-plugin-kkk?style=flat-square&logo=github)](https://github.com/ikenxuan/karin-plugin-kkk)
8
+ [![license](https://img.shields.io/github/license/ikenxuan/karin-plugin-kkk?style=flat-square)](./LICENSE)
9
9
  [![pkg.pr.new](https://pkg.pr.new/badge/ikenxuan/karin-plugin-kkk)](https://pkg.pr.new/~/ikenxuan/karin-plugin-kkk)
10
10
 
11
- _Karin 的「抖音」「B 站」视频解析/动态推送插件_
11
+ Karin 的多平台短视频 & 图文内容解析推送插件,为群聊打造极致的媒体分享体验
12
12
 
13
- > 提供对 Bot 的视频解析和动态推送功能,通过接口获取数据并渲染图片返回
13
+ 自动识别分享链接 · 智能提取视频/图集/热评 · 精美的模板渲染 · 无需跳转即可浏览
14
14
 
15
- </div>
15
+ **开箱即用** · 配置 Cookie 即刻启程
16
16
 
17
17
  ---
18
18
 
19
- ## Feature
20
-
21
- - **视频解析** - 自动解析抖音、B站、快手、小红书链接
22
- - **动态推送** - 订阅博主/UP主,自动推送最新动态
23
- - **扫码登录** - 支持扫码获取平台 Cookies
24
- - **WebUI 配置** - 通过 Karin WebUI 轻松管理插件
25
-
26
- ## Quick Start
27
-
28
- 推荐通过 **Karin WebUI 插件市场** 安装,或使用命令:
29
-
30
- ```sh
31
- pnpm add karin-plugin-kkk@latest -w
32
- ```
33
-
34
- > 首次使用请务必查看文档了解配置方法
35
-
36
- ## Link
19
+ **📖 文档**
37
20
 
38
- <div align="center">
21
+ [![Vercel](https://img.shields.io/badge/Vercel-000000?style=for-the-badge&logo=vercel&logoColor=white)](https://karin-plugin-kkk-docs.vercel.app)
22
+ [![Netlify](https://img.shields.io/badge/Netlify-00C7B7?style=for-the-badge&logo=netlify&logoColor=white)](https://karin-plugin-kkk-docs.netlify.app)
39
23
 
40
- **📖 文档(国内)**
24
+ **📖 文档(中国大陆)**
41
25
 
42
26
  [![KarinJS](https://img.shields.io/badge/kkk.karinjs.com-FF6B6B?style=for-the-badge&logo=bookstack&logoColor=white)](https://kkk.karinjs.com)
43
27
  [![QWQO](https://img.shields.io/badge/kkk.qwqo.cn-845EF7?style=for-the-badge&logo=bookstack&logoColor=white)](https://kkk.qwqo.cn)
44
28
 
45
- **📖 文档(海外)**
46
-
47
- [![Vercel](https://img.shields.io/badge/Vercel-000000?style=for-the-badge&logo=vercel&logoColor=white)](https://karin-plugin-kkk-docs.vercel.app)
48
- [![Netlify](https://img.shields.io/badge/Netlify-00C7B7?style=for-the-badge&logo=netlify&logoColor=white)](https://karin-plugin-kkk-docs.netlify.app)
49
-
50
29
  **💬 交流**
51
30
 
52
31
  [![QQ Group](https://img.shields.io/badge/QQ_群-795874649-12B7F5?style=for-the-badge&logo=qq&logoColor=white)](https://qm.qq.com/q/DgLbCERYVG)
@@ -56,7 +35,7 @@ pnpm add karin-plugin-kkk@latest -w
56
35
 
57
36
  ## Thanks
58
37
 
59
- - [Karin](https://github.com/Karinjs/Karin) - 即时通讯 Bot 框架
38
+ - [Karin](https://github.com/Karinjs/Karin) - 即时通讯应用机器人框架
60
39
  - [amagi](https://github.com/ikenxuan/amagi) - 接口文档与加密参数算法
61
40
 
62
41
  ## Contributors
@@ -67,6 +67,9 @@ danmakuArea: 0.5
67
67
  # - 'large': 大号
68
68
  danmakuFontSize: 'medium'
69
69
 
70
+ # 弹幕透明度(0-100,0为完全透明,100为完全不透明,推荐70)
71
+ danmakuOpacity: 70
72
+
70
73
  # 竖屏适配(模拟手机端竖屏观看体验,视频居中,上下黑边显示弹幕)
71
74
  # - 'off': 关闭,保持原始视频比例
72
75
  # - 'standard': 智能模式,仅对 16:9、21:9 等常见宽屏比例生效
@@ -67,6 +67,9 @@ danmakuArea: 0.5
67
67
  # - 'large': 大号
68
68
  danmakuFontSize: 'medium'
69
69
 
70
+ # 弹幕透明度(0-100,0为完全透明,100为完全不透明,推荐70)
71
+ danmakuOpacity: 70
72
+
70
73
  # 横屏转竖屏模式(针对横屏视频,抖音大多是竖屏,此选项主要用于横屏视频)
71
74
  # - 'off': 关闭,保持原始比例
72
75
  # - 'standard': 智能模式,仅对宽高比 ≥1.7 的横屏视频转竖屏
package/lib/apps/admin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import "../core_chunk/vendor-D-0Q6ngg.js";
3
- import { C as setbilick, S as removeAllFiles, T as task, b as biLogin, w as setdyck, x as dylogin } from "../core_chunk/main-B6qdbnVO.js";
4
- import "../core_chunk/template-Ci1msqvx.js";
2
+ import "../core_chunk/vendor-DZc1p0vy.js";
3
+ import { C as setbilick, S as removeAllFiles, T as task, b as biLogin, w as setdyck, x as dylogin } from "../core_chunk/main-BxTu7Wbh.js";
4
+ import "../core_chunk/template-DrnOcKSr.js";
5
5
  export { biLogin, dylogin, removeAllFiles, setbilick, setdyck, task };
package/lib/apps/help.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import "../core_chunk/vendor-D-0Q6ngg.js";
3
- import { v as help, y as version } from "../core_chunk/main-B6qdbnVO.js";
4
- import "../core_chunk/template-Ci1msqvx.js";
2
+ import "../core_chunk/vendor-DZc1p0vy.js";
3
+ import { v as help, y as version } from "../core_chunk/main-BxTu7Wbh.js";
4
+ import "../core_chunk/template-DrnOcKSr.js";
5
5
  export { help, version };
package/lib/apps/push.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import "../core_chunk/vendor-D-0Q6ngg.js";
3
- import { _ as testDouyinPush, d as changeBotID, f as douyinPush, g as setdyPush, h as setbiliPush, l as bilibiliPush, m as forcePush, p as douyinPushList, u as bilibiliPushList } from "../core_chunk/main-B6qdbnVO.js";
4
- import "../core_chunk/template-Ci1msqvx.js";
2
+ import "../core_chunk/vendor-DZc1p0vy.js";
3
+ import { _ as testDouyinPush, d as changeBotID, f as douyinPush, g as setdyPush, h as setbiliPush, l as bilibiliPush, m as forcePush, p as douyinPushList, u as bilibiliPushList } from "../core_chunk/main-BxTu7Wbh.js";
4
+ import "../core_chunk/template-DrnOcKSr.js";
5
5
  export { bilibiliPush, bilibiliPushList, changeBotID, douyinPush, douyinPushList, forcePush, setbiliPush, setdyPush, testDouyinPush };
package/lib/apps/tools.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import "../core_chunk/vendor-D-0Q6ngg.js";
3
- import { a as douyinAPP, c as xiaohongshuAPP, i as bilibiliAPP, o as kuaishouAPP, s as prefix } from "../core_chunk/main-B6qdbnVO.js";
4
- import "../core_chunk/template-Ci1msqvx.js";
2
+ import "../core_chunk/vendor-DZc1p0vy.js";
3
+ import { a as douyinAPP, c as xiaohongshuAPP, i as bilibiliAPP, o as kuaishouAPP, s as prefix } from "../core_chunk/main-BxTu7Wbh.js";
4
+ import "../core_chunk/template-DrnOcKSr.js";
5
5
  export { bilibiliAPP, douyinAPP, kuaishouAPP, prefix, xiaohongshuAPP };
@@ -1,5 +1,5 @@
1
1
  import "../core_chunk/rolldown-runtime-BMXAG3ag.js";
2
- import "../core_chunk/vendor-D-0Q6ngg.js";
3
- import { n as kkkUpdateCommand, r as update, t as kkkUpdate } from "../core_chunk/main-B6qdbnVO.js";
4
- import "../core_chunk/template-Ci1msqvx.js";
2
+ import "../core_chunk/vendor-DZc1p0vy.js";
3
+ import { n as kkkUpdateCommand, r as update, t as kkkUpdate } from "../core_chunk/main-BxTu7Wbh.js";
4
+ import "../core_chunk/template-DrnOcKSr.js";
5
5
  export { kkkUpdate, kkkUpdateCommand, update };
@@ -1,10 +1,10 @@
1
1
  {
2
- "version": "2.17.0",
3
- "buildTime": "2025-12-19T02:28:16.910Z",
4
- "buildTimestamp": 1766111296911,
2
+ "version": "2.17.1",
3
+ "buildTime": "2025-12-25T07:54:34.036Z",
4
+ "buildTimestamp": 1766649274036,
5
5
  "name": "karin-plugin-kkk",
6
6
  "description": "Karin 的「抖音」「B 站」视频解析/动态推送插件",
7
7
  "homepage": "https://github.com/ikenxuan/karin-plugin-kkk",
8
- "commitHash": "d8c0c8d03af5f2ed750a8a8743715ae8884e4bbd",
9
- "shortCommitHash": "d8c0c8d0"
8
+ "commitHash": "77c1280d326b58f98ace7399d635ffc79e0f5afe",
9
+ "shortCommitHash": "77c1280d"
10
10
  }
@@ -1,10 +1,10 @@
1
1
  import { n as __esmMin, o as __toESM, r as __export } from "./rolldown-runtime-BMXAG3ag.js";
2
- import { A as formatDistanceToNow, Bt as Xhshow, Gt as init_axios, Ht as init_zod, Jt as init_dist, Kt as axios_default, M as differenceInSeconds, O as init_date_fns, Rt as require_express, T as zhCN, Ut as zod_default, Vt as init_esm, Wt as AxiosError$1, Xt as init_source, Yt as Chalk, a as require_lib, c as Window, i as require_lib$1, j as format, k as fromUnixTime, n as require_heic_convert, o as require_qr_code_styling, qt as dist_exports, r as require_dist, s as init_lib, t as snapka, w as init_locale, zt as require_protobufjs } from "./vendor-D-0Q6ngg.js";
3
- import { n as init_client, r as reactServerRender } from "./template-Ci1msqvx.js";
2
+ import { A as format, Bt as init_esm, C as init_locale, D as init_date_fns, Gt as axios_default, Ht as zod_default, Jt as Chalk, Kt as dist_exports, Lt as require_express, O as fromUnixTime, Rt as require_protobufjs, Ut as AxiosError$1, Vt as init_zod, Wt as init_axios, Yt as init_source, a as require_qr_code_styling, i as require_lib, j as differenceInSeconds, k as formatDistanceToNow, n as require_dist, o as init_lib, qt as init_dist, r as require_lib$1, s as Window, t as require_heic_convert, w as zhCN, zt as Xhshow } from "./vendor-DZc1p0vy.js";
3
+ import { n as init_client, r as reactServerRender } from "./template-DrnOcKSr.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";
7
- import path, { dirname, resolve } from "node:path";
7
+ import path, { resolve } from "node:path";
8
8
  import url, { fileURLToPath } from "node:url";
9
9
  import os, { platform } from "node:os";
10
10
  import crypto from "node:crypto";
@@ -17,6 +17,7 @@ import axios, { AxiosError } from "node-karin/axios";
17
17
  import express from "node-karin/express";
18
18
  import template from "node-karin/template";
19
19
  import _ from "node-karin/lodash";
20
+ import { snapka } from "@snapka/puppeteer";
20
21
  import { newInjectedPage } from "fingerprint-injector";
21
22
  var getLog4js, log4jsPromise, getPackageLogsPath, logsPath, getLogLevel, currentLogLevel, initLogger, CustomLogger, logger$1, httpLogger, logMiddleware;
22
23
  var init_logger = __esmMin(() => {
@@ -5314,7 +5315,7 @@ async function getFrameRate$1(path$1) {
5314
5315
  return 30;
5315
5316
  }
5316
5317
  function generateBiliASS(danmakuList, width, height, options = {}) {
5317
- const { scrollTime = 8, opacity = 180, fontName = "Microsoft YaHei", danmakuArea = .5, danmakuFontSize = "medium" } = options;
5318
+ const { scrollTime = 8, danmakuOpacity = 70, fontName = "Microsoft YaHei", danmakuArea = .5, danmakuFontSize = "medium" } = options;
5318
5319
  const fontScale = height / 1080;
5319
5320
  const sizeConfig = FONT_SIZE_MAP$1[danmakuFontSize];
5320
5321
  const fontSize = Math.round(sizeConfig.base * fontScale);
@@ -5325,7 +5326,7 @@ function generateBiliASS(danmakuList, width, height, options = {}) {
5325
5326
  const trackCount = Math.max(1, Math.floor((areaHeight - fontSize) / trackH));
5326
5327
  const fixedTrackCount = trackCount;
5327
5328
  const minGap = Math.round(10 * fontScale);
5328
- const alpha = (255 - opacity).toString(16).padStart(2, "0").toUpperCase();
5329
+ const alpha = Math.round((100 - Math.max(0, Math.min(100, danmakuOpacity))) * 2.55).toString(16).padStart(2, "0").toUpperCase();
5329
5330
  let ass = `[Script Info]\nTitle: Bilibili Danmaku\nScriptType: v4.00+\nPlayResX: ${width}\nPlayResY: ${height}\nTimer: 100.0000\n\n[V4+ Styles]\nFormat: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\nStyle: Scroll,${fontName},${fontSize},&H${alpha}FFFFFF,&H${alpha}FFFFFF,&H${alpha}000000,&H${alpha}000000,0,0,0,0,100,100,0,0,1,1,0,2,0,0,0,1\nStyle: Top,${fontName},${fontSize},&H${alpha}FFFFFF,&H${alpha}FFFFFF,&H${alpha}000000,&H${alpha}000000,0,0,0,0,100,100,0,0,1,1,0,8,0,0,0,1\nStyle: Bottom,${fontName},${fontSize},&H${alpha}FFFFFF,&H${alpha}FFFFFF,&H${alpha}000000,&H${alpha}000000,0,0,0,0,100,100,0,0,1,1,0,2,0,0,0,1\n\n[Events]\nFormat: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n`;
5330
5331
  const scrollTracks = Array(trackCount).fill(null);
5331
5332
  const topTracks = Array(fixedTrackCount).fill(0);
@@ -5681,7 +5682,7 @@ async function getFrameRate(path$1) {
5681
5682
  return 30;
5682
5683
  }
5683
5684
  function generateDouyinASS(danmakuList, width, height, options = {}) {
5684
- const { scrollTime = 8, opacity = 180, fontName = "Microsoft YaHei", danmakuArea = .5, danmakuFontSize = "medium" } = options;
5685
+ const { scrollTime = 8, danmakuOpacity = 70, fontName = "Microsoft YaHei", danmakuArea = .5, danmakuFontSize = "medium" } = options;
5685
5686
  const fontScale = height / 1080;
5686
5687
  const sizeConfig = FONT_SIZE_MAP[danmakuFontSize];
5687
5688
  const fontSize = Math.round(sizeConfig.base * fontScale);
@@ -5690,7 +5691,7 @@ function generateDouyinASS(danmakuList, width, height, options = {}) {
5690
5691
  const areaHeight = Math.floor(height * danmakuArea) - topMargin;
5691
5692
  const trackCount = Math.max(1, Math.floor((areaHeight - fontSize) / trackH));
5692
5693
  const minGap = Math.round(15 * fontScale);
5693
- const alpha = (255 - opacity).toString(16).padStart(2, "0").toUpperCase();
5694
+ const alpha = Math.round((100 - Math.max(0, Math.min(100, danmakuOpacity))) * 2.55).toString(16).padStart(2, "0").toUpperCase();
5694
5695
  let ass = `[Script Info]\nTitle: Douyin Danmaku\nScriptType: v4.00+\nPlayResX: ${width}\nPlayResY: ${height}\nTimer: 100.0000\n\n[V4+ Styles]\nFormat: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\nStyle: Scroll,${fontName},${fontSize},&H${alpha}FFFFFF,&H${alpha}FFFFFF,&H${alpha}000000,&H${alpha}000000,0,0,0,0,100,100,0,0,1,0.8,0,2,0,0,0,1\n\n[Events]\nFormat: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n`;
5695
5696
  const scrollTracks = Array(trackCount).fill(null);
5696
5697
  const calcDistance = (last, startTime, duration, textWidth) => {
@@ -8428,7 +8429,7 @@ var init_setup = __esmMin(async () => {
8428
8429
  });
8429
8430
  await init_module();
8430
8431
  await init_semver();
8431
- var requireVersion = "1.14.0";
8432
+ var requireVersion = "1.14.1";
8432
8433
  if (process.env.NODE_ENV !== "development" && isSemverGreater(requireVersion, Root.karinVersion)) {
8433
8434
  const msg = `[karin-plugin-kkk] 插件构建时的 karin 版本 (${requireVersion}) 高于当前运行版本 (${Root.karinVersion}),可能会出现兼容性问题!`;
8434
8435
  logger.warn(msg);
@@ -8757,6 +8758,16 @@ const BilibiliWeb = (all) => [components.accordion.create("bilibili", {
8757
8758
  })
8758
8759
  ]
8759
8760
  }),
8761
+ components.input.number("danmakuOpacity", {
8762
+ label: "弹幕透明度",
8763
+ description: "0为完全透明,100为完全不透明,推荐70",
8764
+ defaultValue: all.bilibili.danmakuOpacity.toString(),
8765
+ isDisabled: !all.bilibili.switch || !all.bilibili.burnDanmaku,
8766
+ rules: [{
8767
+ min: 0,
8768
+ max: 100
8769
+ }]
8770
+ }),
8760
8771
  components.radio.group("verticalMode", {
8761
8772
  label: "竖屏适配",
8762
8773
  description: "模拟手机端竖屏观看体验,视频居中显示,上下黑边区域用于展示弹幕",
@@ -9214,6 +9225,16 @@ const DouyinWeb = (all) => [components.accordion.create("douyin", {
9214
9225
  })
9215
9226
  ]
9216
9227
  }),
9228
+ components.input.number("danmakuOpacity", {
9229
+ label: "弹幕透明度",
9230
+ description: "0为完全透明,100为完全不透明,推荐70",
9231
+ defaultValue: all.douyin.danmakuOpacity.toString(),
9232
+ isDisabled: !all.douyin.switch || !all.douyin.burnDanmaku,
9233
+ rules: [{
9234
+ min: 0,
9235
+ max: 100
9236
+ }]
9237
+ }),
9217
9238
  components.radio.group("verticalMode", {
9218
9239
  label: "竖屏适配",
9219
9240
  description: "针对横屏视频,模拟手机端竖屏观看体验,视频居中显示,上下黑边区域用于展示弹幕",
@@ -10257,16 +10278,18 @@ var Bilibili = class extends Base {
10257
10278
  Type;
10258
10279
  islogin;
10259
10280
  downloadfilename;
10281
+ forceBurnDanmaku;
10260
10282
  get botadapter() {
10261
10283
  return this.e.bot?.adapter?.name;
10262
10284
  }
10263
- constructor(e, data$1) {
10285
+ constructor(e, data$1, options) {
10264
10286
  super(e);
10265
10287
  this.e = e;
10266
10288
  this.isVIP = false;
10267
10289
  this.Type = data$1?.type;
10268
10290
  this.islogin = data$1?.USER?.STATUS === "isLogin";
10269
10291
  this.downloadfilename = "";
10292
+ this.forceBurnDanmaku = options?.forceBurnDanmaku ?? false;
10270
10293
  this.headers.Referer = "https://api.bilibili.com/";
10271
10294
  this.headers.Cookie = Config.cookies.bilibili;
10272
10295
  }
@@ -10367,7 +10390,7 @@ var Bilibili = class extends Base {
10367
10390
  else {
10368
10391
  if (Config.bilibili.videoQuality !== 0 && Config.bilibili.videoQuality < 64) this.islogin = false;
10369
10392
  let danmakuList = [];
10370
- if (Config.bilibili.burnDanmaku) try {
10393
+ if (this.forceBurnDanmaku || Config.bilibili.burnDanmaku) try {
10371
10394
  const cid = iddata.p ? infoData.data.data.pages[iddata.p - 1]?.cid ?? infoData.data.data.cid : infoData.data.data.cid;
10372
10395
  const duration = iddata.p ? infoData.data.data.pages[iddata.p - 1]?.duration ?? infoData.data.data.duration : infoData.data.data.duration;
10373
10396
  const segmentCount = Math.ceil(duration / 360);
@@ -10815,7 +10838,7 @@ var Bilibili = class extends Base {
10815
10838
  headers: this.headers
10816
10839
  });
10817
10840
  if (bmp4.filepath && bmp3.filepath) {
10818
- const hasDanmaku = Config.bilibili.burnDanmaku && danmakuList.length > 0;
10841
+ const hasDanmaku = (this.forceBurnDanmaku || Config.bilibili.burnDanmaku) && danmakuList.length > 0;
10819
10842
  const resultPath = Common.tempDri.video + `Bil_Result_${this.Type === "one_video" ? infoData && infoData.data.bvid : infoData && infoData.result.season_id}.mp4`;
10820
10843
  let success;
10821
10844
  if (hasDanmaku) {
@@ -10824,7 +10847,8 @@ var Bilibili = class extends Base {
10824
10847
  danmakuArea: Config.bilibili.danmakuArea,
10825
10848
  verticalMode: Config.bilibili.verticalMode,
10826
10849
  videoCodec: Config.bilibili.videoCodec,
10827
- danmakuFontSize: Config.bilibili.danmakuFontSize
10850
+ danmakuFontSize: Config.bilibili.danmakuFontSize,
10851
+ danmakuOpacity: Config.bilibili.danmakuOpacity
10828
10852
  });
10829
10853
  } else success = await mergeVideoAudio(bmp4.filepath, bmp3.filepath, resultPath);
10830
10854
  if (success) {
@@ -10855,7 +10879,7 @@ var Bilibili = class extends Base {
10855
10879
  }
10856
10880
  case false:
10857
10881
  logger.debug("视频 URL:", playUrlData.durl[0].url);
10858
- if (Config.bilibili.burnDanmaku && danmakuList.length > 0) {
10882
+ if ((this.forceBurnDanmaku || Config.bilibili.burnDanmaku) && danmakuList.length > 0) {
10859
10883
  const videoFile = await downloadFile(playUrlData.durl[0].url, {
10860
10884
  title: `Bil_V_tmp_${Date.now()}.mp4`,
10861
10885
  headers: this.headers
@@ -10867,7 +10891,8 @@ var Bilibili = class extends Base {
10867
10891
  danmakuArea: Config.bilibili.danmakuArea,
10868
10892
  verticalMode: Config.bilibili.verticalMode,
10869
10893
  videoCodec: Config.bilibili.videoCodec,
10870
- danmakuFontSize: Config.bilibili.danmakuFontSize
10894
+ danmakuFontSize: Config.bilibili.danmakuFontSize,
10895
+ danmakuOpacity: Config.bilibili.danmakuOpacity
10871
10896
  })) {
10872
10897
  const filePath = Common.tempDri.video + `${Config.app.removeCache ? "tmp_" + Date.now() : this.downloadfilename}.mp4`;
10873
10898
  fs.renameSync(resultPath, filePath);
@@ -12341,15 +12366,17 @@ var DouYin = class extends Base {
12341
12366
  type;
12342
12367
  is_mp4;
12343
12368
  is_slides;
12369
+ forceBurnDanmaku;
12344
12370
  get botadapter() {
12345
12371
  return this.e.bot?.adapter?.name;
12346
12372
  }
12347
- constructor(e, iddata) {
12373
+ constructor(e, iddata, options) {
12348
12374
  super(e);
12349
12375
  this.e = e;
12350
12376
  this.type = iddata?.type;
12351
12377
  this.is_mp4 = iddata?.is_mp4;
12352
12378
  this.is_slides = false;
12379
+ this.forceBurnDanmaku = options?.forceBurnDanmaku ?? false;
12353
12380
  }
12354
12381
  async DouyinHandler(data$1) {
12355
12382
  Config.app.EmojiReply && !this.e.isPrivate && await this.e.bot.setMsgReaction(this.e.contact, this.e.messageId, Config.app.EmojiReplyID, true);
@@ -12571,7 +12598,7 @@ var DouYin = class extends Base {
12571
12598
  }
12572
12599
  if (this.is_mp4 && Config.douyin.sendContent.includes("video")) {
12573
12600
  let danmakuList = [];
12574
- if (Config.douyin.burnDanmaku && video) try {
12601
+ if ((this.forceBurnDanmaku || Config.douyin.burnDanmaku) && video) try {
12575
12602
  const duration = video.duration;
12576
12603
  logger.debug(`[抖音] 视频时长: ${duration}ms, 开始获取弹幕数据`);
12577
12604
  const danmakuData = await this.amagi.getDouyinData("弹幕数据", {
@@ -12586,7 +12613,7 @@ var DouYin = class extends Base {
12586
12613
  } catch (err) {
12587
12614
  logger.warn("[抖音] 获取弹幕失败,将不烧录弹幕", err);
12588
12615
  }
12589
- if (Config.douyin.burnDanmaku && danmakuList.length > 0) {
12616
+ if ((this.forceBurnDanmaku || Config.douyin.burnDanmaku) && danmakuList.length > 0) {
12590
12617
  const videoFile = await downloadFile(g_video_url, {
12591
12618
  title: `Douyin_V_tmp_${Date.now()}.mp4`,
12592
12619
  headers: {
@@ -12601,7 +12628,8 @@ var DouYin = class extends Base {
12601
12628
  danmakuArea: Config.douyin.danmakuArea,
12602
12629
  verticalMode: Config.douyin.verticalMode,
12603
12630
  videoCodec: Config.douyin.videoCodec,
12604
- danmakuFontSize: Config.douyin.danmakuFontSize
12631
+ danmakuFontSize: Config.douyin.danmakuFontSize,
12632
+ danmakuOpacity: Config.douyin.danmakuOpacity
12605
12633
  })) {
12606
12634
  const filePath = Common.tempDri.video + `${Config.app.removeCache ? "tmp_" + Date.now() : g_title}.mp4`;
12607
12635
  fs.renameSync(resultPath, filePath);
@@ -14185,8 +14213,14 @@ var handleTestDouyinPush = wrapWithErrorHandler(async (e) => {
14185
14213
  e.reply(img$2);
14186
14214
  return true;
14187
14215
  }, { businessName: "测试抖音推送" });
14188
- const douyinPush = Config.douyin.push.switch && karin$1.task("抖音推送", Config.douyin.push.cron, handleDouyinPush, { log: Config.douyin.push.log });
14189
- const bilibiliPush = Config.bilibili.push.switch && karin$1.task("B站推送", Config.bilibili.push.cron, handleBilibiliPush, { log: Config.bilibili.push.log });
14216
+ const douyinPush = Config.douyin.push.switch && karin$1.task("抖音推送", Config.douyin.push.cron, handleDouyinPush, {
14217
+ log: Config.douyin.push.log,
14218
+ type: "skip"
14219
+ });
14220
+ const bilibiliPush = Config.bilibili.push.switch && karin$1.task("B站推送", Config.bilibili.push.cron, handleBilibiliPush, {
14221
+ log: Config.bilibili.push.log,
14222
+ type: "skip"
14223
+ });
14190
14224
  const forcePush = karin$1.command(/#(抖音|B站)(全部)?强制推送/, handleForcePush, {
14191
14225
  name: "𝑪𝒊𝒂𝒍𝒍𝒐~(∠・ω< )⌒★",
14192
14226
  perm: "master",
@@ -14619,17 +14653,19 @@ var reg = {
14619
14653
  };
14620
14654
  var handleDouyin = wrapWithErrorHandler(async (e) => {
14621
14655
  if (e.msg.startsWith("#测试")) return false;
14656
+ const forceBurnDanmaku = /^#?弹幕解析/.test(e.msg);
14622
14657
  const urlMatch = e.msg.match(/(https?:\/\/[^\s]*\.(douyin|iesdouyin)\.com[^\s]*)/gi);
14623
14658
  if (!urlMatch) {
14624
14659
  logger.warn(`未能在消息中找到有效的抖音链接: ${e.msg}`);
14625
14660
  return true;
14626
14661
  }
14627
14662
  const iddata = await getDouyinID(e, String(urlMatch[0]));
14628
- await new DouYin(e, iddata).DouyinHandler(iddata);
14663
+ await new DouYin(e, iddata, { forceBurnDanmaku }).DouyinHandler(iddata);
14629
14664
  return true;
14630
14665
  }, { businessName: "抖音视频解析" });
14631
14666
  var handleBilibili = wrapWithErrorHandler(async (e) => {
14632
14667
  e.msg = e.msg.replace(/\\/g, "");
14668
+ const forceBurnDanmaku = /^#?弹幕解析/.test(e.msg);
14633
14669
  const urlRegex = /(https?:\/\/(?:(?:www\.|m\.|t\.)?bilibili\.com|b23\.tv|bili2233\.cn)\/[a-zA-Z0-9_\-.~:\/?#[\]@!$&'()*+,;=]+)/;
14634
14670
  const bvRegex = /^BV[1-9a-zA-Z]{10}$/;
14635
14671
  const avRegex = /^av\d+$/i;
@@ -14643,7 +14679,7 @@ var handleBilibili = wrapWithErrorHandler(async (e) => {
14643
14679
  return true;
14644
14680
  }
14645
14681
  const iddata = await getBilibiliID(url$1);
14646
- await new Bilibili(e, iddata).BilibiliHandler(iddata);
14682
+ await new Bilibili(e, iddata, { forceBurnDanmaku }).BilibiliHandler(iddata);
14647
14683
  return true;
14648
14684
  }, { businessName: "B站视频解析" });
14649
14685
  var handleKuaishou = wrapWithErrorHandler(async (e) => {
@@ -14663,7 +14699,9 @@ var handleXiaohongshu = wrapWithErrorHandler(async (e) => {
14663
14699
  return true;
14664
14700
  }, { businessName: "小红书视频解析" });
14665
14701
  var handlePrefix = wrapWithErrorHandler(async (e, next) => {
14702
+ const originalMsg = e.msg;
14666
14703
  e.msg = await Common.getReplyMessage(e);
14704
+ if (/^#?弹幕解析/.test(originalMsg)) e.msg = "#弹幕解析 " + e.msg;
14667
14705
  if (reg.douyin.test(e.msg)) return await handleDouyin(e, next);
14668
14706
  else if (reg.bilibili.test(e.msg)) return await handleBilibili(e, next);
14669
14707
  else if (reg.kuaishou.test(e.msg)) return await handleKuaishou(e, next);
@@ -14685,7 +14723,7 @@ var xiaohongshu = karin$1.command(reg.xiaohongshu, handleXiaohongshu, {
14685
14723
  name: "kkk-视频功能-小红书",
14686
14724
  priority: Config.app.videoTool ? -Infinity : 800
14687
14725
  });
14688
- const prefix = karin$1.command(/^#?(解析|kkk解析)/, handlePrefix, { name: "kkk-视频功能-引用解析" });
14726
+ const prefix = karin$1.command(/^#?(解析|kkk解析|弹幕解析)/, handlePrefix, { name: "kkk-视频功能-引用解析" });
14689
14727
  const douyinAPP = Config.douyin.switch && douyin;
14690
14728
  const bilibiliAPP = Config.bilibili.switch && bilibili;
14691
14729
  const kuaishouAPP = Config.kuaishou.switch && kuaishou;
@@ -1,5 +1,5 @@
1
1
  import { n as __esmMin, o as __toESM, r as __export } from "./rolldown-runtime-BMXAG3ag.js";
2
- import { $ as Share2, A as formatDistanceToNow, At as Bot, B as init_io5, C as init_ai, Ct as Clock, D as init_lu, Dt as CircleCheckBig, E as LuFullscreen, Et as CircleEllipsis, F as chip_default, Ft as init_clsx, G as UserPlus, H as Zap, I as button_default, It as require_server_node, J as ThumbsUp, K as TriangleAlert, L as HeroUIProvider, Lt as require_react, Mt as BookOpen, N as init_dist, Nt as Bell, O as init_date_fns, Ot as CircleAlert, P as code_default, Pt as clsx_default, Q as Shield, R as require_jsx_runtime, S as AiFillStar, St as Code, T as zhCN, Tt as CircleFadingArrowUp, U as Users, V as init_lucide_react, W as User, X as Star, Y as Terminal, Z as Sparkles, _ as FaBug, _t as Eye, at as Plug2, b as init_fa6, bt as CornerDownLeft, ct as MessageCircle, d as init_react_markdown, dt as List, et as Send, f as Markdown, ft as Link, g as init_ri, gt as FileText, h as RiShareForwardFill, ht as Hash, it as Power, j as format, jt as Bookmark, kt as Calendar, l as init_rehype_highlight, lt as MapPin, m as init_md, mt as Heart, nt as Radio, ot as Play, p as MdAccessTime, pt as Info, q as TrendingUp, rt as QrCode, st as Music, tt as RefreshCw, u as rehypeHighlight, ut as LogIn, v as FaCodeBranch, vt as ExternalLink, w as init_locale, wt as CircleQuestionMark, x as AiFillHeart, xt as Coins, y as FaCommentDots, yt as Crown, z as IoSearch } from "./vendor-D-0Q6ngg.js";
2
+ import { $ as Send, A as format, At as Bookmark, B as init_lucide_react, C as init_locale, Ct as CircleQuestionMark, D as init_date_fns, Dt as CircleAlert, E as init_lu, Et as CircleCheckBig, F as button_default, Ft as require_server_node, G as TriangleAlert, H as Users, I as HeroUIProvider, It as require_react, J as Terminal, K as TrendingUp, L as require_jsx_runtime, M as init_dist, Mt as Bell, N as code_default, Nt as clsx_default, Ot as Calendar, P as chip_default, Pt as init_clsx, Q as Share2, R as IoSearch, S as init_ai, St as Clock, T as LuFullscreen, Tt as CircleEllipsis, U as User, V as Zap, W as UserPlus, X as Sparkles, Y as Star, Z as Shield, _ as FaCodeBranch, _t as ExternalLink, at as Play, b as AiFillHeart, bt as Coins, c as init_rehype_highlight, ct as MapPin, d as Markdown, dt as Link, et as RefreshCw, f as MdAccessTime, ft as Info, g as FaBug, gt as Eye, h as init_ri, ht as FileText, it as Plug2, jt as BookOpen, k as formatDistanceToNow, kt as Bot, l as rehypeHighlight, lt as LogIn, m as RiShareForwardFill, mt as Hash, nt as QrCode, ot as Music, p as init_md, pt as Heart, q as ThumbsUp, rt as Power, st as MessageCircle, tt as Radio, u as init_react_markdown, ut as List, v as FaCommentDots, vt as Crown, w as zhCN, wt as CircleFadingArrowUp, x as AiFillStar, xt as Code, y as init_fa6, yt as CornerDownLeft, z as init_io5 } from "./vendor-DZc1p0vy.js";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import url, { fileURLToPath } from "node:url";
@@ -6962,7 +6962,7 @@ var init_handlerError = __esmMin(() => {
6962
6962
  className: "w-18 h-17"
6963
6963
  }), (0, import_jsx_runtime$2.jsxs)("div", { children: [(0, import_jsx_runtime$2.jsx)("div", {
6964
6964
  className: "text-2xl text-default-400",
6965
- children: "解析库版本"
6965
+ children: "接口库版本"
6966
6966
  }), (0, import_jsx_runtime$2.jsx)("div", {
6967
6967
  className: "text-4xl font-bold text-foreground",
6968
6968
  children: amagiVersion
@@ -1,4 +1,4 @@
1
1
  import "./rolldown-runtime-BMXAG3ag.js";
2
- import "./vendor-D-0Q6ngg.js";
3
- import { r as reactServerRender, t as template_default } from "./template-Ci1msqvx.js";
2
+ import "./vendor-DZc1p0vy.js";
3
+ import { r as reactServerRender, t as template_default } from "./template-DrnOcKSr.js";
4
4
  export { template_default as default, reactServerRender };