Files
acfunlive-remake/recordjsonl_test.go
T
tamakyi e44dfa3a4a 补测试:重排对「本程序自己录的弹幕」零影响;多分段跨段冲突被一并解决
核实「弹道重排会不会影响正常录播的合并」时补的两个用例:

- recordjsonl_test.go:用真正的录制写入器 danmuWriter 造 500 条(密集,平均 0.22
  秒一条),再按合并流程读回 jsonl 重排 —— 弹道变化 0 条、宽度变化 0 条。录制侧
  写文件完全不经过 relayoutLanes,只有合并渲染前会重排,所以磁盘上的
  .ass/.nick.ass/.jsonl 一个字节都不变,单段自动合并的成片和以前完全一致。
  (顺带记下录制时确实会丢弹幕:500 条里 1 条因为 100 条弹道全满被丢弃,
  jsonl 里根本没有它,重排也不会把它变出来。)

- layout_test.go:多分段(断流重连)拼接时 remapJsonlTimes 只改时间、保留各段
  自己算的弹道,两段都从 0 号弹道起排,时间压缩到同一根轴后必然互相压。新增用例
  先断言这种拼法本来就撞,再断言重排后冲突为 0 —— 这是重排唯一会改变输出的场景,
  方向是变好,不是回归。
2026-09-25 18:28:52 +08:00

94 lines
2.6 KiB
Go
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.
package main
import (
"bufio"
"encoding/json"
"os"
"path/filepath"
"testing"
"github.com/orzogc/acfundanmu"
)
// 用真正的录制写入器(danmuWriter)产生 jsonl,再按合并的流程重排一遍,
// 验证「本程序自己录下来的弹幕」合出来和以前一模一样(弹道、宽度都不变)。
// 这也是手动合并与自动合并的分水岭:录制侧写文件完全不经过 relayoutLanes,
// 只有合并渲染前会重排,所以磁盘上的 .ass/.nick.ass/.jsonl 一个字节都不变。
func TestLiveRecordingPathUnaffected(t *testing.T) {
dir := t.TempDir()
cfg := acfundanmu.SubConfig{Title: "测试直播", PlayResX: 1920, PlayResY: 1080,
FontSize: 48, StartTime: 1700000000000000000}
ass := filepath.Join(dir, "live.ass")
w := newDanmuWriter("liveid", "stream", cfg, ass)
texts := []string{"来啦", "这首歌好听", "主播加油啊", "打卡打卡", "哈哈哈哈哈哈哈哈哈",
"这条弹幕稍微长一点看看弹道到底怎么排"}
for i := 0; i < 500; i++ {
relMs := int64(i) * 220 // 平均 0.22 秒一条,够密集
c := &acfundanmu.Comment{Content: texts[i%len(texts)]}
c.SendTime = (cfg.StartTime + relMs*1e6) / 1e6
c.UserID = int64(2000 + i%9)
c.Nickname = "观众" + string(rune('A'+i%9))
c.Avatar = "http://example.invalid/a.png"
w.write(c)
}
w.close()
f, err := os.Open(filepath.Join(dir, "live.jsonl"))
if err != nil {
t.Fatal(err)
}
defer f.Close()
sc := bufio.NewScanner(f)
sc.Buffer(make([]byte, 1<<20), 1<<20)
var meta danmuMeta
first := true
var recs []danmuRecord
for sc.Scan() {
if first {
json.Unmarshal(sc.Bytes(), &meta)
first = false
continue
}
var r danmuRecord
if json.Unmarshal(sc.Bytes(), &r) == nil {
recs = append(recs, r)
}
}
type snap struct{ lane, width int }
before := make([]snap, len(recs))
for i, r := range recs {
before[i] = snap{r.Lane, r.Width}
}
relayoutLanes(recs, meta)
laneDiff, widthDiff := 0, 0
for i, r := range recs {
if r.Lane != before[i].lane {
laneDiff++
if laneDiff <= 3 {
t.Logf("第 %d 条弹道变了:%d → %d", i, before[i].lane, r.Lane)
}
}
if r.Width != before[i].width {
widthDiff++
}
}
t.Logf("录制产生 %d 条弹幕(含空内容 %d 条),重排后弹道变化 %d 条、宽度变化 %d 条",
len(recs), countEmpty(recs), laneDiff, widthDiff)
if laneDiff != 0 || widthDiff != 0 {
t.Errorf("正常录制的弹幕重排后不应有任何变化")
}
}
func countEmpty(recs []danmuRecord) int {
n := 0
for _, r := range recs {
if r.Content == "" {
n++
}
}
return n
}