mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-07 13:56:37 +08:00
优化视频头尾跳过功能
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/truewhile/MeBox/internal/model"
|
||||
)
|
||||
|
||||
// 章节标题只有「有语义」时才认。西文关键词要词边界,否则 Options / Weekend
|
||||
// 这类标题会被误判成片头/片尾;中文日文按子串匹配。
|
||||
func TestChapterTitleKind(t *testing.T) {
|
||||
cases := []struct {
|
||||
title string
|
||||
want string
|
||||
}{
|
||||
{"Intro", model.SegmentKindIntro},
|
||||
{"Opening", model.SegmentKindIntro},
|
||||
{"Opening Title", model.SegmentKindIntro},
|
||||
{"OP", model.SegmentKindIntro},
|
||||
{"NCOP", model.SegmentKindIntro},
|
||||
{"片头", model.SegmentKindIntro},
|
||||
{"オープニング", model.SegmentKindIntro},
|
||||
|
||||
{"Recap", model.SegmentKindRecap},
|
||||
{"Previously on", model.SegmentKindRecap},
|
||||
{"前情提要", model.SegmentKindRecap},
|
||||
{"回顾", model.SegmentKindRecap},
|
||||
{"あらすじ", model.SegmentKindRecap},
|
||||
|
||||
{"End Credits", model.SegmentKindCredits},
|
||||
{"Credits", model.SegmentKindCredits},
|
||||
{"Ending", model.SegmentKindCredits},
|
||||
{"ED", model.SegmentKindCredits},
|
||||
{"Outro", model.SegmentKindCredits},
|
||||
{"片尾", model.SegmentKindCredits},
|
||||
{"エンディング", model.SegmentKindCredits},
|
||||
|
||||
{"Next Episode", model.SegmentKindPreview},
|
||||
{"Next time", model.SegmentKindPreview},
|
||||
{"Preview", model.SegmentKindPreview},
|
||||
{"预告", model.SegmentKindPreview},
|
||||
{"次回予告", model.SegmentKindPreview},
|
||||
|
||||
// 无语义或容易误判的标题一律不认:猜错比没有数据更糟。
|
||||
{"", ""},
|
||||
{" ", ""},
|
||||
{"Chapter 01", ""},
|
||||
{"Chapter 12", ""},
|
||||
{"Options", ""},
|
||||
{"Weekend", ""},
|
||||
{"Main Menu", ""},
|
||||
{"Menu", ""},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
if got := chapterTitleKind(tc.title); got != tc.want {
|
||||
t.Errorf("chapterTitleKind(%q) = %q, want %q", tc.title, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestChaptersToSegmentsOnlyKeepsSemanticChapters(t *testing.T) {
|
||||
rows := chaptersToSegments([]ProbeChapter{
|
||||
{Index: 0, StartMs: 0, EndMs: 95_000, Title: "Chapter 01"},
|
||||
{Index: 1, StartMs: 228_664, EndMs: 246_143, Title: "Opening"},
|
||||
{Index: 2, StartMs: 246_500, EndMs: 247_400, Title: "Recap"}, // 不足 chapterMinMs
|
||||
{Index: 3, StartMs: 3_431_000, EndMs: 0, Title: "End Credits"},
|
||||
})
|
||||
if len(rows) != 2 {
|
||||
t.Fatalf("rows = %#v, want 2 (Opening + End Credits)", rows)
|
||||
}
|
||||
if rows[0].Kind != model.SegmentKindIntro || rows[0].StartMs != 228_664 || rows[0].EndMs != 246_143 {
|
||||
t.Fatalf("first row = %#v", rows[0])
|
||||
}
|
||||
if rows[1].Kind != model.SegmentKindCredits || rows[1].StartMs != 3_431_000 || rows[1].EndMs != 0 {
|
||||
t.Fatalf("second row = %#v", rows[1])
|
||||
}
|
||||
for _, row := range rows {
|
||||
if row.Source != SegmentSourceFFprobe {
|
||||
t.Fatalf("source = %q, want %q", row.Source, SegmentSourceFFprobe)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestChaptersToSegmentsIgnoresUntitledAndNegativeChapters(t *testing.T) {
|
||||
rows := chaptersToSegments([]ProbeChapter{
|
||||
{Index: 0, StartMs: 0, EndMs: 60_000, Title: ""},
|
||||
{Index: 1, StartMs: -1, EndMs: 60_000, Title: "Intro"},
|
||||
})
|
||||
if len(rows) != 0 {
|
||||
t.Fatalf("rows = %#v, want none", rows)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeSegmentSourceFallsBackToAuto(t *testing.T) {
|
||||
cases := map[string]string{
|
||||
"": SegmentSourceAuto,
|
||||
" ": SegmentSourceAuto,
|
||||
"auto": SegmentSourceAuto,
|
||||
"AUTO": SegmentSourceAuto,
|
||||
"ffprobe": SegmentSourceFFprobe,
|
||||
" FFprobe ": SegmentSourceFFprobe,
|
||||
"theintrodb": SegmentSourceTheIntroDB,
|
||||
"TheIntroDB": SegmentSourceTheIntroDB,
|
||||
"aniskip": SegmentSourceAuto, // 未知值按 auto 处理
|
||||
}
|
||||
for input, want := range cases {
|
||||
if got := NormalizeSegmentSource(input); got != want {
|
||||
t.Errorf("NormalizeSegmentSource(%q) = %q, want %q", input, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user