Dont store overlapping chapterprints

This commit is contained in:
Zoe Roux 2026-04-15 23:26:21 +02:00
parent df0c2ced13
commit ae8485fdb0
No known key found for this signature in database
2 changed files with 25 additions and 18 deletions

View File

@ -172,12 +172,6 @@ func (s *MetadataService) matchByOverlap(
continue
}
fpId, err := s.StoreChapterprint(ctx, fp)
if err != nil {
slog.WarnContext(ctx, "failed to store intro chapterprint", "err", err)
continue
}
slog.InfoContext(ctx, "Identified intro", "start", intro.StartFirst, "duration", intro.Duration)
candidates = append(candidates, Chapter{
Id: info.Id,
@ -185,24 +179,18 @@ func (s *MetadataService) matchByOverlap(
EndTime: float32(intro.StartFirst + intro.Duration),
Name: "",
Type: Intro,
FingerprintId: &fpId,
Fingerprint: fp,
MatchAccuracy: new(int32(intro.Accuracy)),
})
}
for _, cred := range credits {
segData, err := ExtractSegment(fingerprint.End, cred.StartFirst, cred.StartFirst+cred.Duration)
fp, err := ExtractSegment(fingerprint.End, cred.StartFirst, cred.StartFirst+cred.Duration)
if err != nil {
slog.WarnContext(ctx, "failed to extract credits segment", "err", err)
continue
}
fpId, err := s.StoreChapterprint(ctx, segData)
if err != nil {
slog.WarnContext(ctx, "failed to store credits chapterprint", "err", err)
continue
}
endOffset := info.Duration - samplesToSec(len(fingerprint.End))
slog.InfoContext(ctx, "Identified credits", "start", endOffset+cred.StartFirst, "duration", cred.Duration, "end_offset", endOffset)
candidates = append(candidates, Chapter{
@ -211,7 +199,7 @@ func (s *MetadataService) matchByOverlap(
EndTime: float32(endOffset + cred.StartFirst + cred.Duration),
Name: "",
Type: Credits,
FingerprintId: &fpId,
Fingerprint: fp,
MatchAccuracy: new(int32(cred.Accuracy)),
})
}
@ -234,10 +222,12 @@ func mergeChapters(info *MediaInfo, candidates []Chapter) []Chapter {
merged := false
for i := range chapters {
if absF32(chapters[i].StartTime-cand.StartTime) < MergeWindowSec {
if absF32(chapters[i].StartTime-cand.StartTime) < MergeWindowSec &&
absF32(chapters[i].EndTime-cand.EndTime) < MergeWindowSec {
if chapters[i].Type == Content {
chapters[i].Type = cand.Type
}
chapters[i].Fingerprint = cand.Fingerprint
chapters[i].FingerprintId = cand.FingerprintId
chapters[i].MatchAccuracy = cand.MatchAccuracy
merged = true
@ -246,12 +236,19 @@ func mergeChapters(info *MediaInfo, candidates []Chapter) []Chapter {
}
if !merged {
if cand.StartTime < MergeWindowSec {
cand.StartTime = 0
}
if absF32(float32(info.Duration)-cand.EndTime) < MergeWindowSec {
cand.EndTime = float32(info.Duration)
}
chapters = insertChapter(chapters, Chapter{
Id: info.Id,
StartTime: cand.StartTime,
EndTime: cand.EndTime,
Name: "",
Type: cand.Type,
Fingerprint: cand.Fingerprint,
FingerprintId: cand.FingerprintId,
MatchAccuracy: cand.MatchAccuracy,
}, info.Duration)
@ -340,6 +337,14 @@ func (s *MetadataService) saveChapters(ctx context.Context, infoId int32, chapte
// Insert new chapters
for _, c := range chapters {
if c.FingerprintId == nil && c.Fingerprint != nil {
fpId, err := s.StoreChapterprint(ctx, c.Fingerprint)
if err != nil {
slog.WarnContext(ctx, "failed to store intro chapterprint", "err", err)
} else {
c.FingerprintId = new(fpId)
}
}
_, err = tx.Exec(ctx,
`insert into gocoder.chapters(id, start_time, end_time, name, type, fingerprint_id, match_accuracy)
values ($1, $2, $3, $4, $5, $6, $7)`,

View File

@ -152,10 +152,12 @@ type Chapter struct {
EndTime float32 `json:"endTime" db:"end_time"`
/// The name of this chapter. This should be a human-readable name that could be presented to the user.
Name string `json:"name" db:"name"`
/// The type value is used to mark special chapters (openning/credits...)
/// The type value is used to mark special chapters (opening/credits...)
Type ChapterType `json:"type" db:"type"`
/// Reference to the chapterprint used for fingerprint matching.
FingerprintId *int32 `json:"-" db:"fingerprint_id"`
FingerprintId *int32 `json:"-" db:"fingerprint_id"`
/// Only used internally, never fetched from db.
Fingerprint []uint32 `json:"-" db:"-"`
/// Accuracy of the fingerprint match (0-100).
MatchAccuracy *int32 `json:"matchAccuracy,omitempty" db:"match_accuracy"`
}