scrypted-jellyfin-bridge
v0.0.6
Published
Expose every Scrypted camera as a Jellyfin Live TV channel — auto-generated M3U tuner playlist and XMLTV guide, no per-camera configuration.
Maintainers
Readme
Scrypted Jellyfin Bridge
Expose every camera in Scrypted as a Jellyfin Live TV channel — automatically.
The plugin serves a dynamically generated M3U tuner playlist and XMLTV guide covering every Scrypted camera that has the Rebroadcast (prebuffer) mixin enabled. Configure Jellyfin once with two URLs; cameras added, removed, or renamed in Scrypted appear on Jellyfin's next tuner/guide refresh. No per-camera M3U files, no copying RTSP URLs, and rebroadcast token changes self-heal.
Why
Jellyfin has no native camera support (jellyfin#7629) — the usual workaround is a hand-maintained M3U file per camera pointing at an RTSP URL copied out of some camera UI. Scrypted already normalizes every camera brand into stable rebroadcast RTSP streams; this plugin turns those into Jellyfin channels with zero per-camera work.
Install
- Scrypted → Plugins → Install Plugin → search for
scrypted-jellyfin-bridge. - Open the plugin's Settings — the M3U and XMLTV URLs are shown there, ready to copy (they include the plugin's access token; see below).
- Jellyfin → Dashboard → Live TV → Tuner Devices → Add:
- Type: M3U Tuner
- URL: the M3U Tuner URL from Settings
- Jellyfin → TV Guide Data Providers → Add → XMLTV:
- URL: the XMLTV Guide URL from Settings
- Refresh the guide (Dashboard → Scheduled Tasks → Refresh Guide).
Use Scrypted's HTTP port in the URLs (the default the plugin shows) — Jellyfin will reject Scrypted's self-signed HTTPS certificate.
Diagnostics
Open http://<scrypted-host>:<port>/endpoint/scrypted-jellyfin-bridge/ in a
browser while logged in to Scrypted. It lists every discovered channel and
— more importantly — every camera that was not bridged, with the reason
(usually: the Rebroadcast mixin isn't enabled on that camera).
Access token
All bridge endpoints require an access token, passed as ?token=… in the
URLs. Without it, devices on your LAN could anonymously enumerate your cameras
and harvest their stream URLs.
- The token is generated once when the plugin is first installed.
- It never changes on its own — not on plugin restarts or updates, not on Scrypted reboots, and not when cameras are added, disabled, re-enabled, or removed.
- The only thing that changes it is the Regenerate Access Token button
in the plugin's Settings. After regenerating, the old URLs stop working
(requests get
403) and you must update the tuner and guide URLs in Jellyfin with the new values from Settings.
Regenerate the token if you ever suspect it leaked (e.g. a shared screenshot of your Jellyfin tuner config).
Settings
| Setting | Default | Purpose |
| ----------------------- | --------- | ------------------------------------------------ |
| M3U Tuner URL | readonly | Copy into Jellyfin's M3U tuner |
| XMLTV Guide URL | readonly | Copy into Jellyfin's XMLTV guide provider |
| Regenerate Access Token | button | Invalidate the current token and mint a new one |
| Channel Group | Cameras | M3U group-title shown in Jellyfin |
| Excluded Cameras | none | Cameras that should not become channels |
| Snapshot Channel Logos | on | Serve each camera's snapshot as its channel logo |
Security model
Be aware of what this plugin does and does not protect:
- With the token: the M3U (camera names + tokenized RTSP stream URLs), the XMLTV guide, and live snapshot logos are all retrievable. Treat the bridge URLs like a password.
- Anyone with access to your Jellyfin can watch all bridged cameras. Use Jellyfin's per-user Live TV permissions if some Jellyfin users shouldn't see cameras.
- Everything travels cleartext HTTP/RTSP on your LAN (same as Scrypted's rebroadcast streams themselves). Do not port-forward Scrypted or these endpoints to the internet; if you need remote access, use a VPN.
- The camera stream URLs contain Scrypted's rebroadcast path tokens, which persist across restarts. If those ever leak, regenerating the bridge token does not rotate them — they are managed by Scrypted's Rebroadcast plugin.
Requirements & notes
- Each camera needs the Rebroadcast (prebuffer) mixin enabled — cameras without it are skipped (the diagnostics page tells you which and why).
- Channel numbers are assigned once per camera and persisted, so they never reshuffle as cameras come and go.
- Multi-stream cameras: the first advertised stream (the default) becomes the channel.
Development
npm install
npm test # jest against a mocked @scrypted/sdk
npm run typecheck
npm run build # scrypted-webpack (rollup)
npm run scrypted-deploy <scrypted-host> # push to a local instanceReleasing
The git tag is the single source of truth for the published version —
package.json stays at 0.0.0 and CI stamps the real version from the tag
before npm publish:
git tag v0.1.0 && git push origin v0.1.0License
MIT
