music indexer: generate video poster thumbnails

Each indexed video gets a compressed poster (a frame grab ~10% in, capped at
30s, scaled ≤600px q5 like covers), written to cache/<rel>/posters/<file>.jpg
and recorded as `poster` on the meta.videos entry. The posters dir is wiped and
regenerated on each rebuild so orphans (removed videos) don't linger. New
`postersSaved` status counter.

Served by a new sidecar route GET /api/music/poster?path=<rel>&file=<video>
(image/jpeg, ETag=<v>, 304, 404 when none) — path-safe via basename.

Verified end-to-end on a real .mp4: video-only album → manifest {tracks:0,
videos:1}, meta.poster set, 14 KB poster on disk. MUSIC_API.md documents the
poster field + endpoint + postersSaved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-27 14:38:15 +00:00
co-authored by Claude Opus 4.8
parent d5b3dbb473
commit 10d7b6a425
3 changed files with 72 additions and 2 deletions
+12 -2
View File
@@ -106,7 +106,8 @@ Returns the album's `meta.json`. Sends `ETag: <v>`; a request with `If-None-Matc
"title": "Live Shit: Seattle", // from the container title tag, if any
"durationSec": 8130,
"width": 1280,
"height": 720
"height": 720,
"poster": "posters/1989 - Seattle.mp4.jpg" // present when a poster was generated (see §2.3.1)
}
// …
]
@@ -124,6 +125,15 @@ GET /api/music/cover?path=<rel>
Compressed JPEG (≤600px on the long edge, ~3080 KB). Sends `ETag: <v>`; `If-None-Match: <v>``304`.
Only meaningful when the manifest entry has `"cover": true`.
#### 2.3.1 Video poster
```
GET /api/music/poster?path=<rel>&file=<video filename>
```
A compressed frame grab for a video (≤600px, same treatment as covers), taken ~10% into the clip. `file` is
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.4 Discography (artist album grouping)
For artist folders (manifest entry with `"disco": true`), this returns a map of **album folder → release
@@ -174,7 +184,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, "discographies": 3,
"tracksIndexed": 320, "videosIndexed": 4, "coversSaved": 12, "postersSaved": 4, "discographies": 3,
"currentPath": "Albums/AC-DC/[1980] Back in Black",
"error": null
}