- C# 83.1%
- Python 8.1%
- HTML 4.6%
- JavaScript 2%
- Nix 1.4%
- Other 0.8%
|
All checks were successful
Release / release (push) Successful in 5m15s
- Update README.md with troubleshooting steps for plugin discovery issues, specifically addressing missing whitelisted assemblies and stale directories. - Update `flake.nix` to include `dotnetSdk` in the release package check and configure necessary .NET environment variables. - Enhance `tools/verify_release_package.py` by adding a simulation of Jellyfin's plugin discovery process, including validation of `meta.json` status and assembly whitelisting. - Implement assembly load validation using the `dotnet` CLI to ensure that plugin DLLs are loadable and compatible. |
||
|---|---|---|
| .forgejo | ||
| docs | ||
| nix | ||
| src/Jellyfin.Plugin.Infinity | ||
| tests/Jellyfin.Plugin.Infinity.Tests | ||
| tools | ||
| web-patches | ||
| .gitignore | ||
| AGENTS.md | ||
| flake.lock | ||
| flake.nix | ||
| Jellyfin.Plugin.Infinity.sln | ||
| manifest.json | ||
| meta.json | ||
| README.md | ||
Jellyfin Infinity
Jellyfin plugin for federated media search across the local Jellyfin library, resolver-backed on-demand media, and configured remote providers.
The current implementation includes:
- Plugin scaffold with configuration and admin page registration.
- Custom API endpoints under
/Infinity. - Source adapter model with capability discovery.
- Search sources for the local library, resolver-backed music/video, AIOStreams, TMDb, MusicBrainz, and manual Torznab/Prowlarr candidates.
- Native Jellyfin
/Search/Hints,/Items,/Artists, detail, children, playback, artwork, and subtitle augmentation for resolver-backed on-demand music and video. - Ranking, deduplication, source health, partial failure reporting, and request privacy controls.
- Dockerized Chromium/CDP verification for the real Jellyfin Web interface.
- Documentation for API contracts, source adapter development, and testing.
The current native replacement path covers on-demand music and video search, details, playback handoff, resolver-backed artwork, and subtitle lookup. Resolver-backed media paths are accepted only under configured safe music/video roots. If a resolver item is queued, downloading, waiting for scan, unavailable, or mismatched, Infinity returns a structured status payload for the web overlay instead of allowing raw Jellyfin playback errors to surface.
Status
This is a local plugin build installed into the active Jellyfin 10.11.11 configuration. The repository includes smoke tooling for real Jellyfin Web verification.
Target
- Jellyfin server: 10.11.x first.
- Runtime: .NET 9.
- Client integration: custom API plus native Jellyfin search response augmentation for compatible clients.
Build
dotnet restore Jellyfin.Plugin.Infinity.sln
dotnet build Jellyfin.Plugin.Infinity.sln
dotnet test Jellyfin.Plugin.Infinity.sln
Nix
nix develop
nix flake check
nix build .#plugin
nix build .#release
nix run .#verify-infinity-status-patch
The flake fetches Jellyfin 10.11.11 reference assemblies from the official
portable server archive, so the ignored local lib/ directory is not required
for Nix builds. The dev shell also provides Python, Node.js, Chromium, and
verification wrappers:
verify-infinity-status-patch
verify-jellyfin-web-ui-cdp --base-url http://10.1.11.21:8096 --db /jellyfin.db --out-dir /out --query Deadmau5
verify-on-demand-status-ui --base-url http://10.1.11.21:8096 --credentials /path/to/credentials.json --out-dir /out
verify-infinity-parity --base-url http://10.1.11.21:8096 --credentials /path/to/credentials.json --out-dir /out
The live Chromium/CDP wrappers pass the Nix-provided Chromium binary to the
Python scripts. Set INFINITY_CHROME=/path/to/chrome when testing against a
different browser binary.
Releases
Stable releases are generated by pushing a semantic version tag such as
v1.0.0. The tag version is written into the plugin meta.json, release
manifest, artifact name, and download URL.
Nightly releases are generated by pushing to the indev branch. The release
workflow creates a prerelease tag using UTC month/day/year/hour/minute format,
for example v61620261017. The Jellyfin plugin version and artifact name use
the compatible dotted form, for example 6.16.2026.1017, and publish the same
installable plugin zip, checksum, and manifest assets as a stable release.
Every indev push also refreshes the moving indev-latest prerelease. Use
that channel on development or test Jellyfin servers when you want a fixed
repository URL that always points at the newest indev build.
Install a Release
Use a release whose targetAbi is compatible with your Jellyfin server. This
plugin currently targets Jellyfin 10.11.11 and publishes that three-part ABI
string so servers reporting 10.11.11 do not reject the package as newer than
the running server.
Install From the Jellyfin Catalog
-
Open the Jellyfin dashboard as an administrator.
-
Go to Plugins > Repositories.
-
Add a repository named
Infinitywith the release manifest URL:https://git.ds.reinitialized.net/reinitialized/infinity/releases/download/<release-tag>/manifest.jsonReplace
<release-tag>with the stable or nightly release tag, for examplev1.0.0orv61620261017.To track the newest indev build instead, use the moving channel manifest:
https://git.ds.reinitialized.net/reinitialized/infinity/releases/download/indev-latest/manifest.jsonOnly use
indev-lateston development or test servers. Indev builds use timestamp-based versions that may sort newer than stable releases. -
Save the repository, then go to Plugins > Catalog.
-
Select
Infinity, install the available version, and restart Jellyfin when prompted. -
After Jellyfin restarts, confirm
Infinityappears under Plugins > My Plugins.
If Jellyfin logs Plugin "installed": "Infinity" but Infinity disappears
after restart, check the startup log for Registering whitelisted assemblies for plugin "Infinity" and Loaded plugin: "Infinity". If those lines are absent,
Jellyfin did not discover a loadable Infinity_* folder under its program-data
plugins path. Remove stale or partial Infinity_* directories from that path
and reinstall. For the official container this path is usually
/config/plugins; for package installs it is usually
/var/lib/jellyfin/plugins.
Install Manually
-
Download these assets from the release page:
Jellyfin.Plugin.Infinity_<version>.zipJellyfin.Plugin.Infinity_<version>.zip.sha256
-
Set the plugin version from the release asset name:
VERSION=1.0.0 PLUGIN_DIR="/var/lib/jellyfin/plugins/Infinity_${VERSION}" -
Verify the archive before installing it:
sha256sum -c "Jellyfin.Plugin.Infinity_${VERSION}.zip.sha256" -
Stop Jellyfin.
-
Create a plugin directory under the Jellyfin configuration directory:
sudo mkdir -p "$PLUGIN_DIR"For Docker installs, use the host path that is mounted as the container's Jellyfin config directory. The plugin directory inside that config mount is usually
plugins/Infinity_${VERSION}. -
Extract the release archive into that directory:
sudo unzip "Jellyfin.Plugin.Infinity_${VERSION}.zip" -d "$PLUGIN_DIR" -
For package-based Linux installs, make sure Jellyfin owns the extracted files:
sudo chown -R jellyfin:jellyfin "$PLUGIN_DIR" -
Start Jellyfin, then confirm
Infinityappears under Plugins > My Plugins.
Web Verification
With Nix:
nix run .#verify-jellyfin-web-ui-cdp -- \
--base-url http://10.1.11.21:8096 \
--db /jellyfin.db \
--out-dir /out \
--query Deadmau5
The same wrappers are available inside nix develop.
The Docker-based smoke command is still useful when you want to run inside the Playwright container:
docker run --rm --network host \
-v /root/jellyfin-infinity/tools/verify_jellyfin_web_ui_cdp.py:/work/verify_jellyfin_web_ui_cdp.py:ro \
-v /root/docker/jellyfin/config/data/jellyfin.db:/jellyfin.db:ro \
-v /tmp/infinity-webtest:/out \
mcr.microsoft.com/playwright:v1.53.0-noble \
python3 /work/verify_jellyfin_web_ui_cdp.py \
--base-url http://10.1.11.21:8096 \
--db /jellyfin.db \
--out-dir /out \
--query Deadmau5
For broader live parity checks with credentials:
python3 tools/verify_infinity_parity.py \
--base-url http://10.1.11.21:8096 \
--credentials /path/to/credentials.json \
--out-dir /out
Or with a read-only Jellyfin database, which creates and cleans up a temporary non-admin Jellyfin user for the run:
python3 tools/verify_infinity_parity.py \
--base-url http://10.1.11.21:8096 \
--db /path/to/jellyfin.db \
--out-dir /out
That script covers the current manual smoke cases:
- Music:
Deadmau5search and album/detail rendering. - Video:
SkinamarinkandMarie & Galimust either provide safe playback with preferred-language subtitles or a clear preparing/mismatch response. - Search:
Hostage Situationmust not return duplicate One Piece episode cards,Marie & Galimust not show duplicate indistinguishable video cards,Beyond the Boundarymust return video before music, and query transitions must not leave stale Marie cards visible.
API Endpoints
GET /Infinity/SourcesPOST /Infinity/SearchGET /Infinity/Search?q=alien&limit=20GET /Infinity/Results/{resultId}POST /Infinity/Actions/{action}
See docs/api.md for request and response examples.