Files
silo-server/internal/intromarkers/chapter.go

70 lines
1.7 KiB
Go

package intromarkers
import (
"regexp"
"strings"
"github.com/Silo-Server/silo-server/internal/models"
)
var introChapterPattern = regexp.MustCompile(`(?i)(^|\s)(intro|introduction|opening)(\s|:|$)`)
var generatedChapterPattern = regexp.MustCompile(`(?i)^chapter\s*\d+$`)
func DetectChapterIntro(chapters []models.MediaChapter) (Segment, bool) {
for i, chapter := range chapters {
title := strings.TrimSpace(chapter.Title)
if !isIntroChapterTitle(title) {
continue
}
if i > 0 && isIntroChapterTitle(strings.TrimSpace(chapters[i-1].Title)) {
continue
}
if i+1 < len(chapters) && isIntroChapterTitle(strings.TrimSpace(chapters[i+1].Title)) {
continue
}
end := chapter.EndSeconds
if i+1 < len(chapters) && chapters[i+1].StartSeconds > chapter.StartSeconds {
end = chapters[i+1].StartSeconds
}
duration := end - chapter.StartSeconds
if duration < 10 || duration > 180 {
continue
}
return Segment{
Start: chapter.StartSeconds,
End: end,
Confidence: 0.95,
Algorithm: ChapterAlgorithm,
}, true
}
return Segment{}, false
}
func isIntroChapterTitle(title string) bool {
if title == "" || generatedChapterPattern.MatchString(title) {
return false
}
if introChapterPattern.MatchString(title) {
return true
}
return isExplicitOPChapterTitle(title)
}
func isExplicitOPChapterTitle(title string) bool {
if !strings.HasPrefix(title, "OP") {
return false
}
if len(title) == len("OP") {
return true
}
switch next := title[len("OP")]; {
case next >= '0' && next <= '9':
return true
case next == ' ' || next == ':' || next == '-':
return strings.TrimSpace(title[len("OP")+1:]) != ""
default:
return false
}
}