From f3e00939c4b5e2bac4cb27e613a3da71795d029c Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Thu, 16 Apr 2026 11:05:59 +0200 Subject: [PATCH] Add chapter type detection via regexes --- transcoder/src/info.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/transcoder/src/info.go b/transcoder/src/info.go index cc2e445a..282ed39f 100644 --- a/transcoder/src/info.go +++ b/transcoder/src/info.go @@ -11,6 +11,7 @@ import ( "mime" "os" "path/filepath" + "regexp" "strconv" "strings" "sync" @@ -174,6 +175,26 @@ const ( Preview ChapterType = "preview" ) +// regex stolen from https://github.com/intro-skipper/intro-skipper/wiki/Chapter-Detection-Patterns +var chapterTypePatterns = []struct { + kind ChapterType + pattern *regexp.Regexp +}{ + {kind: Recap, pattern: regexp.MustCompile(`(?i)\b(re?cap|sum+ary|prev(ious(ly)?)?|(last|earlier)(\b\w+)?|catch\bup)\b`)}, + {kind: Intro, pattern: regexp.MustCompile(`(?i)\b(intro|introduction|op|opening)\b`)}, + {kind: Credits, pattern: regexp.MustCompile(`(?i)\b(credits?|ed|ending|outro)\b`)}, + {kind: Preview, pattern: regexp.MustCompile(`(?i)\b(preview|pv|sneak\b?peek|coming\b?(up|soon)|next\b+(time|on|episode)|extra|teaser|trailer)\b`)}, +} + +func identifyChapterType(name string) ChapterType { + for _, matcher := range chapterTypePatterns { + if matcher.pattern.MatchString(name) { + return matcher.kind + } + } + return Content +} + func ParseFloat(str string) float32 { f, err := strconv.ParseFloat(str, 32) if err != nil { @@ -327,8 +348,7 @@ func RetriveMediaInfo(ctx context.Context, path string, sha string) (*MediaInfo, Name: c.Title(), StartTime: float32(c.StartTimeSeconds), EndTime: float32(c.EndTimeSeconds), - // TODO: detect content type - Type: Content, + Type: identifyChapterType(c.Title()), } }), Fonts: MapStream(mi.Streams, ffprobe.StreamAttachment, func(stream *ffprobe.Stream, i uint32) string {