npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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.

Readme

Scrypted Jellyfin Bridge

pipeline status npm version

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

  1. Scrypted → Plugins → Install Plugin → search for scrypted-jellyfin-bridge.
  2. 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).
  3. Jellyfin → Dashboard → Live TV → Tuner Devices → Add:
    • Type: M3U Tuner
    • URL: the M3U Tuner URL from Settings
  4. Jellyfin → TV Guide Data Providers → Add → XMLTV:
    • URL: the XMLTV Guide URL from Settings
  5. 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 instance

Releasing

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.0

License

MIT