Files
lxc-streamutils/docs/components/danmaku-overlay.md
T
2026-07-18 11:44:58 -07:00

82 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `danmaku_overlay` 弹幕姬
弹幕姬把一个租户直播源的互动事件投影为透明 OBS 消息墙。它是被动展示组件:不记账、不回复弹幕,也不把 WebSocket 当作持久化业务通道。
## 订阅事件
组件根据设置动态订阅:
- 弹幕、进房、礼物与礼物连击、醒目留言、舰长、点赞、分享。
- 关闭类别后,后端不为该组件投影对应事件,前端也会进行一次兼容性过滤。
- 未归一化的 `live.unknown` 默认不进入弹幕姬。
## 设置
| 字段 | 范围/单位 | 行为 |
| ------------------------ | ----------- | -------------------------- |
| `themeId` | 主题 ID | 选择已安装的完整视觉主题 |
| `fontScale` | 50–300% | 展开与收缩字号的统一比例 |
| `maxVisible` | 1–12 | 同时保留的消息卡数量 |
| `collapseAfterSeconds` | 2–120 秒 | 最新卡从展开态切换到紧凑态 |
| `unfoldDurationMs` | 200–5000 ms | 横向卷轴展开动画时间 |
| `motionIntensity` | 0–100% | 卡片、流光与焦点动画强度 |
| `particleCount` | 0–12 | 每卡星花粒子数量 |
| `particleSpeed` | 25–300% | 粒子动画速度 |
| `lowPerformanceMode` | boolean | 关闭高成本动态效果 |
| `highValueThreshold` | 千分之一元 | 高价值礼物起点 |
| `featuredValueThreshold` | 千分之一元 | 焦点礼物起点 |
| `show*` | boolean | 控制各事件类别订阅 |
后端的 `OverlaySettings::sanitize` 是最终边界。控制台 range input 只改善交互,不能取代服务端校验。
## 主题
主题同时封装配色、花纹素材、装饰变体、粒子组合与动画名称。当前内置主题为
`jade-scroll`(“青玉花卷”);控制台仍以选择框呈现,新增主题后无需改变设置交互或卡片队列。
增加主题时需要同步完成三处注册:
1. 在后端 `OverlayThemeId` 中增加稳定 ID,使未知主题无法进入数据库。
2. 在 `apps/overlay/src/themes/` 增加主题定义,并注册到 `overlayThemes`。
3. 提供主题使用的 CSS 动画和素材;不要在 `Card` 中加入按主题 ID 分支。
旧组件没有 `themeId` 时会自动使用
`jade-scroll`。WebSocket 收到未知 ID 时前端也会安全降级到该主题,以支持前后端滚动部署。
## 卡片生命周期
1. 新事件插入队首,以卷轴动画横向展开。
2. 用户名与内容在展开态分行显示,长内容完整换行。
3. 新事件到达或超时后,旧卡变成紧凑态;内容不会隐藏。
4. 紧凑态缩小字号并尽量压缩布局,但仍允许换行避免截断。
5. 超过 `maxVisible` 的最旧卡才会离开队列。
花纹由事件类型和事件 ID 的稳定 hash 选择。相邻卡会避开完全相同的款式;礼物连击更新沿用原卡片 key 和装饰,避免视觉跳动。
## 礼物展示
- `live.gift` 创建礼物卡;`live.gift.combo` 使用 `comboId` 更新同一张卡。
- 元数据优先使用礼物目录中的静态图、GIF、币种和价格。
- GIF 加载失败时降级为静态图片;静态图失败时隐藏图片但保留名称、数量和用户。
- 普通、高价值和焦点礼物按 `totalPrice` 与两个阈值分级。
- `priceCny` 只用于人类可读展示;整数 `totalPrice` 用于精确分级。
## 弹幕表情
文字和表情按 `segments` 顺序混排。表情 URL 来自消息本身或用户级表情目录补全;图片使用
`no-referrer`,失败后显示原始表情文字。整条大表情可通过 `standalone` 使用更合适的尺寸。
## OBS 自适应
- 根背景完全透明,不存在 1920×1080 固定画布。
- `ResizeObserver` 根据浏览器源实际宽高选择 `narrow`、`short` 或 `standard`。
- 字号和间距使用 CSS custom properties 与 `clamp()`,OBS 自由缩放时不拉伸素材比例。
- 建议从 `360×600`、`440×760`、`600×1080` 或 `720×320` 开始测试。
- 低高度会减少视觉密度,但不会把仍在队列中的文字裁成省略号。
## 测试页面
控制台的事件测试直接构造 canonical
`LiveEvent`,使用当前账户、source 和 component 走同一套订阅、handler、projection 与 EventHub。测试事件标记为
`simulated=true`,不会发送到 Bilibili,也不会跨组件广播。