Add structured lyrics storage and indexing (line/word timing, byte offsets)

Adds database.InsertLyrics/GetSongStructuredLyrics storing multiple
lyrics entries per song with per-line start times and, when the
source provides it, word-level cues carrying precomputed UTF-8 byte
offsets. library.IndexLyrics wires this into the scanner: embedded
plain-text tags are stored unsynced, and a same-basename sidecar .lrc
(plain or Enhanced) is parsed and stored synced, with word cues when
present. IndexFile now takes the media file's absolute path so lyrics
indexing can locate sidecar files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014r98AtcBbevpscWLsfwVvv
This commit is contained in:
2026-08-23 08:16:42 -05:00
co-authored by Claude Sonnet 5
parent efedf1a6bf
commit e48f063f03
7 changed files with 446 additions and 8 deletions
+2 -2
View File
@@ -170,7 +170,7 @@ func (s *Scanner) indexOne(ctx context.Context, folderID, absPath, relPath strin
if err != nil {
return false, false, err
}
song, err := library.IndexFile(s.DB, mf, tags)
song, err := library.IndexFile(s.DB, mf, absPath, tags)
if err != nil {
return false, false, err
}
@@ -199,7 +199,7 @@ func (s *Scanner) indexOne(ctx context.Context, folderID, absPath, relPath strin
if err != nil {
return false, false, err
}
song, err := library.IndexFile(s.DB, mf, tags)
song, err := library.IndexFile(s.DB, mf, absPath, tags)
if err != nil {
return false, false, err
}