From ee7a5e0b4ca6ce4cac9f76f772ffbe8d012487cd Mon Sep 17 00:00:00 2001 From: Sleeps Date: Tue, 6 Oct 2026 17:59:22 +0100 Subject: [PATCH] Document plugin-managed library indexing --- README.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5316a68..b2724da 100644 --- a/README.md +++ b/README.md @@ -167,19 +167,15 @@ On the first run after enabling routing, existing captions are classified. A cap Jellyfin can now be the source of truth for media identity, metadata and frame sampling. -Configure a server API key and the libraries you want Scene Search to manage: +Configure the Jellyfin server connection used by the Python worker. Library selection is normally managed from the Jellyfin plugin UI: ```env JELLYFIN_URL=http://jellyfin-server:8096 JELLYFIN_API_KEY=replace-me -# Preferred for normal use: -JELLYFIN_LIBRARIES=Movies,TV,Home Videos - -# Optional exclusions, also honoured by --all-libraries: -JELLYFIN_EXCLUDE_LIBRARIES=Music,Photos - -# Legacy single-library setting, still supported when JELLYFIN_LIBRARIES is empty: +# Optional CLI defaults only. The Jellyfin plugin stores its own selected library ids. +JELLYFIN_LIBRARIES= +JELLYFIN_EXCLUDE_LIBRARIES= JELLYFIN_LIBRARY= JELLYFIN_TRICKPLAY_WIDTH=320 @@ -362,6 +358,14 @@ When `SCENE_API_KEY` is set, search and thumbnail endpoints accept either `Autho The API intentionally runs with one worker. Multiple workers would each load their own copy of the embedding model into GPU memory. +The API also exposes authenticated Jellyfin-management endpoints used by the plugin: + +- `GET /api/jellyfin/libraries` — list visible libraries and indexed counts. +- `POST /api/jellyfin/index` — start one background indexing job for selected library ids. +- `GET /api/jellyfin/index/status` — report live library/item/frame/sync progress. + +Only one plugin-triggered indexing job can run at a time. Search requests return a temporary 503 while that job owns the shared embedding model. + ## Jellyfin 12 search plugin The repository now includes a thin Jellyfin 12 plugin under `jellyfin-plugin/`. Jellyfin 12's external search-provider API accepts real Jellyfin item IDs with relevance scores, while Jellyfin core applies the requesting user's library visibility and access filtering afterwards. The plugin therefore sends the search text to the local Python API and returns the matching Jellyfin item IDs; it does not run AI models inside Jellyfin. @@ -390,6 +394,13 @@ Open **Dashboard → Plugins → Scene Search** and configure: - API key: the same value as `SCENE_API_KEY`. - Require a search prefix: enabled by default. - Prefix: `scene:`. +- Indexed libraries: tick the Jellyfin libraries that Scene Search should manage. + +The plugin asks the Python service for the libraries visible to the configured Jellyfin API key and shows their current indexed item/frame counts. The selected library ids are saved in Jellyfin's plugin configuration, so normal operation does not require editing `.env`. + +Use **Index selected libraries** to start a backend indexing job. The plugin shows the current library, item and frame progress and polls until the job completes. When ingestion finishes, the backend automatically rebuilds Meilisearch, so newly indexed vectors are searchable without a separate `sync-meili` command. + +Plugin-triggered indexing reuses the API process's existing SigLIP instance and blocks semantic searches while the indexing job owns the model, avoiding a second GPU copy on the same machine. The prefix is intentional for the first rollout. Jellyfin 12 uses non-empty external-provider results instead of its built-in SQL search results. While only a test library is indexed, making Scene Search answer every query could hide ordinary Jellyfin results that have not been indexed yet.