music indexer: index track lyrics (.lrc/.txt sidecars + embedded)
Each track's lyrics are resolved and cached at cache/<rel>/lyrics/<file>.<lrc|txt>, with the format recorded as `lyrics: 'lrc'|'txt'` on the meta.tracks entry. Precedence: external "<base>.lrc" > external "<base>.txt" > embedded tag (lyrics / lyrics-<lang> / unsyncedlyrics — ffprobe now reads all format tags). Content that contains [mm:ss] lines is stored as lrc even from a .txt/embedded source. Only track-matching sidecars affect the version signature (a stray notes.txt is ignored). Lyrics dir is wiped+regenerated per rebuild; new `lyricsIndexed` counter. Served by GET /api/music/lyrics?path=<rel>&file=<track> (text/plain + X-Lyrics-Format header, ETag=<v>, 304, 404 when none). Verified end-to-end: external .lrc wins over embedded; embedded → plain txt; unmatched .txt ignored. MUSIC_API.md documents the field + endpoint. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+16
-2
@@ -96,7 +96,8 @@ Returns the album's `meta.json`. Sends `ETag: <v>`; a request with `If-None-Matc
|
||||
"album": "Back in Black",
|
||||
"track": "1",
|
||||
"year": "1980",
|
||||
"durationSec": 312
|
||||
"durationSec": 312,
|
||||
"lyrics": "lrc" // present if lyrics exist: "lrc" = synced, "txt" = plain (see §2.3.2)
|
||||
}
|
||||
// …
|
||||
],
|
||||
@@ -134,6 +135,19 @@ A compressed frame grab for a video (≤600px, same treatment as covers), taken
|
||||
the video's filename within `<rel>` (URL-encode it). Sends `ETag: <v>`; `If-None-Match: <v>` → `304`; `404`
|
||||
when the video has no poster. Only request it when that video's `meta.videos[]` entry has a `poster` field.
|
||||
|
||||
#### 2.3.2 Lyrics
|
||||
|
||||
```
|
||||
GET /api/music/lyrics?path=<rel>&file=<track filename>
|
||||
```
|
||||
Plain-text body of the track's lyrics; the `X-Lyrics-Format` header is `lrc` (synced, `[mm:ss.xx]`-timestamped)
|
||||
or `txt` (plain). Sends `ETag: <v>`; `If-None-Match: <v>` → `304`; `404` when the track has no lyrics. Only
|
||||
request it when that track's `meta.tracks[]` entry has a `lyrics` field (`"lrc"`/`"txt"`).
|
||||
|
||||
Sources, in precedence order (indexed at build time): an external **`<track basename>.lrc`** > external
|
||||
**`<track basename>.txt`** > **embedded** lyrics in the audio tags (`lyrics` / `lyrics-<lang>` /
|
||||
`unsyncedlyrics`). A `.txt` (or embedded) whose text actually contains `[mm:ss]` lines is served as `lrc`.
|
||||
|
||||
### 2.4 Discography (artist album grouping)
|
||||
|
||||
For artist folders (manifest entry with `"disco": true`), this returns a map of **album folder → release
|
||||
@@ -184,7 +198,7 @@ GET /api/music/reindex/status → IndexStatus snapshot
|
||||
"running": true,
|
||||
"startedAt": 1785034701973, "finishedAt": null,
|
||||
"foldersScanned": 45, "albumsBuilt": 12, "albumsSkipped": 3,
|
||||
"tracksIndexed": 320, "videosIndexed": 4, "coversSaved": 12, "postersSaved": 4, "discographies": 3,
|
||||
"tracksIndexed": 320, "videosIndexed": 4, "coversSaved": 12, "postersSaved": 4, "lyricsIndexed": 45, "discographies": 3,
|
||||
"currentPath": "Albums/AC-DC/[1980] Back in Black",
|
||||
"error": null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user