Skip to content

Plugin Authors

xcentaurix edited this page Oct 15, 2026 · 2 revisions

For plugin authors

A provider plugin registers itself under a scheme when it is imported:

from Plugins.SystemPlugins.StreamProxyCockpit import StreamProxy

def resolveStream(channel_id, sref):
    # runs on the main thread while Enigma2 zaps: do not wait for the network here
    return StreamProxy.registerChannel("mytv", channel_id, url_refresher=lookupStreamUrl, refresh_on_failure=True)

StreamProxy.registerProvider("mytv", resolveStream)

Bouquet entries

The channels are services of type 4097 whose stream is mytv%3a//<channel id>:

4097:0:1:<sid>:<tsid>:<onid>:<namespace>:0:0:0:mytv%3a//<channel id>:<channel name>

When such a service is played or recorded, Enigma2 calls resolveStream(channel_id, sref). It returns the address of the proxy for the channel, or an empty string if the channel cannot be resolved (the service is then left as it is).

The channel id ends up in a path of the proxy, so it may only contain letters, digits and ._-.

Whether the channels go through the proxy is the plugin's decision, made when it writes its bouquet: the lazy address, or the address of the stream. The three TV plugins offer a setting Stream proxy for that. See Settings.

registerProvider(scheme, resolve)

Makes the services <scheme>%3a//<channel id> playable and recordable through the proxy, and installs the service extensions in Enigma2. Call it when the plugin is imported, not from sessionstart: a record timer that is resumed while Enigma2 starts prepares its recording before any sessionstart runs.

registerChannel(scheme, channel_id, ...)

Starts the proxy if it is not running, registers the channel with it and returns the address Enigma2 plays the channel from.

Argument Meaning
scheme Scheme of the provider
channel_id Id of the channel (letters, digits and ._-)
master_url Master playlist of the stream. Empty (the default) if it has to be looked up first
url_refresher callable() -> master url. It is called on a worker thread, so it may block. It resolves an empty master_url and renews an address that no longer works
headers Request headers (a dict) that the proxy sends for this channel, or a callable returning them (runs on a worker thread)
refresh_on_failure Call url_refresher whenever the master playlist cannot be fetched. For addresses that expire
session_param Name of the query parameter of the master address that carries the id of the stream session (default sid). When a running channel is registered again with another session id, the proxy discards what it served from the old session. A provider whose addresses carry no session id can ignore it

registerChannel makes no network call itself: with an empty master_url and a url_refresher the stream address is looked up on a worker thread when the player requests it. That keeps the zap fast.

If Enigma2 itself needs request headers for a stream that the proxy hands over unchanged, append LiveProxyUnmuxed.header_suffix(headers) to the returned address. registerChannel does that for a plain dict.

What the address leads to

Playback uses /auto/<channel id>.m3u8 of the proxy and a recording /rec/<channel id>.ts. The recording keeps the #header suffix of the address, if there is one. See How it works for the endpoints, and for how a channel is closed.

The package

A plugin that uses the proxy depends on enigma2-plugin-systemplugins-streamproxycockpit in its CONTROL/control.

Clone this wiki locally