tamakyi
|
a24425e16d
|
修第三批 P2:除零、停止/暂停的响应与状态一致性、临时文件、带 BOM 的 ASS
一、弹幕滚动时间不再整数除零
write() 里拿 (PlayResX+length) 做除数,PlayResX 被配成 0 又收到一条空内容弹幕时
分母正好是 0,直接 panic 终止整场录制。抽成 scrollMarks 并给分母为 0 的兜底
(退回半个停留时长,至少让它正常显示出来)。
二、点停止不再要等整个块渲完
jobAttach 原来只看 paused:停止请求若落在 jobGate 之后、ffmpeg 启动过程中,
job.proc 还没登记,jobStop 拿不到进程可杀,用户得等整个块渲完(大块要几分钟)。
现在 attach 时发现任务已请求停止就地把它杀掉,上层拿到 errJobStopped,
卡片显示的是「已停止」而不是「失败」。
三、暂停没挂住就回滚状态
jobPause 先把 job.paused 置 true 再调 suspendProcess,挂起失败时状态已经改了:
界面显示「已暂停」而 ffmpeg 还在跑。失败时回滚(只在 proc 仍是同一个进程时回滚)。
jobResume 同理:恢复不成放回「已暂停」,免得显示在跑却停着。
四、.ass 还原的临时 jsonl 用完就删
还原结果写不进录播目录时会退到系统临时目录的固定名文件,原来从不清理,
每失败一次留一份。新增 danmuSource.tempJsonl 标记 + dropTempDanmu 收尾删除;
只删标记过的临时文件 —— 正常情况下那个路径是用户录播目录里的同名 jsonl,
删了就是丢数据。
五、带 BOM 的 ASS 能整份解析
带 UTF-8 BOM 时首行是 BOM+[Script Info],一个节都进不去,最后只报
「可能不是弹幕文件」,跟真实原因完全对不上。解析时剥掉 BOM。
六、头像下载期间暂停/停止不用再干等
单次超时 30 秒 × 3 次重试,最坏 96 秒才响应暂停/停止。单次超时收到 10 秒
(头像只有几百 KB),并且每次重试前过闸门:暂停在这里等、停止直接放弃,
不再把剩下的重试跑完;停止也不再打「头像不可用」的告警。
验证:
- gofmt -l 空;go vet ./... 空;go build 与 GOOS=linux go build 通过
- go test ./... 全绿(10.9s);go test -race ./... 全绿(14.5s)
- 新增 p2_fixes_test.go 8 个用例;本轮 6 项加上一批 6 项共 12 项反向验证全部通过
(每项临时退回源码 → 对应测试确实失败 → 恢复)
- 51897 隔离实例上完整复测:e2e.py 37 项全过、smoke_extra.py 33 项全过
|
2026-09-26 10:07:30 +08:00 |
|
tamakyi
|
9b9b3fa2cd
|
弹幕写盘出错不再被静默吞掉
审查发现:录制时每写一条弹幕都调用 os.File.Write / fmt.Fprintf,
但返回值一个都没接。磁盘写满、外接盘或网络盘掉线时,写入会失败而程序
毫无察觉 —— 照样打印「录制完成」、照样自动合并,最后拿到的成片缺了一大截
弹幕,界面上看不出是「缺了」还是「本来就没弹幕」。
1. 写入器记住写盘错误
danmuWriter 增加一个 err 字段:每条弹幕的 ass / nick.ass / jsonl 写入,
以及文件头的写入,都检查返回值。只保留第一个错误 —— 磁盘满了之后
每写一条都会失败,全记下来只会把日志刷爆,而第一个就足以说明原因。
2. close() 负责把错误交出来
三个文件的 Close 错误也要记:os.File 在部分系统上(NFS、某些网络盘)
是到 Close 才报出「写不进去」,只盯每次 Write 的返回值会漏掉这种情况。
getDanmu 里拿到错误就明确告警,并把这条记录标记成「弹幕文件写坏了」。
3. 写坏的本场跳过自动合并
光打一条日志不够 —— 照样会合成一个缺弹幕的成片。liveInfo 增加
danmuWriteFailed,finishPart 据此跳过合并,录播和弹幕文件都留着,
用户检查磁盘后还能手动合并。
已验证:
- 新增 4 个用例:
TestDanmuWriteErrorSurfacedOnClose(写入失败后 failed() 为真、
close() 必须把错误交出来、错误里能看出是哪个文件)、
TestDanmuWriteKeepsOnlyFirstError(只记第一个)、
TestDanmuWriteNoFalseAlarm(正常录制不能误判,这是加检查最容易踩的反向坑)、
TestFinishPartSkipsMergeWhenDanmuBroken(先跑一个「条件都满足应当合并」
的对照组确认测试本身有效,再验证标了写坏之后不合并)。
- 反向验证:把 jsonl 的两处 Write 错误改回丢弃,
TestDanmuWriteErrorSurfacedOnClose 立刻报「failed() 应为 true」。
- 测试踩到的两个坑(都记进注释):替换 w.jsonl 前要先关掉原句柄否则
Windows 上临时目录删不掉;测试里没跑 initialize(),lInfoMap.info 是 nil,
直接赋值会 panic。
- gofmt / go vet / go build / GOOS=linux go build / go test / go test -race 全过,
全量测试连跑两次稳定。
|
2026-09-26 03:14:07 +08:00 |
|
tamakyi
|
cbe5dfa982
|
弹幕字号按画面短边自动定,竖屏成片不再字大到铺满整行
1. 字号基准从「画面高度」改成「画面短边」
以前合并时只用高度比换算字号(字号 × 视频高 ÷ 弹幕文件高)。横屏弹幕文件
(1920x1080、60 号)配竖屏视频(720x1280)时会被放大到 71 号,而画面只有
720 宽,一条 10 字弹幕就铺满整行。横竖屏互换时高度不是约束文字宽度的维度,
短边才是:横屏取高、竖屏取宽。
2. 「弹幕字号」填 0 的含义从「跟随弹幕文件」改成「自动按画面分辨率」
取画布短边的 5.56%(60/1080)。于是 1920x1080 → 60、1280x720 → 40、
960x540 → 30,横屏行为与以前完全一致;720x1280 → 40(以前 60)、
640x1280 → 36。填大于 0 仍是精确像素覆盖。
3. 录制端竖屏档位预设 720x1280 的字号从 60 改成 40
原来横屏三档都是短边的 5.56%,只有竖屏这档是 8.33%,比横屏大 50%。
改完四档口径一致,新录的弹幕文件和成片也对得上。
4. 坐标系和字号拆开
unifyDanmuSpace 只负责把 PlayRes 统一到视频分辨率,字号统一交给
applyFontSize 按最终画布算,避免两处各改一次。
5. .gitignore 加上 /avatar_cache
头像缓存挪到程序目录后,程序正好跑在仓库里,缓存目录会被 git 看见,
git add . 会把那 336 个 PNG 一起提交进去。
已验证:
- 新增 TestShortSide / TestAutoFontSize / TestSubConfigsMatchAutoFontSize /
TestApplyFontSize;TestUnifyDanmuSpace 改成只校验 PlayRes,并且新增断言
确认它不再动字号。
- 反向验证:把短边规则临时退回「按高度」,TestAutoFontSize 报
「720x1280 应为 40,实际 71」「1080x1920 应为 60,实际 107」,
TestApplyFontSize、TestSubConfigsMatchAutoFontSize 同步失败。
- 端到端:造 720x1280 竖屏视频 + 1920x1080/60 号的 jsonl,字号填 0 真跑一次合并,
日志打出「竖屏画布 720x1280,弹幕字号自动取 40」;同一输入再用旧规则跑一次对照,
抽同一时刻的帧量墨迹高度:改前 46px、改后 25px(1.84 倍)。
- gofmt / go vet / go build / GOOS=linux go build / go test 全过。
|
2026-09-26 00:59:17 +08:00 |
|
tamakyi
|
ed4e47e305
|
init
|
2026-09-25 13:16:54 +08:00 |
|