fix(stream): /critico review fixes for the sidecar cache
- ExtractSubtitlesVTTMulti: distrust output when ffmpeg is killed by signal (45-min timeout on a too-big remux) — a truncated WebVTT passed the len>0 check and got cached as a silently-incomplete track until the media mtime changed. Skip all output on signal-kill; keep it on a clean non-zero exit. - stream handlers: read the sidecar cache BEFORE the ffmpegPath guard so a pre-warmed sub/thumbnail still serves if ffmpeg was removed after the cache was filled. - scan: log when the prewarm is skipped because ffmpeg is unavailable (matches the daemon; CLAUDE.md wants bootstrap to log on every branch). - unexport sidecarDir/subtitleCachePath/thumbnailCachePath (no external callers). - prewarm: surface a sample error in the summary so a systemic ffmpeg failure is distinguishable from one corrupt file. - add unit tests: codec whitelist, cache paths, mtime freshness, atomic write, thumb-position dedup.
This commit is contained in:
parent
1c8cc1c409
commit
bc6f85bf39
6 changed files with 228 additions and 37 deletions
|
|
@ -60,6 +60,8 @@ func PrewarmSidecars(ctx context.Context, cache *LibraryCache, opts PrewarmOptio
|
|||
var wg sync.WaitGroup
|
||||
var mu sync.Mutex
|
||||
subCached, thumbCached, failed := 0, 0, 0
|
||||
var sampleErr string // first extraction error, surfaced in the summary so a
|
||||
// systemic ffmpeg failure (vs one corrupt file) is diagnosable from "N failed".
|
||||
|
||||
for i := 0; i < workers; i++ {
|
||||
wg.Add(1)
|
||||
|
|
@ -77,9 +79,12 @@ func PrewarmSidecars(ctx context.Context, cache *LibraryCache, opts PrewarmOptio
|
|||
jctx, cancel := context.WithTimeout(ctx, 60*time.Second)
|
||||
img, err := mediainfo.ExtractThumbnailJPEG(jctx, opts.FFmpegPath, j.path, j.posSec, j.width)
|
||||
cancel()
|
||||
if err != nil { // seek past EOF / corrupt → skip silently
|
||||
if err != nil { // seek past EOF / corrupt → skip
|
||||
mu.Lock()
|
||||
failed++
|
||||
if sampleErr == "" {
|
||||
sampleErr = err.Error()
|
||||
}
|
||||
mu.Unlock()
|
||||
continue
|
||||
}
|
||||
|
|
@ -120,6 +125,9 @@ func PrewarmSidecars(ctx context.Context, cache *LibraryCache, opts PrewarmOptio
|
|||
if err != nil {
|
||||
mu.Lock()
|
||||
failed += len(todo)
|
||||
if sampleErr == "" {
|
||||
sampleErr = err.Error()
|
||||
}
|
||||
mu.Unlock()
|
||||
continue
|
||||
}
|
||||
|
|
@ -174,7 +182,11 @@ func PrewarmSidecars(ctx context.Context, cache *LibraryCache, opts PrewarmOptio
|
|||
|
||||
wg.Wait()
|
||||
if subCached > 0 || thumbCached > 0 || failed > 0 {
|
||||
log.Printf("[prewarm] %d subtitles, %d thumbnails cached, %d failed", subCached, thumbCached, failed)
|
||||
if failed > 0 && sampleErr != "" {
|
||||
log.Printf("[prewarm] %d subtitles, %d thumbnails cached, %d failed (e.g. %s)", subCached, thumbCached, failed, sampleErr)
|
||||
} else {
|
||||
log.Printf("[prewarm] %d subtitles, %d thumbnails cached, %d failed", subCached, thumbCached, failed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue