feat(api): SHA-256 and Chromaprint fingerprints for the library (M5.5)
ci / api / api (push) Successful in 27s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 58s

A background Fingerprinter runs after every scan and at startup, one file
at a time, filling media_files.sha256 and track_fingerprints (fpcalc raw,
first 120 s). Without fpcalc only SHA-256 is computed and files stay
queued for Chromaprint. Changing a file's content resets its prints.
Similarity() compares raw prints with a ±80-point alignment search; it is
the basis for duplicate detection in the upload queue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Opus 5.5 committed 2026-10-20 13:37:05 +03:00
1 parent ed063d3763
commit 9b50038bb4
9 files changed
+406 -6

No files matched your search

+10
View File
@@ -106,11 +106,21 @@ func run() error {
log.Warn("STREAM_SIGNING_KEY is not set: cover and stream links will break on restart")
}
covers := library.NewCovers(libStore, libSvc, cfg.FFmpegPath, filepath.Join(cfg.CacheDir, "covers"), log)
fingerprints := library.NewFingerprinter(libStore, library.FPCalc{Bin: cfg.FPCalcPath, Timeout: time.Minute},
func(ctx context.Context, sourceID uuid.UUID) (string, error) {
src, err := libStore.GetSource(ctx, sourceID)
if err != nil {
return "", err
}
return libSvc.Root(src)
}, log)
scanner.AfterScan = func(ctx context.Context) {
covers.Run(ctx)
indexer.Trigger()
fingerprints.Trigger(ctx)
}
go covers.Run(ctx) // альбомы, оставшиеся без обложки с прошлого запуска
fingerprints.Trigger(ctx)
concurrency := cfg.TranscodeConcurrency
if concurrency <= 0 {