Skip to content

Dispatcharr

Media Servers

Open-source IPTV stream management tool for consolidating sources, integrating with media centers, transcoding, and real-time monitoring

JavaScript Latest v0.25.1 · 11d ago Security brief →

Features

  • Consolidate multiple IPTV sources into a single interface
  • Integrate with Plex, Emby, or Jellyfin via HDHomeRun emulation
  • Generate and manage EPG guides (XMLTV) for personalized TV listings
  • Transcode streams in real‑time using FFmpeg profiles
  • Route all traffic through a VPN container for geo‑restricted content

Recent releases

View all 16 releases →
No immediate action
v0.25.1 Bug fix

Auto-Sync + XC playlists + DVR rule fix

Monitor
v0.25.0 Breaking risk
RBAC

Auto-Sync, fMP4, Comskip, DVR rules, Django

v0.24.0 Breaking risk
⚠ Upgrade required
  • DVR recordings now run in a dedicated worker pool; ensure the Celery configuration allows up to 20 concurrent threads.
  • HDHomeRun SSDP advertiser has been removed – manual tuner entry is required for discovery.
Security fixes
  • CVE-2026-41066 — Fixed external entity injection (XXE) in `lxml` by updating to 6.1.0
  • GHSA-2v35-w6hq-6mfw — Resolved uncontrolled recursion DoS in `@xmldom/xmldom` via upgrade to 0.8.13
  • GHSA-f6ww-3ggp-fr8h — Fixed XML injection via unvalidated `DocumentType` serialization in `@xmldom/xmldom` (v0.8.13)
Notable features
  • DVR Live Preview – watch recordings while they are still being recorded via FFmpeg HLS segmentation
  • VOD start/stop toast notifications and webhook integration
  • Editable default M3U profile patterns with live regex preview
Full changelog

✨ New Features

DVR Live Preview - Watch Recordings In Progress

  • Recordings can now be watched while they are still in progress. The Watch button on a recording card is enabled as soon as recording starts, and the in-app floating player begins playback from the start of the recording with the ability to scrub all the way to the live edge.
  • Once the recording finishes, the same Watch button serves the final MKV file - no page refresh required.
  • Live preview is made possible by a full rebuild of the recording pipeline on top of FFmpeg HLS segmentation. The new pipeline normalizes erratic IPTV source timestamps, shifts output to start at 0 for reliable segment boundary detection, and continues segment numbering after a server restart rather than overwriting earlier segments.
  • Stall detection watches both segment count and file modification time - if neither advances within the configured window, the recording ends cleanly rather than hanging until the scheduled end time.
  • End-time extensions are picked up automatically by a running recording without restarting FFmpeg.
  • VLC, Infuse, and other HLS-capable clients can also play the in-progress recording URL directly.
  • Up to 20 DVR recordings can now run simultaneously in a dedicated worker pool isolated from M3U and EPG background tasks, eliminating startup delays when background work is active.

VOD Start/Stop Notifications

  • The frontend now shows a toast notification when a VOD stream starts or stops, matching the existing live channel notifications.
  • VOD start and stop events are also written to the system event log and are now selectable as integration trigger events (webhook or script) on the Connect page.

Editable Default M3U Profile Patterns

  • The default profile in the M3U Profiles editor now exposes Search Pattern and Replace Pattern fields, allowing a URL transformation to be applied globally to every stream in the playlist (useful for replacing a local IP address, for example).
  • A live regex preview panel shows matched text as you type.
  • A "Reset to Defaults" button restores the pass-through patterns.

