弹幕写盘出错不再被静默吞掉
审查发现:录制时每写一条弹幕都调用 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 全过, 全量测试连跑两次稳定。
This commit is contained in:
@@ -67,8 +67,11 @@ type liveInfo struct {
|
||||
danmuStopped bool // 弹幕是否被用户手动停止(手动停止不触发自动合并)
|
||||
recordStopped bool // 视频是否被用户手动停止
|
||||
mergeStarted bool // 自动合并是否已经启动
|
||||
doneAt int64 // 最近一次录制结束的时刻,纳秒 Unix(用于延迟清理这条记录)
|
||||
resumeUntil int64 // 断流后等待直播恢复的截止时刻,纳秒 Unix;0 表示没在等待
|
||||
// 弹幕文件在写盘时出过错(磁盘满、网络盘断开等)。文件是不完整的,
|
||||
// 拿它合并会得到一个缺弹幕的成片,所以本场跳过自动合并
|
||||
danmuWriteFailed bool
|
||||
doneAt int64 // 最近一次录制结束的时刻,纳秒 Unix(用于延迟清理这条记录)
|
||||
resumeUntil int64 // 断流后等待直播恢复的截止时刻,纳秒 Unix;0 表示没在等待
|
||||
}
|
||||
|
||||
// streamerInfo 的 map
|
||||
|
||||
Reference in New Issue
Block a user