Eric
|
2120d1a0d0
|
Merge pull request #1212 from Joftal/dev
feat(live/sooplive,recorders,configs,servers): Soop 取流降请求与密码出口封堵
|
2026-09-30 18:44:42 +08:00 |
|
Joftal
|
8683fcf37f
|
fix(webapp): 明文配置页补一条快照过期提示
明文页展示的是打开那一刻的配置快照,而后台会在运行中续期各平台 Cookie。掩码字段
(如 Soop 密码)保存时始终沿用服务器上的最新原文,不受快照影响;Cookie 则是按
"这条与服务器当前值是否一致"判断用户有没有改过,拿着过期快照保存会把期间刚续好的
新值当成用户手写的旧改动顶回去。合并逻辑本身不改,只把风险与"刷新会覆盖未保存修改"
一并写在页面上。
|
2026-09-30 18:30:44 +08:00 |
|
Joftal
|
a6286fd631
|
fix(live/sooplive): 自动登录冷却期内直接采用配置里已刷新的 Cookie
同账号多个房间共用 10 分钟自动登录冷却:房间 A 刚登录成功并把新 Cookie 写进配置后,
房间 B 这一路根本没发登录请求就被冷却挡住,只能继续举着自家的旧运行态干等下一个窗口,
19+ 私有房间整段录不上。
改为区分"被冷却挡住"与"登录确实失败"(新增哨兵错误 errAutoLoginCoolingDown),前者先
校验配置里那份 Cookie,可用就立即采用;与自家运行态相同则跳过,不重复敲校验接口,
校验结果本身也有 2 分钟缓存。Soop 账号密码是全局唯一一份,不存在跨账号串号,
因此不加 LoginID 守卫。配置里那份同样不可用时保持原冷却错误与运行态不变。
|
2026-09-30 18:30:35 +08:00 |
|
Joftal
|
d40f034a97
|
fix(recorders): 延迟解析的四处静默失效与分段重启退避回退
- 本轮偏好改为在尝试开头取一次并固定下来:延迟解析要跑几百毫秒的平台请求,期间面板
"切换清晰度"改的就是这个值,最终选择若重读全局配置会按两套偏好算,选中根本没解析过
播放地址的那一路
- 选中的候选没有 Url 时带原因退出,不再在持有 currentFileLock 的情况下解引用空 URL:
panic 被 goroutine 边界 recover 后写锁永不释放,面板查房间状态的读请求会全部挂住,
表现成整个房间无响应而不是报错
- 全部候选解析失败不再回退全量解析:那等于同一次尝试里把每档的凭证与调度请求再敲一遍,
而"全部失败"恰恰是最需要少发请求的状态;改为把第一档原因上抛,由 run() 的退避拉长间隔
- 解析途中房间才显示下播时,ErrLiveOffline 立即上抛交给 stopRetryForExplicitOffline,
不再继续敲剩余档位,也不会让 recorder 卡在"录制准备中"反复重试
- TransferPipelineState 的 everHeldStream 改为单调或:新分段先被 Start,等转移执行时它
自己可能已经录上过,无条件覆盖会把这份成功抹回旧实例的 false,后续重试退回 60s 长封顶
时序行为补常驻回归测试 recorder_stream_selection_test.go(7 项,含端到端 tryRecord 用例)。
|
2026-09-30 18:30:22 +08:00 |
|
Joftal
|
a0c2469768
|
style(live/sooplive): 三条错误串改为动词开头,修 golangci-lint ST1005
upstream CI 全量跑 staticcheck,ST1005 不允许错误串以大写开头;这三条原本以 Soop 起头。
改成与本文件既有写法一致的动词开头(请求/获取/申请 Soop …失败),只调文案,不动逻辑与判断分支。
|
2026-09-30 08:47:51 +08:00 |
|
Joftal
|
4646611665
|
fix(configs,servers): Soop 密码不再从 JSON 接口下发并在明文页掩码
- SoopLiveAuth.Password 标记 json:"-":面板读取走专用状态接口与 raw-config YAML,
/api/config 之类的 JSON 出口不再把明文密码带给浏览器或留在前端状态里。
- 设置明文页把密码位输出为占位符,提交时按"整节没提交/照抄占位符/只改用户名/显式换密码/
留空清除"四种意图分别三方合并,既不会把占位符当成新密码存下,也不会用打开页面那一刻的
旧快照倒回后台刚保存的凭证。
|
2026-09-29 20:00:19 +08:00 |
|
Joftal
|
cdad77fa51
|
perf(live/sooplive,live,live/system,recorders): Soop 只解析选中清晰度并在同轮复用播放页
- 取流改为按 DeferredStreamResolver 延迟解析:先列档位、只给要录的那一路申请 aid,
开播房间的请求量由 8 次降到 4 次;包装层与初始化窗口一并转发,平台未实现时返回
ErrNotImplemented 由录制器回退全量解析,其他平台选路结果与旧算法逐位等价。
- 播放页与频道信息在 15s 窗口内复用成功结果:只缓存"已成功且开播"和 result 正常的
播放信息,返回副本供调用方就地排序,登录态变化与房间配置更新时整体作废。
- 取流请求按原始 URL 做 singleflight 合并,同一轮的重复解析只发一次网络请求。
- 录制失败重试改为升档退避(5s 起倍增,从未录上过封顶 60s、本场录上过封顶 15s),
间隔随分段重启继承,避免下播后仍以 5s 频率反复冲击平台接口。
|
2026-09-29 19:59:46 +08:00 |
|
Eric
|
cb6837ce0a
|
Merge pull request #1211 from Joftal/dev
fix(recorders/danmaku,configs,webapp): 弹幕去排队并修复四项静默失效
|
2026-09-29 09:57:43 +08:00 |
|
Joftal
|
6822de38c7
|
fix(recorders/danmaku,configs,webapp): 修描边虚化失效、刷屏叠印同车道与 128 迁移复活
- writeHeader:OutlineColour 跟随 opacity(BorderStyle=1 下只虚化填充会留实心黑边),outline 对 SC/Guard 全样式生效
- assignLane:并列最早车道从 nextLane 起扫描,占用点取 max 不被短弹幕提前抹掉;时间戳仍恒等于到达时刻,不级联
- configs:新增 danmaku_opacity_migrated 闸门,opacity 128→255 只在首次加载迁移,之后 128 按用户意图保留
- webapp 预览:描边 alpha 与文字 alpha 同口径,top/bottom 区域边界与后端车道一致
|
2026-09-29 09:50:20 +08:00 |
|
Joftal
|
eb3dd548ed
|
fix(recorders/danmaku,configs,webapp): 弹幕去排队并修复四项静默失效
滚动车道耗尽时不再推迟开始时间,改为占用一个净空窗口后复用,时间戳恒等于
到达时刻(#1178 的排队级联根因);scroll_time 用四舍五入的 ms/px 作为速度
唯一口径,事件时长与车道净空统一走 travelCS,消除"标称 5s 实跑 3.84s"。
opacity 原本全链路无效(Banner 样式不绘 BackColour),现按"文字透明度"实现
并把 128 视为未设置迁移到 255;outline 补齐到 SC/上舰样式;web 播放器底部
区域按像素中线取上整,不再整条车道凭空不显示。
yaml.Unmarshal 会顺着指针原地写入,值拷贝后仍指向包级默认配置,任意 YAML
都会永久污染全局默认,故新增 clonePointerFields 在加载/合并/取默认处换新指针。
|
2026-09-28 14:03:21 +08:00 |
|
Eric
|
230e24d17c
|
Merge pull request #1210 from Joftal/dev
斗鱼自动续期cookie+部分问题修复
|
2026-09-26 00:42:43 +08:00 |
|
Joftal
|
fc71b311ed
|
fix(servers,configs,live/douyu): 明文配置并发提交与三处静默失效
- putRawConfig 改为锁内三方合并:继承与作废判定以提交时刻的最新配置为准,
解析整份 YAML 那几十毫秒里后台续期写入的票据、登录 cookie 与 OpenList 令牌
不再被入口快照倒回旧值(内存与磁盘同时倒带,重启也回不来)。
- 房间 URL 规范化后的去重改为逐字段补齐:整条丢弃会把重复条目上单独配的原画、
输出目录、弹幕开关、转 mp4 无声清零,并随本次加载写回磁盘。
- 换票链未真正到达终点时不再报登录成功:3xx 无 Location、8 跳耗尽、终点 4xx/5xx
一律判失败,否则残缺 cookie 落盘后面板显示已登录而实际录不上,下次续期还排到三天后。
- 扫码接口非 2xx 与缺少 error 字段的响应直接判失败,错误串不再夹带上游正文,
避免一次性 token 与风控页原文进入 HTTP 响应和应用日志。
行为变更:明文页整块删除 cookies: 一节视为"未提交",不再清空登录态;
确要清除请写 cookies: {} 或把对应主机留空。
|
2026-09-26 00:23:21 +08:00 |
|
Joftal
|
73518c6723
|
Merge origin/master into dev
master 侧 1a629df 把配置改为不可变快照(GetCurrentConfig() 返回的对象不得就地
改写),与第十九轮 putRawConfig 的斗鱼凭证保护改到了同一段代码。
冲突解法:保留本分支一侧。CloneConfigShallow 会连 liveRoomIndexCache 一起换
新 map,因此"在副本上刷新索引"本身就不违反快照不可变这条不变量;同时把注释
口径修正为 concurrent map read and map write 会导致进程 fatal 退出。
验证:go run build.go dev / build-web 通过,go vet -tags dev ./src/... 干净,
go run build.go test 无失败(含 master 新增的 TestGetLiveRoomByUrlConcurrent
与本分支的 raw-config 凭证回归)。
|
2026-09-25 21:07:40 +08:00 |
|
Joftal
|
78c6336c93
|
feat(live/douyu,servers,configs,webapp): 斗鱼 cookie 后台自动续期(LTP0 + safeAuth 换票)
主站 acf_* 登录 cookie 实测仅约 6 天有效(Set-Cookie Max-Age=529200s),过期后取流降级、
弹幕登录失败且只能重新扫码。本功能用 passport 域的长期票据 LTP0 走 safeAuth 换票链自动续命。
- configs: 新增 douyu_auth(LTP0/DyDid/续期日程);Marshal 改 temp+fsync+rename 原子写并 Chmod 0600,
rename 或建临时文件失败才回退原地写(Docker 单文件挂载场景);cookie 域名别名(douyu.com/m.douyu.com)
入库统一归一到 www.douyu.com;写盘前从 cookie 串剥离 LTP0;凭证三处出口全部掩码
(/api/config 走 json:"-"、raw-config 走 __BILILIVE_DOUYU_SECRET_HIDDEN__、debug 转储走 CloneForLog)
- live/douyu/refresh.go: 手动逐跳跟随 302 累积 Set-Cookie(8 跳上限、跳过空值),
只放行 https 且 *.douyu.com 的跳点(douyu.com.evil.com、裸 http、片段藏域名一律拒绝),
终点必须 200 且 follow/top3 探针返回 error=0 才算成功;非 200 归为临时错误、缺必需字段才判失效;
字段级合并 + 设备号策略(dy_did/acf_did/acf_devid 复用旧值),合并结果按字段名有序写回避免无意义配置 diff
- 阈值调度:3d 到点续期、临时失败 6h 退避、判失效 24h、连败 6d 升档;cookie 确凿过期前不发取流请求
- servers/douyu_keeper.go: 30s 首检 + 每小时廉价检查,仅在存有 LTP0 时真正换票;
续期结果只在 CAS 闭包内合并并校验 LTP0 归属(旧票据的迟到结果直接作废);
失效只置 need_rescan 不清 LTP0,告警按 LTP0 去重且推送走独立 goroutine 不阻塞续期循环
- servers/handler.go: raw-config 区分"该节未提交"与"显式清空"、按 acf_uid 判换号、带锁提交并支持版本冲突重试;
putLiveHostCookie 不误清长期票据;新增 GET /api/douyu/auth/status 供前端显示登录态与下次续期时间;
B 站 pollBilibiliQRCode 保留上游原有字段(不再因结构体重序列化丢 refresh_token)并把 Set-Cookie
登录字段拼进 data.cookies
- notify: 新增 SendSystemAlert,斗鱼需重新扫码时按已配渠道推送
- cmd/bililive: 启动 keeper 且不依赖 Web RPC 是否启用,保证无界面后台长期保活
- webapp: 斗鱼面板显示登录态/续期日程并做轮询会话隔离,房间列表标记登录态;
B 站扫码成功后回填 cookie 并提示未落盘的后果
- 测试:新增 6 个文件覆盖换票链分类、失效与退避升档、掩码出口、原子写与回退、别名归一、设备号复用
(全部 httptest/合成值,不触网、不含真实凭证)
- go.mod: google/uuid 由 indirect 归位为 direct(handler 直接引用)
实测记录:真机换票链有效态 302→200 JSONP+17 个 Set-Cookie、垃圾票据态 200 JSONP+零 cookie;
临时实例 30s 首检续期成功并热应用后,斗鱼原画以 60fps 连续录制跨过 5 分钟分段;
垃圾 LTP0 走 need_rescan + 5.99h 退避,原 cookie 与票据均未被破坏。
|
2026-09-25 20:45:43 +08:00 |
|
Joftal
|
43f3dfadb1
|
fix(live/system): InitializingLive 未把房间选项热应用到原始 Live
- BaseLive 是值嵌入,只调继承来的 UpdateLiveOptionsbyConfig 时,cookie/只录音频/清晰度只落在
包装对象上;初始化完成后 OriginalLive 会顶掉本包装对象,期间热应用的 cookie 跟着一起丢了——
表现为"重新扫码后老房间仍按扫码前的登录态取流",且没有任何提示
- 新增同名方法同时更新包装对象与 OriginalLive,错误优先返回包装层的
- 补 GetRoomID 委托:少了这层转发,WrappedLive 的类型断言只能走到本对象就返回空,
斗鱼别名 URL(如 /lotterytimer)的弹幕录制会退回拿 URL 路径当房间号,弹幕登录直接失败
- 补用例:断言两个对象都收到选项、以及 OriginalLive 报错时能向上传播
|
2026-09-25 20:45:04 +08:00 |
|
Joftal
|
f722eef366
|
fix(pkg/parser/ffmpeg): 请求头必须落在 -i 之前且只发一个 -headers
- 原实现把逐个 header 拼成多个 -headers 追加在 -c copy 之后,即 -i 之后;FFmpeg 中位于输入文件
之后的选项属于输出文件,会被静默丢弃(实测服务端只收到 -user_agent/-referer,收不到 Cookie)
——带登录态取流的能力形同不存在
- 抽出 buildInputArgs/buildExtraHeaders:-user_agent、-referer、-headers 统一前置到 -i 之前,
多个头合并为单个 -headers 并以 \r\n 分隔
- 合并时按 key 排序:map 遍历顺序随机,不排序会让每次录制生成不同命令行,无法复现与比对
- use_proxy 分支保持原样(命令行只有 -rw_timeout -i),限速条件一并收敛进 buildInputArgs
- 补 4 条用例覆盖头合并、头的相对位置、代理分支、限速开关
|
2026-09-25 20:44:52 +08:00 |
|
Joftal
|
b615ca67b5
|
fix(pkg/hlsproxy): ReadTimeout 把 ffmpeg 复用的 keep-alive 连接掐断
- Go 的 http.Server.ReadTimeout 同时被当作 keep-alive 连接的空闲上限,空闲超时即由服务端关闭,
客户端表现为 WSAECONNABORTED / ffmpeg 的 "Error number -10053 occurred"
- ffmpeg 的 HLS demuxer 正是复用同一条连接轮询播放列表,两次轮询之间可空闲几十秒,
因此本地代理只能限"读请求头"这一段:改用 ReadHeaderTimeout,写超时留空(分段是流式透传)
- 上游资源超时仍由 p.client 负责,本地回环无需整体读超时
- 补回归用例:实测 Go 1.24 下只设 ReadHeaderTimeout 时空闲复用连接仍可用
|
2026-09-25 20:44:38 +08:00 |
|
Joftal
|
03059c7c0f
|
feat(recorders/danmaku/douyin,configs): 抖音分享短链转长链与房间 URL 规范化 (issue #1185)
- 弹幕 client:v.douyin.com 分享口令运行时逐跳解析真实 roomId(域名白名单+ctx 30s 超时),修复手机版分享链接弹幕 WS 502
- 新增 sharelink.go:ResolveShareLongURL 锚定 owner.shortId 提取账号级 web_rid,添加房间时一次性转 live.douyin.com/<web_rid> 长链入库,规避短链固化场次跨开播失效;转换失败保留原短链不阻断添加
- NormalizeLiveRoomUrl:live.douyin.com/?live_web_rid=<n> 首页 query 形态规范化为长链(path 空才转换,只认 live_web_rid 不认 room_id),存量坏房间加载期自动修复
- newConfigPostProcess:规范化后同 URL 房间去重合并(is_listening 取 OR、notify_only 取 AND),堵升级后"query/别名存量条目+长链"双条目双录
|
2026-09-23 15:02:25 +08:00 |
|
Joftal
|
7fc3658a6b
|
feat(live/douyu,webapp): 斗鱼扫码登录与 cookie 登录态录制
签名/取流/下载全链路携带 cookie,消除匿名拉流约 5 分钟断流;
新增扫码登录面板(自动落盘热应用、到期倒计时);m.douyu.com 入口规范化为 www
|
2026-09-23 10:45:36 +08:00 |
|
Eric
|
ad8a9f2192
|
Merge branch 'bililive-go:master' into master
|
2026-09-22 15:06:03 +08:00 |
|
kira1928
|
ef71711a7c
|
Merge pull request #1198 from bililive-go/fix/config-snapshot-concurrent-map
fix: 消除配置快照并发读写导致的 fatal 崩溃
|
2026-09-04 01:58:56 +09:00 |
|
kira1928
|
d32204dfcc
|
Merge pull request #1175 from bililive-go/fix/e2e-active-recordings
fix(test): 修复 E2E active_recordings 泄漏并终止渲染失败的录制重试
|
2026-09-04 01:56:25 +09:00 |
|
 
|
1a629df637
|
fix: 消除配置快照并发读写导致的 fatal 崩溃
GetLiveRoomByUrl 在索引缓存未命中时会调用 RefreshLiveRoomIndexCache
写入共享的不可变配置快照的 map。该函数被列表接口、录制、监听等大量
goroutine 高频并发调用,一个 goroutine 写 map 而另一个读同一 map 时,
触发 Go 运行时的 fatal error(concurrent map read and map write),
整个进程直接退出——表现为「开始录制后一段时间报错崩溃」。
配置采用不可变快照架构(Update 复制-修改-原子替换,替换前统一
RefreshLiveRoomIndexCache),已存入的快照不应再被就地修改。本次修复:
- GetLiveRoomByUrl 改为纯只读:命中缓存直接返回,未命中回退到只读线性
扫描,不再写共享快照的 map。
- 移除 putConfig / putRawConfig 中对共享快照的 RefreshLiveRoomIndexCache
调用(Marshal 不需要该缓存,后续查找也已是只读)。
- 删除无调用者且同样就地修改快照的死方法 (*Config).RemoveLiveRoomByUrl。
- 新增并发回归测试 TestGetLiveRoomByUrlConcurrent。
via [HAPI](https://hapi.run)
Co-Authored-By: HAPI <noreply@hapi.run>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-09-04 00:49:03 +09:00 |
|
kira1928
|
37d1d0e7d7
|
Merge pull request #1181 from bililive-go/fix/disable-platform-rate-limit
fix: 暂时关闭平台级访问限流
|
2026-08-28 23:31:52 +09:00 |
|
kira1928
|
45dcc52ba3
|
fix: 同步平台限流禁用状态
|
2026-08-23 04:09:33 +09:00 |
|
kira1928
|
8dc79754f8
|
Merge origin/master into fix/e2e-active-recordings
|
2026-08-23 04:05:36 +09:00 |
|
kira1928
|
7dcee5132b
|
fix: 暂时关闭平台级访问限流
|
2026-08-23 01:46:57 +09:00 |
|
Eric
|
ea8c24305c
|
Merge pull request #1174 from Joftal/dev
fix(notify): 修复录制摘要通知在 Pipeline 处理前发送导致文件列表不准确
|
2026-08-18 10:25:10 +08:00 |
|
kira1928
|
ad81d2b9cf
|
fix: 根据 review 收紧录制器停止与 E2E 清理
|
2026-08-18 01:10:20 +09:00 |
|
 
|
524f3329c7
|
fix(test): 修复 E2E active_recordings 泄漏并终止渲染失败的录制重试
E2E 中 update-full/update-workflow 的 "active_recordings 为 0" 断言偶发失败,根因有三:
1. fixture 模板 out_put_tmpl 使用了 live.Info 上不存在的字段 {{.StartTime}},
导致每次文件名渲染都失败(自 #1061 起)。改为合法的时间戳写法。
2. recording.spec.ts 通过 UI 添加的 dev 直播间从不清理;workers=1 下所有 spec
共用同一后端进程,残留房间被 mock 持续判定为在播,泄漏进后续 spec 的断言。
增加 afterAll 统一删除全部直播间。
3. 文件名渲染失败后 recorder 会以 5s 间隔无限重试、刷屏且被计入活跃录制数。
现改为派发一次 LiveEnd 交由 manager 回收(与 stopRetryForExplicitOffline
同构),避免无意义的重试风暴。
并将两处 active_recordings 断言改为轮询,容忍录制器回收的短暂延迟。
via [HAPI](https://hapi.run)
Co-Authored-By: HAPI <noreply@hapi.run>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-08-17 22:51:54 +09:00 |
|
 JoftalandKscc
|
5cc21c8afd
|
fix(pipeline): immediate 模式下后续阶段替换文件后上传标记丢失
immediate 模式下 cloud_upload 最先执行,上传 .flv 后设置 Metadata[uploaded]。
后续 fix_flv 阶段创建新 FileInfo 替换原始 .flv,新对象无 Metadata,
上传标记丢失。.ass 不经过 fix_flv,标记保留。
修复:
1. 上传循环中上传成功时立即设置 Metadata[uploaded](不依赖删除逻辑块)
2. PipelineContext 新增 UploadedPaths 记录已上传文件路径
3. 所有阶段执行完毕后,按基名匹配为被替换的文件恢复上传标记
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 17:44:42 +08:00 |
|
 JoftalandKscc
|
e52df5b4f9
|
fix(pipeline): immediate 模式下上传文件未标记 Metadata[uploaded]
Metadata[uploaded] 的设置在 if !uploadFailed && uploadTiming != 'immediate'
块内,immediate 模式下整个块被跳过,uploaded 文件从未被标记。
extractUploadedDetails 读取 LastStageFiles 时找不到 uploaded 标记,
通知回退到无上传标注的格式。
修复:在上传循环中上传成功时立即设置 Metadata[uploaded] = true,
不依赖后续删除逻辑块。同时修复 cleanupOrphanedAssFiles 未检查 .ass
是否已被 deleteMarkedFiles 删除的问题。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 17:28:18 +08:00 |
|
 JoftalandKscc
|
4fbbd52f32
|
fix(pipeline,recorders): cleanupOrphanedAssFiles 未检查 .ass 是否已被删除
deleteMarkedFiles 删除 .ass 后不加入 kept,但 cleanupOrphanedAssFiles 的
第二轮(处理 Pipeline 中的 .ass)只检查关联视频是否存在,不检查 .ass 本身。
当 .mp4 存在时,已删除的 .ass 被错误保留在 kept 中,CurrentFiles 多出一个
条目,导致 onPipelineTaskComplete 的 uploaded/kept 分类错误。
修复:第二轮先检查 os.Stat,.ass 已不存在则跳过(不加入 kept)。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 17:23:49 +08:00 |
|
 JoftalandKscc
|
543b04e67d
|
fix(recorders): 部分上传时回调丢失已上传文件详情
onPipelineTaskComplete 仅在 CurrentFiles 为空(全部删除)时从 LastStageFiles
提取 uploaded 详情。当部分文件被上传删除、部分保留时(如 immediate 模式),
CurrentFiles 非空走 else 分支,已上传文件从 CurrentFiles 消失,LastStageFiles
的上传标记被忽略。
修复:始终从 LastStageFiles 提取 uploaded 详情,再合并 CurrentFiles 中未被
上传标记覆盖的保留文件。回退逻辑仅在两者都为空时触发。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 17:18:34 +08:00 |
|
 JoftalandKscc
|
77ba76cfa3
|
fix(pipeline): LastStageFiles 快照被 deleteMarkedFiles 清除上传标记
executor 保存 LastStageFiles 快照后调用 deleteMarkedFiles,后者清除已删除
文件的 Metadata[uploaded]。由于快照与 files 共享底层数组,LastStageFiles
中的上传标记也被清除。extractUploadedDetails 读取时无 uploaded 标记,
通知回退到 r.recordedFiles(无上传标注)。
修复:保存快照前深拷贝 files slice,断开与 deleteMarkedFiles 的共享。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 16:56:22 +08:00 |
|
 JoftalandKscc
|
8740b943e0
|
fix(recorders,webapp): 分段重启时摘要在 Pipeline 完成前发出及预览 burnDelSource 错误
1. 分段重启时序问题:CloseForRestart 先调用 r.Close() 让 run() 退出,
run() 的 defer 触发 sendAccumulatedSummary,此时 suppressSummary
可能还未设置(在 pipelineState 中需要锁),导致摘要在 Pipeline 完成前
发出(pipelineDetails 为空,回退到 recordedFiles,无上传标记)。
Pipeline 完成后回调发现 summarySent=true,跳过发送,上传详情丢失。
修复:新增 closeForRestart 原子标记,在 CloseForRestart 中先设置标记
再调用 Close()。run() 的 defer 检查此标记,跳过 sendAccumulatedSummary。
TransferPipelineState 完成后由 onAllTasksDone 回调发送完整摘要。
2. 预览 burnDelSource=false 在 immediate 模式下错误标记 .mp4 为 uploaded。
.mp4 在 immediate 模式下不会被上传(cloud_upload 最先执行),应保持 kept。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 16:38:00 +08:00 |
|
 JoftalandKscc
|
b54af8ad62
|
fix(webapp): immediate 模式下预览上传列表和中间产物标记错误
immediate 模式下 cloud_upload 最先执行,上传原始 .flv 和 .ass,
后续处理阶段产出的 .mp4/.mkv 不会被上传。但预览逻辑把 .flv 标记为
intermediate(不上传),把 .mp4 标记为 uploaded,与实际完全相反。
修复:immediate 模式下,源文件用 uploaded_deleted(已上传后被处理阶段
替代删除),处理阶段产出的 .mp4/.mkv 保持 kept(未被上传)。
after_process 模式下 intermediate 逻辑不变。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 16:22:14 +08:00 |
|
 JoftalandKscc
|
42f8f9b519
|
fix(webapp): 预览未区分中间产物导致上传列表和保留列表错误
预览用 'deleted' 同时表示「被处理阶段替代的源文件」和「被删除的文件」,
导致:1) 中间产物(如转码后的 .mp4)误出现在上传列表,2) 最终视频误出现在
保留列表,3) 孤儿 .ass 清理逻辑误判视频存在。
修复:新增 'intermediate' 状态表示中间产物(被转码/烧录替代的源文件)。
- intermediate 不参与上传(仅最终产物上传)
- intermediate 在预览中显示为「删除」
- 孤儿 .ass 检查正确识别 intermediate 视频为不存在
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 16:09:13 +08:00 |
|
 JoftalandKscc
|
54678eb83f
|
fix(recorders): 通知合并时清理无关联视频的孤立 .ass 文件
DAA 发现的 .ass 标记为 Deletable(不标记 uploaded),executor 删除视频后
.ass 从 recordedFiles 加入 merged,但通知误显为本地保留。
修复:合并后检查 .ass 的关联视频是否在列表中,无视频的 .ass 被移除。
与 executor 的 cleanupOrphanedAssFiles 逻辑一致。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 16:01:53 +08:00 |
|
 JoftalandKscc
|
f6002f088b
|
fix(pipeline): 发现的 .ass 文件不应标记为已上传
deleteAllAfter 和 deleteAfter 路径中,从磁盘发现的关联 .ass 文件被标记
Metadata['uploaded'] = true,但实际未上传到云存储。通知错误将其报告为
「已上传到云端」。
修复:发现的 .ass 仅标记 Deletable(由 executor 删除),不标记 uploaded。
已通过 uploadSubtitles 上传的 .ass 不受影响(在上传循环中正确标记)。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 15:59:24 +08:00 |
|
 JoftalandKscc
|
15c973411f
|
fix(webapp): 预览兜底逻辑未正确识别已删除视频导致 .ass 误显为保留
兜底逻辑用 status !== 'deleted' && status !== 'uploaded_deleted' 判断视频
是否存在,但 deleteAfter 标记的视频状态是 'uploaded_delete'(无 d),
导致兜底逻辑认为视频仍存在,.ass 不被清理。
修复:改为只认 'kept' 和 'uploaded'(本地保留)的视频为存在,
其他状态(deleted、uploaded_delete、uploaded_deleted)均视为不存在。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 15:54:12 +08:00 |
|
 JoftalandKscc
|
7ed283cf14
|
fix(pipeline): burn_delete_ass + upload_subtitles 时 .ass 未被上传
burn 阶段将 .ass 标记为 Deletable 后,cloud upload 的上传循环跳过它,
导致 .ass 未上传但通知显示「已上传到云端」。
修复:
- 上传循环放行 Deletable 的 .ass(当 uploadSubtitles 时)
- 上传后标记 Metadata[uploaded],确保 executor 正确删除
修复后行为:
- burn_delete_ass=true + upload_subtitles=true:.ass 先上传再删除
- burn_delete_ass=true + upload_subtitles=false:.ass 不上传,直接删除
- burn_delete_ass=false + upload_subtitles=true:.ass 正常上传
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 15:31:39 +08:00 |
|
 JoftalandKscc
|
9eb367623a
|
fix(notify): 上传后不删除时摘要也应显示已上传文件
原逻辑把「已上传」等同于「已删除」,只有所有文件都上传且删除时才走
「已上传到云端」分支。上传但不删除时,通知错误显示「本地文件已清理」。
修复:分离 uploaded 和 kept 两个维度,支持三种通知格式:
- 全部上传:显示「已上传到云端」
- 部分上传+部分保留:显示两段(上传列表+本地列表+磁盘空间)
- 全部本地保留:显示文件列表+磁盘空间
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 15:20:33 +08:00 |
|
 JoftalandKscc
|
cdd0544d79
|
fix(pipeline,servers): 手动上传和配置保存遗漏 upload_subtitles
1. EnqueueUploadTask 构建 pipeline config 时未传递 OptionUploadSubtitles,
手动单文件/批量上传不会发现关联 .ass 文件
2. handler.go 解析 cloud_upload 配置时遗漏 upload_subtitles 字段,
前端开关保存无效
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 15:18:08 +08:00 |
|
 JoftalandKscc
|
0d5f2edd2f
|
fix(servers): 上传弹幕字幕开关无法保存
handler.go 解析 cloud_upload 配置时遗漏 upload_subtitles 字段,
前端发送的开关值被后端忽略,导致保存无效。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 15:09:27 +08:00 |
|
 JoftalandKscc
|
79426525e9
|
feat(webapp): 云上传新增「上传弹幕字幕」开关及文件处理预览
- EffectiveConfig 接口新增 upload_subtitles 字段
- CloudUploadSettings 新增开关,位于删除开关之后、OpenList 认证之前
- analyzeConfig 预览逻辑:after_process 模式下 .ass 标记为 uploaded,
immediate 模式不标记(.ass 尚未生成),兜底逻辑保持无视频时删除 .ass
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 14:50:52 +08:00 |
|
 JoftalandKscc
|
f5716ad3de
|
feat(pipeline): 支持上传 .ass 弹幕字幕文件到云存储
新增 upload_subtitles 配置项,启用后 cloud upload stage 会在上传循环前
从磁盘发现与视频文件同名的 .ass 字幕文件,加入 input 参与上传。
改动:
- configs: CloudUpload 新增 UploadSubtitles 字段
- pipeline/config: 新增 OptionUploadSubtitles,ConvertLegacyConfig 传递
- extract_cover: CloudUploadStage 新增 uploadSubtitles 字段,
Execute 中扫描 input 视频文件发现关联 .ass 并加入上传队列,
文件类型过滤放行 .ass
限制:仅 after_process 模式生效(immediate 模式下 .ass 尚未生成)。
需要同时开启弹幕录制(danmaku_enable)才有 .ass 文件可上传。
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 14:42:27 +08:00 |
|
 JoftalandKscc
|
ad5fa50a59
|
fix(pipeline): 云上传模式下 .ass 文件未标记 uploaded 导致摘要误显
cloud upload 的 deleteAllAfter 和 deleteAfter 模式都只处理视频文件,
关联的 .ass 字幕文件不在 pipeline 中,不会被标记 Metadata[uploaded]。
摘要将其作为本地文件显示,但实际已被删除。
修复:
- deleteAllAfter:加入 output 时即设置 Metadata[uploaded] = true
- deleteAfter:为已上传视频文件查找关联 .ass,加入 output 并标记 uploaded
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 14:26:30 +08:00 |
|
 JoftalandKscc
|
6fde121e55
|
fix(pipeline,recorders): 修复分段重启相关的五个并发问题
1. redirectedTo 数据竞争:改用 atomic.Pointer,遍历 Load()、写入 Store()
2. merged 底层数组写冲突:快照时深拷贝,断开与 ps.details 的共享
3. 摘要发送先于状态转移:transferWg 屏障确保 Pipeline 状态转入后再发送
4. 回调注册先于任务可见:扩展 m.mu.Lock 覆盖 CreateTask + 回调注册,
阻塞 pollLoop 的 scheduleNextTasks
5. 异步通知 goroutine 未跟踪:notifyWg 跟踪 go sendAccumulatedSummary,
关闭流程中 PipelineManager.Close 后等待通知完成
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-17 11:34:59 +08:00 |
|
 JoftalandKscc
|
04ffe41c3c
|
fix(pipeline): 修复分段重启时 Pipeline 状态转移的三个问题
1. 连续重启 A→B→C 回调链断裂:用 redirectedTo 链替代指针覆盖,
resolveState() 沿链找到最终活跃状态,回调正确操作最终 recorder 的计数器
2. data race:suppressSummary 从 recorder 移入 pipelineSharedState 用 mu 保护;
r.pipelineState 指针字段不再被覆盖,消除 Lock/Unlock 不配对的竞态
3. extractUploadedDetails 未排除封面文件:增加 FileTypeCover 过滤,
与 FileInfoToDetails 保持一致
Co-Authored-By: Kscc <noreply@owtffssent.com>
|
2026-08-14 17:09:10 +08:00 |
|