✅ Builtin DASH and HLS Clearkey/DRM Support — Either append a #clearkey=<clearkey> fragment to the end of the URL or include a clearkeys json file or URL for DRM decryption
✅ High Performance — Uses streamlink API's for segment dowloading which significantly improves channel start times
✅ Highly Flexible — Can support standard HLS, Mpeg-DASH as well as DASH-DRM, Youtube, Twitch and other livestreaming services as channels
✅ Proxy and Proxy Bypass Support — Full support for passing proxy servers to bypass geo restrictions. Also support for bypassing proxy for specific URL's used in initial redirections or supply of clearkeys
✅ Custom Header Support — Currently supports the 'Referer' and 'Origin' headers by appending #referer=<URL> or #origin=<URL> (or both) fragments to the end of the URL
✅ Cookie Jar Support — Supports loading of cookie jar txt files in Netscape/Mozilla format
✅ Extended Stream Type Detection — Fallback option that checks MIME type of stream URL for streamlink plugin selection
✅ Streaming Radio Support with Song Information — Play streaming radio to your TV with song information displayed on your screen for ICY and HLS stream types
✅ Automated Stream Variant Detection — Detects streams with no video or no audio and muxes in the missing components for compatibility with most players
✅ Packed audio support for HLS streams — Automatically extracts timestamp data from Apple ID3 metadata in muxed HLS streams to ensure correct playback
✅ Support for SSAI/DAI — Supports streams using SCTE-35 type discontinuities for Server-Side or Dynamic Ad Injection
Dispatchwrapparr can be installed through the official Dispatcharr plugin repository.
You can find this in Dispatcharr under 'Plugins' -> 'Find Plugins' and searching for 'Dispatchwrapparr'.
Once the Dispatchwrapparr plugin is installed, configuring your first profile is easy!
Simply click 'Settings', complete the details in the form and then click 'Save'. When finished, click the 'Actions' tab and then click the 'Generate Stream Profile' button.
Note: For the new stream profile to appear, you will need to refresh Dispatcharr from your browser.
Dispatchwrapparr has many more features than those available in the form. The below documentation contains an exhaustive list of the capabilities of the plugin including how to achieve DRM decryption of HLS and DASH streams using clearkey(s).
Loading of the Dispatchwrapparr plugin creates two directories inside your /config directory, and installs the following files automatically:
/config/dispatchwrapparr/dispatchwrapparr.py/config/dispatchwrapparr/drmplugins/dashdrm.py/config/dispatchwrapparr/drmplugins/hlsdrm.py
Updates to Dispatchwrapparr, including the files above are handled via the official Dispatcharr plugin system.
URL fragment options can be used to tell Dispatchwrapparr what to do with a specific stream.
Important: When using URL fragment options, it is recommended that you remove "URL" from the "M3U Hash Key" option in Dispatcharr. This setting can be found in 'Settings' > 'Stream Settings'.
Below is a list of fragment options and their specifc usage:
| Fragment | Type | Example Usage | Description |
|---|---|---|---|
| clearkey | String | #clearkey=7ff8541ab5771900c442f0ba5885745f |
Defines the DRM Clearkey for decryption of stream content |
| header | String | #header=Authorization:Bearer%20XYZ&header=Origin:https://example.com |
Adds one or more custom HTTP headers using repeated header=<Header-Name>:<Header-Value> fragments |
| referer | String | #referer=https://somesite.com/ |
Defines the 'Referer' header to use for the stream URL |
| origin | String | #origin=https://somesite.com/ |
Defines the 'Origin' header to use for the stream URL |
| stream | String | #stream=1080p_alt |
Override Dispatchwrapparr automatic stream selection with a manual selection for the stream URL |
| novariantcheck | Bool | #novariantcheck=true |
Do not automatically detect audio-only or video-only streams and mux in blank video or silent audio for compatibility purposes. Just pass through the stream as-is (without video or audio). |
| ffmpeg_nocopyts | Bool | #ffmpeg_nocopyts=true |
Do not copy timestamps during stream muxing. May help solve playability issues with some streams. |
| noaudio | Bool | #noaudio=true |
Disables variant checking (-novariantcheck) and manually specifies that the stream contains no audio. This instructs Dispatchwrapparr to mux in silent audio. |
| novideo | Bool | #novideo=true |
Disables variant checking (-novariantcheck) and manually specifies that the stream contains no video. This instructs Dispatchwrapparr to mux in blank video. |
Important notes about fragment options:
- Fragments can be added to stream URL's inside m3u8 playlists, or added to stream URL's that are manually added as channels into Dispatcharr.
- Fragments are never passed to the origin. They are stripped off the URL before the actual stream is requested.
- Fragments will override any identical options specified by CLI arguments (Eg.
-clearkeys/#clearkeyor-stream/#stream). headerfragments can be repeated. If the same header appears more than once, the last value wins.- Multiple fragments can be used, and can be separated by ampersand. (Eg.
https://stream.url/stream.manifest#clearkey=7ff8541ab5771900c442f0ba5885745f&referer=https://somesite.com/&stream=1080p_alt).
Most DRM implementations apply consistent encryption across both audio and video streams by using the same key.
In this instance, you can simply just supply a clearkey. The HLSDRM and DASHDRM plugins will ignore any Key ID (KID) supplied to it.
To use a single clearkey for a particular stream using a URL fragment, simply create a custom m3u8 file that places the #clearkey= fragment at the end of the stream URL.
Below is an example that could be used for Channel 4 (UK):
#EXTM3U
#EXTINF:-1 group-title="United Kingdom" channel-id="Channel4London.uk" tvg-id="Channel4London.uk" tvg-logo="https://raw.githubusercontent.com/tv-logo/tv-logos/main/countries/united-kingdom/channel-4-uk.png", Channel 4
https://olsp.live.dash.c4assets.com/dash_iso_sp_tl/live/channel(c4)/manifest.mpd#clearkey=5ce85f1aa5771900b952f0ba58857d7aMore channels can be added to the same m3u8 file, and may also contain a mixture of DRM and non-DRM encrypted streams.
Simply upload your m3u8 file into Dispatcharr, select a Dispatchwrapparr stream profile, and it'll do the rest.
You can also add a cleakey fragment to the end of a URL of a stream being manually entered into Dispatcharr rather than administering a custom m3u8 file. This can be useful in testing.
For more complex streams that contain different clearkeys for video and audio, two keys can be provided in the order of 'video,audio'.
Streams which contain separate audio and video feeds, where only one is encrypted can specify 'none' as the key at the position.
The below table provides real world examples of how the DASHDRM and HLSDRM streamlink plugins process clearkeys.
| Example Fragment | Clearkey applied to VIDEO stream | Clearkey applied to AUDIO stream |
|---|---|---|
| #clearkey=a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0 | a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0 | a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0 |
| #clearkey=a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0,b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1 | a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0 | b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1 |
| #clearkey=a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0,none | a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0 | None (Unencrypted) |
| #clearkey=none,b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1 | None (Unencrypted) | b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1 |
The #stream fragment allows you to manually select a stream variant. Sometimes there may be occasions where you may want to manually select various stream variants depending on your preferences.
To find a list of available variants for a particular stream, simply run the following on the system running the dispatcharr docker container:
docker logs dispatcharr -f --since 0m | grep 'Available streams'
Once this command is running, play the stream and look at the output of the above command. It should show you a list of what variants are available.
Some examples of outputs are shown below:
[dispatchwrapparr] 2025-10-14 19:44:01,860 [info] Available streams: 270p_alt, 270p, 360p_alt, 360p, 480p_alt, 480p, 720p_alt2, 720p_alt, 720p, 1080p_alt, 1080p, worst, best
Once you have the stream you wish to use, eg. '1080p_alt', then all you need to do is append the fragment to the end of the stream URL as follows: https://some.stream.com/playlist.m3u8#stream=1080p_alt
In instances where a stream variants contain special characters such as '+' like in the second example above, you will need to ensure that the URL is encoded correctly. The '+' character is '%2B'.
For example, to select the '720p+a128k_48k' stream variant, then it would look like this: https://some.stream.com/playlist.m3u8#stream=720p%2Ba128k_48k
| Argument | Type | Example Values | Description |
|---|---|---|---|
| -i | Required | {streamUrl} |
Input stream URL from Dispatcharr. |
| -ua | Required | {userAgent} |
Input user-agent header from Dispatcharr. |
| -clearkeys | Optional | /path/to/clearkeys.json or https://url.to/clearkeys |
Supply a json file or URL containing URL -> Clearkey pairs. |
| -proxy | Optional | http://proxy.server:8080 |
Configure a proxy server. Supports HTTP and HTTPS proxies only. |
| -proxybypass | Optional | .domain.com,192.168.0.100:80 |
A comma delimited list of hostnames to bypass. Eg. '.local,192.168.0.44:90'. Do not use "*", this is unsupported. Whole domains match with '.' |
| -cookies | Optional | cookies.txt or /path/to/cookies.txt |
Supply a cookies txt file in Mozilla/Netscape format for use with streams |
| -customheaders | Optional | '{"Authentication": "Bearer abc123", "Header": "Value"}' |
Supply a JSON string containing custom header values |
| -streamlink_plugins | Optional | /path/to/streamlink/plugins |
Specify a custom path for any Streamlink plugins that you wish to load |
| -stream | Optional | 1080p_alt or worst |
Override Dispatchwrapparr automatic stream selection with a manual selection for the stream URL |
| -ffmpeg | Optional | /path/to/ffmpeg |
Specify the location of an ffmpeg binary for use in stream muxing instead of auto detecting ffmpeg binaries in PATH or in the same directory as dispatchwrapparr.py |
| -ffmpeg_transcode_audio | Optional | copy, eac3, aac, ac3 |
Enables the ffmpeg option to transcode audio. By default, dispatchwrapparr just copies the audio. |
| -ffmpeg_nocopyts | Optional | Do not copy timestamps during stream muxing. May help solve playability issues with some streams. | |
| -novariantcheck | Optional | Do not automatically detect audio-only or video-only streams and mux in blank video or silent audio for compatibility purposes. Just pass through the stream as-is (without video or audio). | |
| -noaudio | Optional | Disables variant checking (-novariantcheck) and manually specifies that the stream contains no audio. This instructs Dispatchwrapparr to mux in silent audio. | |
| -novideo | Optional | Disables variant checking (-novariantcheck) and manually specifies that the stream contains no video. This instructs Dispatchwrapparr to mux in blank video. | |
| -nosonginfo | Optional | Disables the display of song information for radio streams. Only a blank video will be muxed | |
| -loglevel | Optional | CRITICAL, ERROR, WARNING, INFO, DEBUG, NOTSET |
Sets the python and ffmpeg log levels. By default, the loglevel is set to 'INFO' |
Example: dispatchwrapparr.py -i {streamUrl} -ua {userAgent} -proxy http://your.proxy.server:3128 -proxybypass 192.168.0.55,.somesite.com -clearkeys clearkeys.json -loglevel INFO
The -clearkeys CLI argument is perfect for building custom API's or supplying json files that contain or supply automatically rotated URL -> Clearkey pairs to Dispatchwrapparr for DRM decryption.
Below is an example of what Dispatchwrapparr expects in the json API response or file contents:
{
"https://olsp.live.dash.c4assets.com/dash_iso_sp_tl/live/channel(c4)/manifest.mpd": "5ce85f1aa5771900b952f0ba58857d7a",
"https://some.other.stream.com/somechannel/*.mpd": "7ff8541ab5771900c442f0ba5885745f"
}For streams where the video and audio use different clearkeys, place them in a comma separated list. Eg:
{
"https://olsp.live.dash.c4assets.com/dash_iso_sp_tl/live/channel(c4)/manifest.mpd": "5ce85f1aa5771900b952f0ba58857d7a,7ff8541ab5771900c442f0ba5885745f",
"https://some.other.stream.com/somechannel/*.mpd": "7ff8541ab5771900c442f0ba5885745f"
}- A json file can be specified by just the filename (Eg.
-clearkeys clearkeys.json) where it will use the file 'clearkeys.json' within the same directory as dispatchwrapparr.py (Usually /data/dispatchwrapparr), or an absolute path to a json file (Eg.-clearkeys /path/to/clearkeys.json) - A json HTTP API can be specified by providing the URL to the -clearkeys argument (Eg.
-clearkeys https://someserver.local/clearkeys?getkeys) - When using the
-proxydirective, be careful to ensure that you add your clearkeys api endpoints into the-proxybypasslist if the endpoints are local to your network - Wildcards/Globs (*) are supported by Dispatchwrapparr for URL -> Clearkey matching. (Eg. The URL string could look like this and still match a Clearkey
https://olsp.live.dash.c4assets.com/*/live/channel(c4)/*.mpd) - Supports KID:KEY combinations, and comma delimited lists of clearkeys where multiple keys are required, although only the Clearkey is needed.
- If
-clearkeysis specified, and no stream URL matches a clearkey, Dispatchwrapparr will simply carry on as normal and treat the stream as if it's not DRM encrypted
You do not need to use Dispatchwrapparr in order to use the DASH and HLS DRM plugins. If you wish, you can use the dashdrm.py and hlsdrm.py plugins on their own with Streamlink.
Credit to titus-au whose work with DASH DRM and streamlink provided the basis by which the Dispatchwrapparr plugins are created.
In Jellyfin there are a number of settings related to m3u8 manifests.
Make sure that all options ("Allow fMP4 transcoding container", "Allow stream sharing", "Auto-loop live streams", "Ignore DTS (decoding timestamp)", and "Read input at native frame rate") are unticked/disabled.
This is a technology called SCTE-35 (aka. SSAI or DAI) which injects ads/commercial breaks into streams based on parameters such as geolocation and demographics etc.
While dispatchwrapparr has had some success in dealing with these types of streams, due to the way that some broadcasters implement SCTE-35 it may not always be stable.
Yes, maybe, but it depends on if you need to pass any custom arguments to it. Pass the -streamlink_plugins option to Dispatchwrapparr, specifying a custom directory to look for plugins in. In some circumstances, plugins may require Chromium based browsers for session tokens, and/or require additional arguments which Dispatchwrapparr will not pass through. The best option here is to just use Streamlink directly.
This script was made possible thanks to many wonderful python libraries and open source projects.
- titus-au for their awesome streamlink dashdrm plugin!
- Dispatcharr development community for making such an awesome stream manager!
- SergeantPanda for support and guidance on the Dispatcharr discord
- OkinawaBoss for creating the Dispatcharr plugin system and providing example code
- sethwv for building such an awesome plugin system in Dispatcharr
- Streamlink for their awesome API and stream handling capability
- matthuisman this guy is a local streaming legend in New Zealand. His code and work with streams has taught me heaps!
This project is licensed under the MIT License.