Channel Profiles Column in Users Table

  • Users can now see all channel profiles assigned to each user directly in the Users table. (Closes #819) - Thanks @damien-alt-sudo

Plugin Enhancements

  • Plugin install, update, downgrade, and overwrite buttons now show the download size of the plugin directly on the button when the repository manifest includes size data. A "Publish Your Plugin" link to the contributing guide was added to the plugin store toolbar. - Thanks @sethwv
  • Plugin warning and disclaimer UI has been extracted into shared components, normalizing the experience across all plugin action modals. - Thanks @sethwv

🔄 Changes & Improvements

Performance

  • TS proxy Redis traffic reduced significantly: buffer chunk writes now pipeline four Redis commands into a single round trip (down from five). Per-client stats writes are throttled to once per second per client instead of on every chunk delivered.
  • Channel table is faster and more responsive across the board:
    • Expanding or collapsing a channel row, reordering streams, adding streams, and removing streams all now complete in a single network request instead of three, with local store updates replacing full page-wide re-fetches.
    • Individual channel rows are now memoized so only the 1-2 affected rows re-render when a channel is expanded or collapsed.
    • Expanding a channel row now refreshes stream stats for that channel's streams via a lightweight delta endpoint instead of a full channel-list re-fetch, restoring the live-stats refresh behavior that earlier performance work had removed.
  • Streams table only refetches what changed: paginating or sorting the Streams table (on the Channels page) now hits only the page-data endpoint. The IDs list and filter options are no longer re-pulled on every pagination or sort change, cutting per-pagination traffic significantly on large stream libraries.
  • Channel stats no longer query the database on every tick: channel names and stream names are now stored in Redis at startup and read back directly during stats collection, eliminating multiple DB queries per stats tick for every active channel.
  • Stream name sorting now uses a database index: the stream list default sort (ORDER BY name) previously caused full table scans that could spill to disk on large stream libraries. A new index eliminates the disk spill entirely. (Fixes #1209)
  • Dedicated DVR worker pool: DVR recordings now run in a separate Celery worker with a thread pool (up to 20 concurrent threads), completely isolated from the default worker used for M3U refreshes, EPG parsing, and other background tasks. Up to 20 recordings can run concurrently with no startup delay regardless of background activity.
  • M3U operations: redundant database queries eliminated from M3U update progress tracking and auto-channel orphan cleanup.

Stats Page

  • Channel start and channel stop notifications now display both the channel name and the connected user (username + IP, or IP alone) on separate lines. When a channel starts, the redundant separate "new channel" and "new client" toasts are combined into a single "Channel started streaming" notification.
  • The Duration column in the Stats page connection table now shows a human-readable tooltip on hover (e.g., "2 hours, 15 minutes") instead of a raw seconds count.
  • The connected-at wall-clock time shown on the Stats page is now stable across polls rather than being recomputed on each response.

Channel Table

  • Column resizing now propagates to body cells via CSS, so memoized rows immediately reflect resize changes without a full re-render.
  • Expanding a channel row no longer also selects it.

HDHomeRun

  • The HDHomeRun SSDP advertiser (UDP multicast on port 1900) has been removed. None of the major HDHomeRun-aware clients (Plex, Emby, Jellyfin, Channels DVR, Kodi) use SSDP for tuner discovery, so the advertiser provided no practical benefit while running background threads at all times. Tuners can still be added manually by entering the Dispatcharr URL in any HDHomeRun-aware client.

Dependency Updates

  • psycopg2-binary 2.9.11 → 2.9.12
  • lxml 6.0.3 → 6.1.0 (security patch; see Security section)
  • sentence-transformers 5.4.0 → 5.4.1
  • @xmldom/xmldom 0.8.12 → 0.8.13 (security patch; see Security section)

🐛 Bug Fixes

EPG

  • Fixed EPG program times being shifted by the host system's UTC offset when /etc/localtime is bind-mounted from a non-UTC host into the container. Every EPG program time was read back N hours wrong and written to the XML output incorrectly. (Fixes #651)
  • Fixed EPG channel name truncation: EPG sources with long <display-name> values (e.g. event-based channels with a description appended to the name) would crash the channel-parse task with a database error and silently discard the entire batch. Names exceeding 512 characters are now truncated with a warning instead of aborting the import. (Fixes #1134)

Xtream Codes

  • Fixed the XC player_api.php user_info block missing the active_cons field. Enigma2 clients (XStreamity, XKlass) read this field unconditionally and would crash with a key error when it was absent. max_connections was also hardcoded to the system-wide tuner count for every user, ignoring per-user stream limit configuration. Both values are now reported correctly. (Fixes #990)

DVR

  • Fixed empty show and season folders being left behind on disk after a recording is deleted.

Channels

  • Fixed channel start/stop notifications not showing the channel name - the "channel stopped" toast was displaying the raw channel UUID instead of the name.
  • Fixed the channel create/edit form clearing all filled-in fields when a new channel group is created from within the form. The newly created group is also automatically selected after being saved. (Fixes #545)

Plugins

  • Fixed plugin discovery running a full filesystem scan on every Connect event when zero plugins were installed. Discovery now runs at most once per worker process lifetime regardless of whether any plugins are present.

Streaming & Stats

  • Fixed channel start/client connect notifications being suppressed for all connections present in the first stats poll after page load, even for streams that had genuinely started after the page loaded.

🔒 Security

  • HDHomeRun discovery endpoints now respect the M3U_EPG network access policy. The lineup endpoint enumerates every channel name and per-channel stream URL; clients outside the M3U_EPG allowlist now receive 403 Forbidden rather than being served the full lineup, matching what the Network Access settings UI already advertised. Operators with a restrictive M3U_EPG policy will see HDHR discovery blocked for off-LAN clients after upgrading; loosen the policy if remote HDHR access is needed.
  • Removed dangerouslySetInnerHTML from the M3U Profile regex preview. The "Matched Text" preview was building an HTML string from user input and rendering it unsafely. A crafted sample input (admin-only, so self-XSS only) could inject arbitrary HTML into the preview pane. The preview now uses React elements so user input is always treated as plain text.
  • Authorization added to DVR recording playback endpoints. The recording file and HLS playlist endpoints now require an authenticated session and enforce a per-user channel-access check before serving any bytes. Unauthenticated requests receive 403 Forbidden.
  • Updated lxml 6.0.3 → 6.1.0, resolving:
    • CVE-2026-41066: External entity injection (XXE) in XML parsing.
  • Updated frontend npm dependencies to resolve 5 audit vulnerabilities (1 moderate, 4 high):
    • Updated @xmldom/xmldom 0.8.12 → 0.8.13, resolving high uncontrolled recursion in XML serialization causing DoS (GHSA-2v35-w6hq-6mfw), high XML injection via unvalidated DocumentType serialization (GHSA-f6ww-3ggp-fr8h), high XML node injection via unvalidated processing instruction serialization (GHSA-x6wf-f3px-wcqx), and high XML node injection via unvalidated comment serialization (GHSA-j759-j44w-7fr8)
    • Updated postcss 8.5.6 → 8.5.13, resolving moderate XSS via unescaped </style> in CSS stringify output (GHSA-qx2v-qp2m-jg93)

:warning: Known Issues

  • Launchpad PPAs are currently down (ongoing as of release). The base Docker image build pulls several packages from Launchpad PPAs; while the outage persists, a new base image cannot be built. This release ships using the previous base image, so nothing is missing - however, the Python package updates listed in the Dependency Updates section (psycopg2-binary, lxml, sentence-transformers) are not included in this build. Once Launchpad is restored, the base image will be rebuilt and a follow-up release will include those updates.
v0.23.0 Breaking risk
Security fixes
  • CVE-2026-33033
  • CVE-2026-33034
  • CVE-2026-4292
Notable features
  • Plugin Hub with repository management, installation, updates, and GPG/SHA256 signature verification
  • EPG Historical Data with configurable days forward/back parameters and per-user defaults
  • Performance improvements: XC response time reduced from 2.5-4s to 250-450ms on large deployments via query optimization
Full changelog

✨ New Features

EPG Historical Data

  • The EPG output now supports a "Days back" parameter, letting third-party players that request past program schedules receive the data they need. (Closes #1154)
  • A Days forward and Days back control is now available in the EPG URL builder on the Channels page.
  • Per-user defaults for both values can be configured in the User Settings modal and are applied automatically when no URL parameter is present.

Plugin Hub

  • Administrators can now browse, install, and update plugins directly from their source repositories via a new Plugin Hub page in Settings. (Closes #393) — Thanks @sethwv:
    • Install plugins directly from the hub with SHA256 integrity verification.
    • Update managed plugins when a newer version is available, with version compatibility checks enforced at install time.
    • Browse available plugins with name, description, version, author, and icon.
    • Plugins installed from a repo are tracked as "managed" — source, version, prerelease status, and deprecation state are all visible in the UI.
    • Add plugin repositories by manifest URL. The official Dispatcharr Plugins repository is pre-configured; third-party repos are supported with an optional GPG public key.
    • Manifest signatures are verified via GPG, with signature status displayed per-repo.
    • Preview a repository URL before adding it — validates the manifest and reports plugin count and signature status without saving anything.
    • Configure an automatic manifest refresh interval (or disable it entirely). Refreshes run as a background task.

🔄 Changes & Improvements

Performance

  • M3U playlist generation, EPG generation, and XC live stream listing are now significantly faster on large deployments by fetching related data in a single database query instead of one per channel. On deployments with ~2,000 channels, XC live stream response time drops from ~2.5–4 s to ~250–450 ms. (Closes #1127) — Thanks @xBOBxSAGETx
  • EPG generation performance improved further with additional query optimizations across EPG channel, grid, and XC EPG endpoints, reducing overall EPG generation time by about %15 on large deployments.
  • M3U playlist generation with the direct=true option no longer issues a separate database query per channel for stream data.
  • XC live stream listing no longer performs a database lookup for each channel that has no group assigned — that lookup now happens at most once per request regardless of how many ungrouped channels are present.

M3U Parsing

  • The M3U parser has been rewritten to handle complex and non-standard M3U files more reliably. Entries with extra directive lines between the stream info and URL are now parsed correctly instead of being corrupted or silently dropped.
  • Added support for the #EXTGRP directive. When a stream has no group-title attribute, the group name from an #EXTGRP line is used as the fallback. (Closes #1088)
  • Stream names now use the display title from the #EXTINF line as the primary name, falling back to tvg-name. Providers that put the human-readable title after the comma will now show the correct name. (Fixes #1081)
  • Added accumulation of #EXTVLCOPT directives per entry, stored in the stream's custom properties for future use and API access.
  • Parsing is approximately 10% faster on large M3U files.

User Settings Modal

  • The User Settings modal has been redesigned with a tabbed layout. Settings are now grouped into Account, Permissions, EPG Defaults, and API & XC tabs, replacing the previous two-column layout.

EPG Improvements

  • The EPG response cache now correctly shares entries between semantically equivalent requests (e.g., a user default of 7 days forward and an explicit ?days=7 URL parameter now hit the same cache entry).
  • EPG scanning now automatically removes stale EPG entries that are no longer present in the upstream source — as long as they aren't mapped to any channel. This prevents unbounded database growth over time.
  • Improved BOM handling when importing EPG source files: the XML declaration is now located reliably regardless of leading BOM markers, whitespace, or other encoding preambles.

URL Builder Popovers

  • The HDHR, M3U, and EPG URL builder popovers in the Channels table now open with a brief description of their purpose. Toggle switches have been updated with a proper label and description layout, and alignment has been corrected to match standard form conventions.

All-in-One (AIO) Container

  • AIO containers now connect to the internal PostgreSQL instance via a Unix domain socket instead of TCP, improving local connection speed and reliability. Existing configurations pointing to localhost or 127.0.0.1 are migrated automatically. — Thanks @JCBird1012

Output Bitrate Tracking

  • The output bitrate statistic is now smoothed and written to the database at most once every 30 seconds instead of on every FFmpeg stats tick (~twice per second). This significantly reduces database write pressure. Short-lived streams that stop before a stable reading is established no longer overwrite previously accurate measurements.

Floating Video Player

  • The native video controls (timeline, play/pause, volume) are now hidden by default when a live stream starts and only appear on hover.

API & Swagger UI

  • The Swagger UI authorization dialog now includes an ApiKeyAuth entry alongside the existing JWT entry, with descriptive text referencing the relevant endpoints for both authentication methods.
  • Several API schema definitions have been corrected: the EPG import endpoint now documents its request body; the bulk logo delete endpoint now shows the delete_files field; the batch EPG assignment endpoint correctly marks the EPG link field as nullable; and the integrations subscription endpoint now has a documented request body.

Frontend Refactoring

  • Multiple form components have been refactored to improve maintainability, with business logic extracted into dedicated utility modules each covered by unit tests. Mantine compound component references have been updated to current conventions. — Thanks @nick4810

Dependency Updates

  • djangorestframework 3.16.1 → 3.17.1
  • requests 2.33.0 → 2.33.1
  • gevent 25.9.1 → 26.4.0
  • rapidfuzz 3.14.3 → 3.14.5

🐛 Bug Fixes

TV Guide & EPG

  • Fixed "Record One" in the TV Guide always scheduling the recording on the first channel matching the program's EPG ID, rather than the channel the user actually clicked. When multiple channels share the same EPG source, the intended channel was silently ignored. (Fixes #1140) — Thanks @fezster

Streaming & VOD Proxy

  • Fixed live stream hiccups caused by nginx silently buffering TS proxy data to disk instead of streaming it directly to the client.
  • Fixed race conditions in the VOD proxy that caused connection limit counters to go permanently negative, allowing more simultaneous connections than the configured profile limit. (Closes #1125) — Thanks @firestaerter3
  • Fixed a connection leak in the VOD proxy where upstream provider connections were not properly closed when a stream ended due to an error before the first data chunk was sent.
  • Fixed manual stream selection from the Stats page not enforcing M3U profile connection limits in multi-worker deployments. The connection counter was not updated after a manual stream switch, causing subsequent capacity checks to report incorrect values and bypass the full-profile guard.
  • Fixed automatic stream rotation not updating connection limit counters, the same class of issue as the manual stream switch bug above.
  • Fixed stream switch state in Redis occasionally reflecting a URL that wasn't actually in use. State is now only written after a switch is confirmed to succeed.

Stats Page

  • Fixed the Active Stream dropdown on the Stats page not updating when a stream switch occurs.

Channels

  • Fixed bulk channel edit returning a 500 error when the request body included a streams list. (Fixes #883)

M3U & File Uploads

  • Fixed uploading a local M3U file with no expiration date set causing a validation error from the API.

Logo Management

  • Fixed the logo cache hanging indefinitely when fetching from a slow or dripping remote server. Downloads now enforce a 10-second total deadline and a 5 MB size cap. Also fixed a race condition where a slow or failed download could result in two simultaneous fetch attempts for the same URL.

User Management

  • Fixed the XC Password field in the User modal being editable by standard users even though any changes would be silently discarded on save. The field and its generate button are now disabled with an explanatory message for non-admin users.

Docker & Container Shutdown

  • Fixed docker stop resulting in a forced kill (exit 137 / SIGKILL). All child processes — including uWSGI workers, Celery, Daphne, and Redis — are now gracefully stopped in order, and the shutdown wait adapts to how quickly they exit rather than using a fixed delay. — Thanks @Shokkstokk for the initial fix!

🔒 Security

  • Hardened global API permissions: All API endpoints now require admin access by default. Endpoints that legitimately require lower permission levels (standard user read access, public streaming) have been explicitly annotated. Streaming proxy endpoints remain accessible without authentication, with access controlled by per-stream-type network allow-lists.
  • Fixed missing network access checks in the VOD proxy: VOD streaming endpoints were not enforcing the STREAMS network policy, unlike the equivalent live stream proxy endpoints. This has been corrected.
  • Fixed path traversal vulnerability in file uploads: The M3U account upload, logo upload, and backup upload endpoints accepted client-supplied filenames without sanitization. A crafted filename could have written files outside the intended upload directory. All three paths now strip directory components and validate the resolved destination. Note: exploiting this required admin credentials.
  • Prevented standard users from modifying admin-managed account fields via the user self-edit endpoint. Fields such as xc_password are now stripped server-side for non-admin requests.
  • Added rate limiting to login endpoints: Both login endpoints now enforce a limit of 3 requests per minute per IP address (sliding window). Excessive attempts receive a 429 Too Many Requests response. Attempts across both endpoints count against the same per-IP limit.
  • Removed unused CORS credentials setting: CORS_ALLOW_CREDENTIALS has been removed from the CORS configuration. Dispatcharr authenticates via JWT tokens and API keys — not cookies — so this setting had no meaningful effect.
  • Updated frontend npm dependencies to resolve 6 high-severity vulnerabilities:
  • Updated Django 6.0.3 → 6.0.4 to address 5 CVEs:
    • CVE-2026-33033: Potential denial-of-service via crafted multipart uploads
    • CVE-2026-33034: Uploads with a missing or understated Content-Length header could bypass the upload memory size limit
    • CVE-2026-4292: Privilege abuse in the Django admin list-editable interface
    • CVE-2026-3902: Header spoofing via underscore/hyphen conflation in ASGI requests
    • CVE-2026-4277: Privilege abuse in Django admin inline interfaces
v0.22.0 New feature
Notable features
  • Per-user concurrent stream limits
  • Username display on stats page
  • TLS/mTLS database support

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

About

Stars
3,385
Forks
238
Languages
JavaScript Python Shell

Install & Platforms

Install via
docker

Community & Support

Beta — feedback welcome: [email protected]