feat(library): detección de intro/créditos post-scan (skip segments)
Some checks failed
CI / Test (push) Failing after 6m18s
CI / Build (push) Successful in 1m32s
CI / Build-1 (push) Successful in 1m55s
CI / Build-2 (push) Successful in 1m33s
CI / Build-3 (push) Successful in 1m32s
CI / Build-4 (push) Successful in 1m35s
CI / Build-5 (push) Successful in 1m33s
CI / Lint (push) Failing after 2m50s
CI / Coverage (push) Successful in 2m58s
CI / Vet (push) Successful in 2m7s
Some checks failed
CI / Test (push) Failing after 6m18s
CI / Build (push) Successful in 1m32s
CI / Build-1 (push) Successful in 1m55s
CI / Build-2 (push) Successful in 1m33s
CI / Build-3 (push) Successful in 1m32s
CI / Build-4 (push) Successful in 1m35s
CI / Build-5 (push) Successful in 1m33s
CI / Lint (push) Failing after 2m50s
CI / Coverage (push) Successful in 2m58s
CI / Vet (push) Successful in 2m7s
Tras cada scan, localiza la intro (OP) y los créditos (ED) comparando fingerprints chromaprint entre episodios de la misma temporada — reimplementación limpia del enfoque de Intro Skipper: índice invertido de uint32, alineamiento por shifts, Hamming ≤6/32, región contigua más larga (15-120s intro / 15-450s créditos). Películas: inicio de créditos por rachas de blackframe (solo keyframes, -skip_frame nokey) que llegan al final del fichero. - fpcalc se auto-descarga de las releases estáticas de acoustid (linux/macos/windows, ~2MB) con el mismo patrón que ffmpeg/ffprobe. - Resultados cacheados como sidecar .skipseg.json (mtime + versión de algoritmo); solo los ficheros nuevos trabajan. - Submit a /api/internal/agent/skip-segments DESPUÉS del library-sync, en dos fases (episodios primero, películas después) para que la fase rápida no espere a los blackframe lentos sobre NAS. - Agrupación por (dir + título-pre-SxxEyy + season): los títulos parseados arrastran nombre de episodio y tags de release. - Gotcha cazado en vivo: fpcalc -length sale sin drenar el pipe; hay que cerrar nuestro read-end o ffmpeg queda bloqueado para siempre. - config: library.skip_detect (default true, backfill) y scan_interval default 24h → 1h (estilo Plex).
This commit is contained in:
parent
59da949a53
commit
a710bc1626
11 changed files with 1223 additions and 5 deletions
|
|
@ -193,7 +193,7 @@ type LibraryConfig struct {
|
|||
FFmpegPath string `toml:"ffmpeg_path"` // optional explicit path (used by the HLS streaming transcoder)
|
||||
BackupDir string `toml:"backup_dir"` // for replaced files
|
||||
AutoScan bool `toml:"auto_scan"` // enable daily auto-scan in daemon (default true)
|
||||
ScanInterval string `toml:"scan_interval"` // e.g. "24h", "12h", "6h" (default "24h")
|
||||
ScanInterval string `toml:"scan_interval"` // e.g. "1h", "6h", "24h" (default "1h", like Plex/Jellyfin periodic scans)
|
||||
AllowDelete bool `toml:"allow_delete"` // allow web UI to request file deletion from disk
|
||||
|
||||
// Sidecar caching: extract text subtitles (WebVTT) and thumbnail frames once
|
||||
|
|
@ -204,6 +204,13 @@ type LibraryConfig struct {
|
|||
CacheSubtitles bool `toml:"cache_subtitles"` // default true
|
||||
CacheThumbnails bool `toml:"cache_thumbnails"` // default true
|
||||
|
||||
// Skip-segment detection: after each scan, find intro/credits ranges by
|
||||
// comparing chromaprint audio fingerprints between episodes of a season
|
||||
// (plus black-frame credits for movies) and submit them to the web so the
|
||||
// player can offer "Skip intro" / "Skip credits". Cached per file; only
|
||||
// new files do work. Default true.
|
||||
SkipDetect bool `toml:"skip_detect"`
|
||||
|
||||
// Trickplay: at scan time, build ONE montage JPEG of frames sampled every
|
||||
// Interval seconds (+ a JSON manifest), cached in .unarr next to the media.
|
||||
// The web scrubber shows tiles from it — no live ffmpeg during playback, so
|
||||
|
|
@ -314,10 +321,11 @@ func Default() Config {
|
|||
},
|
||||
Library: LibraryConfig{
|
||||
AutoScan: true,
|
||||
ScanInterval: "24h",
|
||||
ScanInterval: "1h",
|
||||
Workers: 8,
|
||||
CacheSubtitles: true,
|
||||
CacheThumbnails: true,
|
||||
SkipDetect: true,
|
||||
Trickplay: TrickplayConfig{
|
||||
Enabled: true,
|
||||
Interval: "10s",
|
||||
|
|
@ -396,6 +404,9 @@ func applyDefaults(cfg *Config, meta toml.MetaData) {
|
|||
if !meta.IsDefined("library", "cache_thumbnails") {
|
||||
cfg.Library.CacheThumbnails = true
|
||||
}
|
||||
if !meta.IsDefined("library", "skip_detect") {
|
||||
cfg.Library.SkipDetect = true
|
||||
}
|
||||
// Trickplay defaults ON for configs predating these keys (small sidecar JPEG;
|
||||
// makes the scrubber instant + contention-free). Explicit `enabled = false`
|
||||
// is respected via meta.IsDefined.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue