The main goal of o11 is to convert LIVE and VOD streams to a friendly protocol such as HLS and/or direct HTTP MPEG-TS.
The following input formats are currently supported:
- DASH
- HLS
- Microsoft Smooth Streaming
Dependencies
FFmpeg must be installed when not using internal remuxer
Executing o11
You can list command line options using: ./o11 -h
Main pages
In this section will be described the main features of each page from taskbar.
', 2)), e("div", j4, [e("div", O4, [createVNode(ft, {
'id': 'page-providers',
'title': "Providers",
'url': "/providers"
}, {
'default': withModifiers(() => [...cfg27[0] || (cfg27[0] = [e('p', null, " This page is the default one, it\u2019s a clickable list of the available providers. ", -1), e('p', null, " o11 supports multiple providers. Each provider will have its own set of streams and its own network configuration. ", -1), e('p', null, [toDisplayString(' Go to '), e('kbd', null, "Providers"), toDisplayString(" tab, select a provider name and click on "), e("kbd", null, "Add New Provider"), toDisplayString(". Provider configuration files will be stored into "), e("kbd", null, "providers/"), toDisplayString(" by default. This path can be changed using "), e("kbd", null, "-providers [path]"), toDisplayString(" from command-line. ")], -1), e('p', null, [toDisplayString(' You can also import a new proviser using the '), e("kbd", null, "Import"), toDisplayString(' button. The format is either a text file, a m3u or an o11 cfg file. ')], -1)])]),
'_': 1
}), createVNode(ft, {
'id': 'page-vod',
'title': "VOD",
'url': '/vod'
}, {
'default': withModifiers(() => [...cfg27[1] || (cfg27[1] = [e('p', null, " You will find on this page the list of VOD available in the selected provider. ", -1)])]),
'_': 1
}), createVNode(ft, {
'id': "page-recordings",
'title': "Recordings",
'url': '/recordings'
}, {
'default': withModifiers(() => [...cfg27[2] || (cfg27[2] = [e('p', null, "In this page you can setup stream recordings.", -1)])]),
'_': 1
}), createVNode(ft, {
'id': "page-users",
'title': "Users",
'url': "/users"
}, {
'default': withModifiers(() => [...cfg27[3] || (cfg27[3] = [e('p', null, "This page is used to manage users access.", -1), e('p', null, "When adding a new user, the following options are available:", -1), e('ul', null, [e('li', {
'class': "mb-2"
}, [e("kbd", null, "Password"), toDisplayString(" the password for the selected user. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Providers"), toDisplayString(" the list of providers the user has access to. If the "), e("kbd", null, 'Admin'), toDisplayString(" option is selected, the user has access to all providers ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Networks"), toDisplayString(" allowed network for user. If nothing is selected, the user can access o11 from any ip. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Admin"), toDisplayString(" set user as admin. Only admin users can access the "), e("kbd", null, "Users"), toDisplayString(' and '), e('kbd', null, "Config"), toDisplayString(" pages. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "WebAccess"), toDisplayString(" allow Web UI access to user. ")])], -1)])]),
'_': 1
})]), e("div", B4, [createVNode(ft, {
'id': "page-linear",
'title': "Linear",
'url': "/linear"
}, {
'default': withModifiers(() => [...cfg27[4] || (cfg27[4] = [e('p', null, 'All linear streams are listed in this page.', -1), e('p', null, " Eeach linear channel can be started from this page. You can also play it using the internal player, go to logs or settings. You will also be able to copy the link to this stream. Note that playback will mostly fail under Chrome if the audio track is AC3 or other type of complex audios. ", -1)])]),
'_': 1
}), createVNode(ft, {
'id': "page-events",
'title': "Events",
'url': '/events'
}, {
'default': withModifiers(() => [...cfg27[5] || (cfg27[5] = [e('p', null, " You will find on this page the Schedule list for events and the available recorded events (Replays). The list of events is retrieved using the provider script, please look at section below. ", -1), e('p', null, [toDisplayString(" Schedule can also be accessed using the "), e("kbd", null, "-epgport"), toDisplayString(" command line option and going to "), e('kbd', null, "http://ip:epgport/providerid"), toDisplayString(". An XMLEPG version is also accessible at "), e("kbd", null, "http://ip:epgport/providerid.xml"), toDisplayString(" or "), e('kbd', null, "http://ip:epgport/providerid.xml.gz"), toDisplayString('. ')], -1), e('p', null, [toDisplayString(' Each new event gets a '), e("kbd", null, "eventN"), toDisplayString(" id. N is an unique incremental number. If you want to access on air events, you should use the special id "), e("kbd", null, 'onairN'), toDisplayString(", where N will never exceed the number of events running simultaneously. This "), e("kbd", null, 'onairN'), toDisplayString(" id is only valid during the live window of the event. ")], -1), e('p', null, " The second table is the list of replays (recorded events). They are accessible trough the given link or will be automatically played using their original event link when finished. ", -1)])]),
'_': 1
}), createVNode(ft, {
'id': 'page-monitoring',
'title': 'Monitoring',
'url': "/monitoring"
}, {
'default': withModifiers(() => [...cfg27[6] || (cfg27[6] = [e('p', null, " You will find on this page all active connections and some informations about the system status. ", -1)])]),
'_': 1
}), createVNode(ft, {
'id': 'page-logs',
'title': "EPG",
'url': "/epg"
}, {
'default': withModifiers(() => [...cfg27[7] || (cfg27[7] = [e('p', null, " In this page, you will be able to access EPG for each channel. ", -1)])]),
'_': 1
}), createVNode(ft, {
'id': 'page-logs',
'title': 'Logs',
'url': "/logs"
}, {
'default': withModifiers(() => [...cfg27[8] || (cfg27[8] = [e('p', null, " In this page, you will be able to access logs for each channel as well as the main log. The channel logging verbosity can be configured on the configuration page. ", -1)])]),
'_': 1
})])]), createVNode(ft, {
'id': "page-config",
'title': "Config",
'url': "/config"
}, {
'default': withModifiers(() => [cfg27[40] || (cfg27[40] = e("div", {
'id': 'config-providers',
'class': "space-y-2"
}, [e("div", {
'id': 'config-running-output-mode',
'class': "space-y-2"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, "Running/Output Mode"), e('p', null, "o11 supports 5 running modes:"), e('ul', null, [e('li', {
'class': "mb-2"
}, [e("kbd", null, "Internal remuxer"), toDisplayString(' - (default mode) this mode works without FFmpeg, the remuxing operations are done internally. All output modes are available in this this mode. No file is written on disk. ')]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, 'FFmpeg resident'), toDisplayString(" - FFmpeg must be installed. A FFmpeg process is spawned when the stream is started and will keep running until the channel is stopped. All output modes are available in this this mode. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "FFmpeg TS HLS/Direct"), toDisplayString(" - FFmpeg must be installed. On each new segment, FFmpeg is spawn to convert it to a HLS fragment. CPU load is higher in this mode because FFmpeg is started on every new segment. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "FFmpeg MultiTS HLS"), toDisplayString(' - FFmpeg must be installed. On each new segment, FFmpeg is spawn to convert it to a HLS video or audio fragment. It results in a multi TS HLS playlist. ')]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "FMP4 HLS"), toDisplayString(" - this mode works without FFmpeg. The input stream is converted to FMP4 HLS. No file is written on disk. ")])]), e('p', null, " o11 supports 4 output modes when Internal Remuxer or Resident FFmpeg running modes are selected: "), e('ul', null, [e('li', {
'class': "mb-2"
}, [e("kbd", null, "HLS/Direct"), toDisplayString(" - the input stream is converted to HLS and can also be retrieved in direct HTTP mode. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "SRT Server"), toDisplayString(' - the stream is available through the SRT server. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Custom Pipe"), toDisplayString(" - the stream is pushed to a linux pipe and processed by a custom command defined by the -pipeoutputcmd command line parameter. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "UDP/SRT Push"), toDisplayString(" - the stream is pushed to a linux pipe and processed by tsplay when using FFmpeg mode. When using internal remuxer, it does not use tsplay. The output destination is defined per channel by the Output field. It should be a space separated list of udp://ip:port or srt://ip:port. ")])])])], -1)), cfg27[41] || (cfg27[41] = e('hr', {
'class': "my-8!"
}, null, -1)), cfg27[42] || (cfg27[42] = e('div', {
'id': 'config-script'
}, [e('p', {
'class': 'text-lg font-semibold mb-4'
}, "Script"), e('p', null, [toDisplayString(" Script name (without it's extension, so "), e("kbd", null, "example.py"), toDisplayString(" becomes "), e('kbd', null, "example"), toDisplayString("), followed that parameters that will be passed to that script). Other parameters like the action, the network config, etc., are automatically passed as parameters too. Check the "), e('a', {
'href': "#config-scripts"
}, 'Scripts'), toDisplayString(" paragraph for more details. ")])], -1)), cfg27[43] || (cfg27[43] = e('hr', {
'class': "my-8!"
}, null, -1)), cfg27[44] || (cfg27[44] = e("div", {
'id': "config-script"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, 'External CDM Script'), e('p', null, [toDisplayString(' External CDM Script name (without it\x27s extension, so '), e("kbd", null, 'example.py'), toDisplayString(" becomes "), e("kbd", null, "example"), toDisplayString("). ")])], -1)), cfg27[45] || (cfg27[45] = e('hr', {
'class': 'my-8!'
}, null, -1)), e('div', H4, [e('p', F4, [cfg27[9] || (cfg27[9] = toDisplayString(" Update Linear ", -1)), createVNode(ot)]), cfg27[10] || (cfg27[10] = e('p', null, [toDisplayString(" Call the script to update the channels list. If you select "), e("kbd", null, "auto refresh"), toDisplayString(', channels that are not in the list sent by the script will be removed unless the '), e('kbd', null, "Ignore Update"), toDisplayString(' option is checked. ')], -1))]), cfg27[46] || (cfg27[46] = e('hr', {
'class': "my-8!"
}, null, -1)), e("div", q4, [e('p', W4, [cfg27[11] || (cfg27[11] = toDisplayString(" Refresh Events ", -1)), createVNode(ot)]), cfg27[12] || (cfg27[12] = e('p', null, [toDisplayString(" Call the script to udpate the events list. It can be automated by clicking on "), e("kbd", null, "auto refresh"), toDisplayString(". If you select "), e('kbd', null, 'auto refresh'), toDisplayString(', channels that are not in the list sent by the script will be removed unless the '), e("kbd", null, "Ignore Update"), toDisplayString(" option is checked. ")], -1))]), cfg27[47] || (cfg27[47] = e('hr', {
'class': "my-8!"
}, null, -1)), cfg27[48] || (cfg27[48] = e("div", {
'id': "config-network-parameters",
'class': "space-y-2"
}, [e('p', {
'class': 'text-lg font-semibold mb-4'
}, "Network"), e('p', null, ' Network options can be configured globally for a provider and then overridden per stream. '), e('p', null, [toDisplayString(' All these network parameters can be overridden per channel, selecting the '), e('kbd', null, "NetworkOverride"), toDisplayString(" option. ")]), e('p', null, [toDisplayString(" Don't forget to press "), e("kbd", null, 'APPLY NETWORK'), toDisplayString(" for the changes to take effect. If you set global network parameters while streams are running some streams can crash. ")]), e('p', null, [toDisplayString(' You can select individually a network connection for Scripts/Manifests/Media calls. You can also set a '), e('kbd', null, "Worker"), toDisplayString(" host for each of them, every request will use this host. The real host is passed as an extra header "), e('kbd', null, 'Original-Host'), toDisplayString('. ')]), e('ul', null, [e('li', {
'class': "mb-2"
}, [e("kbd", null, "System"), toDisplayString(" - use system network configuration. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Same as ... "), toDisplayString(" - use the same network configuration as... ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, 'HTTP/SOCKS5 Proxy'), toDisplayString(' - coma separated list of proxies. Format is '), e('kbd', null, "http://user:pass@ip:port"), toDisplayString(" for HTTP proxies and "), e("kbd", null, "socks5://user:pass@ip:port"), toDisplayString(" for SOCKS5 proxies. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Bind"), toDisplayString(' - coma separated list of ips or interface names. ')]), e('li', {
'class': 'mb-2'
}, [e('kbd', null, "DNS over HTTPS"), toDisplayString(' - coma separated list of DOH servers. ')])])], -1)), cfg27[49] || (cfg27[49] = e('hr', {
'class': 'my-8!'
}, null, -1)), cfg27[50] || (cfg27[50] = e("div", {
'id': "config-additional-parameters"
}, [e('p', {
'class': 'text-lg font-semibold mb-4'
}, "Parameters"), e('p', null, " A bunch of additional parameters can be set here. For more info, put your cursor on the parameter to bring the tooltip. ")], -1)), cfg27[51] || (cfg27[51] = e('hr', {
'class': "my-8!"
}, null, -1)), cfg27[52] || (cfg27[52] = e("div", {
'id': "config-script-accounts",
'class': 'space-y-2'
}, [e('p', {
'class': 'text-lg font-semibold mb-4'
}, "Script accounts"), e('p', null, [toDisplayString(" A list of accounts to use with the script. If the account is enabled and selected (next to the script field or per channel next to the script params field), it's info will be passed when calling the script. For instance, "), e("kbd", null, "user=john@mail.com password=mypassword device=123456 pin=1234")]), e('p', null, [toDisplayString(' The '), e("kbd", null, "login"), toDisplayString(' button can be used to call the script with the login action, to test if the account works. The script must print '), e('kbd', null, '\x27logged in\x27'), toDisplayString(" to validate the login. The "), e("kbd", null, "pair"), toDisplayString(" button can be used to call the script with the pair action. ")])], -1)), cfg27[53] || (cfg27[53] = e('hr', {
'class': "my-8!"
}, null, -1)), cfg27[54] || (cfg27[54] = e("div", {
'id': "config-channels",
'class': "space-y-2"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, "Channels"), e('p', null, [toDisplayString(' To add a new channel to a provider, go to '), e("kbd", null, "Config"), toDisplayString(' tab and press '), e("kbd", null, "ADD NEW STREAM"), toDisplayString(' after entering its name in the field. ')]), e('p', null, [toDisplayString(' To delete a stream, click on its checkbox and press '), e("kbd", null, 'DELETE SELECTION'), toDisplayString(". If the stream was running, it will be stopped first, then deleted. ")])], -1)), cfg27[55] || (cfg27[55] = e('hr', {
'class': 'my-8!'
}, null, -1)), e("div", z4, [cfg27[29] || (cfg27[29] = e('p', {
'class': "text-lg font-semibold mb-4"
}, "Stream configuration", -1)), e('ul', null, [cfg27[22] || (cfg27[22] = e('li', {
'class': "mb-2"
}, [e("kbd", null, "Start/Stop"), toDisplayString(" - to start or stop the stream. ")], -1)), cfg27[23] || (cfg27[23] = e('li', {
'class': 'mb-2'
}, [e('kbd', null, "Name"), toDisplayString(' - the name of the stream. This is also a clickable link that will start the internal player. You can also copy this link (HLS) to use in another player. ')], -1)), cfg27[24] || (cfg27[24] = e('li', {
'class': "mb-2"
}, [e("kbd", null, "Status"), toDisplayString(" - the status of the stream.")], -1)), cfg27[25] || (cfg27[25] = e('li', {
'class': "mb-2"
}, [e("kbd", null, "Mode"), toDisplayString(" - "), e("strong", null, "Linear"), toDisplayString(', '), e('strong', null, 'Replay'), toDisplayString(' or '), e("strong", null, "VOD"), toDisplayString('. '), e("strong", null, "Linear"), toDisplayString(" mode is for a live channel. "), e("kbd", null, "Replay"), toDisplayString(' will trigger a fetch of all the fragments from the manifest and generate a HLS output stream. '), e("strong", null, 'VOD'), toDisplayString(" can be used to get VOD stream and generate mp4 file. ")], -1)), e('li', Z4, [cfg27[13] || (cfg27[13] = e('kbd', null, "Manifest", -1)), cfg27[14] || (cfg27[14] = toDisplayString(" - setup the manifest url. If ", -1)), cfg27[15] || (cfg27[15] = e("kbd", null, "SessionManifest", -1)), cfg27[16] || (cfg27[16] = toDisplayString(" - option is selected, the provider script will be called if needed. please check the ", -1)), cfg27[17] || (cfg27[17] = e("strong", null, "Scripts", -1)), cfg27[18] || (cfg27[18] = toDisplayString(" section for more details. Network ovverride fields will also appear in the box when the ", -1)), cfg27[19] || (cfg27[19] = e("kbd", null, "NetworkOverride", -1)), cfg27[20] || (cfg27[20] = toDisplayString(" option is selected. Press the ", -1)), createVNode(ot, {
'class': 'inline'
}), cfg27[21] || (cfg27[21] = toDisplayString(" button to parse the manifest and refresh the tracks list. ", -1))]), cfg27[26] || (cfg27[26] = e('li', {
'class': "mb-2"
}, [e("kbd", null, "Tracks"), toDisplayString(" - list of selectable Video/Audio/Subtitles tracks. The "), e("strong", null, "Best quality"), toDisplayString(" option is seletected by default and let o11 take the best resolution/bandwidth/framrate. Multiple audio and subtiltes tracks can be selected. ")], -1)), cfg27[27] || (cfg27[27] = e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Keys or CDM Script"), toDisplayString(" - set the decryption keys for the stream. On line per kid:key. If "), e("kbd", null, "UseCdm"), toDisplayString(" is selected, o11 will try to call the selected provider script to get keys using the specified parametersm. Please check the "), e("strong", null, "Scripts"), toDisplayString(" section for more detail. ")], -1)), cfg27[28] || (cfg27[28] = e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Options'), toDisplayString(' - please see the '), e("strong", null, "Stream options"), toDisplayString(" section. ")], -1))])]), cfg27[56] || (cfg27[56] = e('hr', {
'class': "my-8!"
}, null, -1)), cfg27[57] || (cfg27[57] = e('div', {
'id': "streaming-parameters"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, 'Streaming Parameters'), e('ul', null, [e('li', {
'class': "mb-2"
}, [e('kbd', null, "Detect SSAI"), toDisplayString(' - Try to detect Server Side Insertion inside manifest. Some streams require this option to work correctly. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Detect CTV"), toDisplayString(" - Try to detect CTV stream inside manifest. Some streams require this option to work correctly. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Force HLS TS"), toDisplayString(" - Force fragment type of HLS input streams to MPEG-TS. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Force HLS FMP4"), toDisplayString(' - Force fragment type of HLS input streams to fragmented MP4. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Ignore DASH static flag"), toDisplayString(" - Treat all DASH input streams as live/linear, regardless of their mode. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Ignore DASH SegmentTimeline"), toDisplayString(' - Treat all DASH input streams removing the SegmentTimeline for local manifest playback. ')]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Use DASH Location"), toDisplayString(' - Use Location value from DASH manifest to grab next manifest. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Call script to download manifest"), toDisplayString(" - Call provider script with downloadmanifest action to download a manifest. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Call script to download media"), toDisplayString(" - Call provider script with downloadmanifest action to download a media. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Use session cookies'), toDisplayString(" - Use cookies set by manifest retrieval for media files retrieval. Mandatory for some providers. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, 'No referer in redirects'), toDisplayString(' - Don\x27t set the Referer header during http redirects files retrieval. Mandatory for some providers. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Use DASH delay"), toDisplayString(" - Delay DASH playback based on manifest info."), e('br')]), e('li', {
'class': 'mb-2'
}, [e('kbd', null, "Use DASH newest period"), toDisplayString(" - Always use the newest period in DASH manifest."), e('br')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Legacy DASH parser'), toDisplayString(" - Use legacy DASH parser. This parser should be slower but may be worth a try if a DASH parsing issue occurs. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Use manifest URL params for segments"), toDisplayString(" - When manifest URL comes with URL parameters (?param1=...\u00b6m2=...), forward these parameters to the HLS sub-manifests and the HLS/DASH media files, only if they don't already include any. Mandatory for some providers. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Force manifest URL params for segments"), toDisplayString(" - When manifest URL comes with URL parameters (?param1=...\u00b6m2=...), always forward these parameters to the HLS sub-manifests and the HLS/DASH media files. Mandatory for some providers. This option overrides the previous one. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Detect invalid PAT in MpegTS"), toDisplayString(" - Some HLS/TS streams have a bad PAT, this option try to detect the PMT. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Detect special JSON redirect URL'), toDisplayString(" - Some providers use a special way to redirect manifest URL. They return a 200 with a JSON that includes the URL to use. Format is a string array named 'Locations'. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Don't wait for full playlist"), toDisplayString(" - When a stream starts, the output stream becomes available when at least 'Output fragments count' are available (look below). This option allows to make the output stream available without waiting for this value to be reached. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Pre-process PSSH"), toDisplayString(" - Call script with action=pssh and the pssh value before processing it. This allows a pre-processing on the PSSH. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Force PSSH from manifest"), toDisplayString(" - Use PSSH from manifest even if a media embeds one. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Don\x27t use keys cache'), toDisplayString(" - For providers using the same KID for all streams, use this option. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Always select default tracks'), toDisplayString(" - Always select default tracks on stream start. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Only match first default track"), toDisplayString(' - Only select first track matching the tracks filte. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Push keys to archive"), toDisplayString(" - Call archive script with action=pushkey for each new key from CDM. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Use media network for HLS key"), toDisplayString(" - Use media network for HLS key instead of manifest one. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Ignore oldest fragment"), toDisplayString(" - Don't use oldest fragment from stream source manifest (it can happen that this fragment disappears before we try to grab it. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Default CDN"), toDisplayString(" - CDN name to be used by default, when multiple CDN manifest URLs are available. The name must match the name of the CDN defined in the stream config. Default is Empty (no filter). ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Default video"), toDisplayString(" - Default video streams to select. Each filter can be an extract of the real stream description. For example, '720p' will match '720p30', '720p60',...'. Multiple filters can be defined, '|' separated. Default is Empty (no filter). ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Default audio'), toDisplayString(" - Default audio streams to select. Each filter can be an extract of the real stream description. For example, 'Eng' will match 'English'. Multiple filters can be defined, '|' separated. Default is Empty (no filter). ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, 'Default subtitles'), toDisplayString(" - Default subtitles streams to select. Each filter can be an extract of the real stream description. For example, 'Eng' will match 'English'. Multiple filters can be defined, '|' separated. Default is Empty (no filter). ")]), e('li', {
'class': 'mb-2'
}, [e('kbd', null, "HLS playlist duration (s)"), toDisplayString(' - Duration of the HLS output playlist. Duration is the sum of all fragments\x27 duration. For instance, 15 means 5 fragments if they are 3 seconds each. There can\x27t be fewer than 5 fragments. This value is ignored if \x27Output fragments count\x27 is not 0. Default is 15 seconds. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "HTTP get timeout"), toDisplayString(" - HTTP call timeout. This value is automatically increased to 24 hours for VOD streams. Default is 30 seconds. ")]), e('li', {
'class': 'mb-2'
}, [e('kbd', null, "HTTP get tentatives count"), toDisplayString(" - Number of times to retry to get a manifest or a media file. Default is 2 times. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "HLS fragments duration (s)"), toDisplayString(' - Duration of output fragments. This value is ignored in FFmpeg TS HLS/Direct output mode that will use the value from input stream. Default is 0 (HLS playlist duration). ')]), e('li', {
'class': 'mb-2'
}, [e('kbd', null, "Output fragments count"), toDisplayString(" - Force the number of fragments in the HLS output playlist. Default is auto, using HLS playlist duration. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Stalled stream timeout (s)'), toDisplayString(" - Time to wait before detecting an input stream as stalled (no new fragment). Default is 60. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Playback Delay (s)"), toDisplayString(" - Add a playback delay to the input stream, ignoring newest fragments. Default is 0 (no delay). ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "\"DASH time offset (ms)"), toDisplayString(' - Add an offset to the wall clock to compute dash fragments time. ')]), e('li', {
'class': 'mb-2'
}, [e('kbd', null, "CDM provider ID"), toDisplayString(" - provider ID to pass when calling keys archive and external CDM scripts. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, 'DRM level'), toDisplayString(" - DRM level to pass to external CDM script. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "CDM certificate"), toDisplayString(' - CDM certificate base64 to pass to external CDM script. ')]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Max streams concurrency"), toDisplayString(" - Max number of streams that can run simultaneously in this provider. Default is 0 (no limit). ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Retry new manifest count'), toDisplayString(" - Number of times to re-try to get a new manifest (using the script), if the current one fails. This only works when 'Session Manifest' is enabled. Default is 1 (re-try once). ")]), e('li', {
'class': 'mb-2'
}, [e('kbd', null, "Max streams per account"), toDisplayString(" - Max number of streams that can be started for a unique script account. Default is 0 (no limit). ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Max download concurrency"), toDisplayString(" - Max number of concurrent media retrieval per stream (when using SpeedUp mode). Default is 50. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Max concurrent script calls"), toDisplayString(" - Max number of concurrent calls to the provider script. Default is 0 (no limit). ")])])], -1)), cfg27[58] || (cfg27[58] = e("div", {
'id': "channels-events-parameters"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, 'Channels/events parameters'), e('ul', null, [e('li', {
'class': "mb-2"
}, [e('kbd', null, 'Reuse event index'), toDisplayString(' - Events retrieved from a script get an autogenerated stream id called \x22eventN\x22 where N is an always increasing number. If this option is set, N will reuse available numbers, that were freed by deleted events. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Reversed events ids"), toDisplayString(" - Instead of an always increasing number, N from 'eventN' will be decreased for each new event. Don't forget to set 'Events first ID' to a high value or you will quickly run out of possible numbers (1 being the lower one). ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Reset events list on refresh"), toDisplayString(" - When refreshing events remove all current ones and start a new list. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Auto-remove missing channels'), toDisplayString(" - When updating linear channels from script, remove from O11 the channels that are not listed anymore. This option is ignored for channels with the 'Ignore update' option set. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, 'Don\x27t add new channels on refresh'), toDisplayString(" - When updating linear channels from script, don't add new ones, only update existing ones. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Auto-refresh channels"), toDisplayString(" - Periodically refresh channels from script. Refresh period is defined in 'Channels refresh con'. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Auto-refresh events'), toDisplayString(" - Periodically refresh events from script. Refresh periodicity is defined in 'Events refresh cron'. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Auto-refresh EPG"), toDisplayString(' - Periodically refresh EPG from script. Refresh periodicity is defined in \x27EPG refresh cron\x27. ')]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Don't auto-remove finished events"), toDisplayString(" - Do not remove from O11 the events that are finished. This option is ignored for events with the 'Ignore update' option set. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Remove events not returned by script"), toDisplayString(" - Remove events that are listed in O11 but not returned by the provider script. This option is ignored for events with the 'Ignore update' option set. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Allow duplicate events'), toDisplayString(" - When updating events from script, allow 2 events with the the same config and similar start time. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Events first ID"), toDisplayString(" - The first ID number to use for eventN streams. Default is 0. ")]), e('li', {
'class': 'mb-2'
}, [e('kbd', null, "Channels update period (s)"), toDisplayString(" - Period to update channels list (linear streams). Default is 0 (no auto-update). ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Channels refresh cron"), toDisplayString(" - Cron defining the time where the channels list is refreshed. This is used only if 'Auto-refresh channels' is set. Default is daily. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Events refresh cron'), toDisplayString(" - Cron defining the time where the events list is refreshed. This is used only if 'Auto-refresh events' is set. Default is daily. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Max events count"), toDisplayString(" - Max number of events to add from script. Default is 0 (no limit). ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Max events hours"), toDisplayString(' - Maximum hours of events to retrieve. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "EPG refresh cron"), toDisplayString(" - Cron defining the time where the EPG is refreshed. This is used only if 'Auto-refresh EPG' is set. Default is daily. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Timezone"), toDisplayString(" - Timezone used to generate dates. This is used for XML EPG, remote DB update, replays. Default is UTC. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Events SQL URL"), toDisplayString(" - SQL URL where to send new events. Format is user:password@tcp(ip:port)/dbname. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "SQL Stream URL"), toDisplayString(" - Stream URL to use when sending it to SQL URL. Format is https://user:pass@ip. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Logo URL"), toDisplayString(" - Logo path for provider URL. Default is /logos/[providerid].png ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Script timeout (s)"), toDisplayString(' - Max time to wait for a script call to return. When the timeout is reached, the call exits with a \x27killed\x27 error. Default is 30 seconds. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Events first ID'), toDisplayString(" - First ID for events. This ID is the N value from 'eventN'. This is important when setting 'Reversed events ids'. Default is 0 (this must be changed). ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Event filters"), toDisplayString(" - Events filtering allows creating special static links for events. These events are called 'Filtered events'. For instance, let\u2019s say that you want a static link for every daily news on Channel1. You know that the event is always called '[DATE] Channel1 News'. Then you must create a filter called 'Channel1 News'. This will auto-create a new event (available in the events tab and in EPG). This special event will always point to the events that match the filter, when they are On-Air. Multiple events can be defined | separated. Additional words ca be added & separated It is also possible to define multiple filters per entry, '#' separated. For instance 'Channel1 News#Channel1 Daily News'. The filter match is on words, not on each char and is case sensitive. Final format is: filter1#alt1#...|filter2|... ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, 'Default events duration'), toDisplayString(" - Duration in seconds for events which don't have a end date. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Don\x27t Gzip EPG in playlist'), toDisplayString(" - Send EPG as non-gzipped XML in playlist. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Use event number as name in playlist"), toDisplayString(" - In M3U playlist print event names as \"Event N\". ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Dont' cool down event start"), toDisplayString(' - Dont\x27 cool down event start. That could cause script call flood. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Delete removed streams logs"), toDisplayString(" - Remove logs from a stream when it's deleted. ")])])], -1)), cfg27[59] || (cfg27[59] = e("div", {
'id': "start-parameters"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, "Start parameters"), e('ul', null, [e('li', {
'class': "mb-2"
}, [e("kbd", null, "Always reset session"), toDisplayString(" - When starting a stream and if 'Session Manifest' is selected, always call the provider script to get a fresh session manifest. Mandatory for some providers. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "No restart on error"), toDisplayString(" - Don't auto-restart a stream when it exits due to an error. Useful for debugging failing streams. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Restart finished broadcast'), toDisplayString(" - When a stream exits because it was detected that the broadcast ended (due to a static flag in the DASH manifest, for instance), auto-restart it. The default behavior is to NOT restart it. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'No restart on track change'), toDisplayString(" - When the tracks list changes in a stream, it is restarted unless this option is set. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Always auto-restart on failure'), toDisplayString(" - When a stream fails to start, without even successfully getting the first media file, it is not auto-restarted because it usually means that subsequent starts will also fail. This option makes the stream always restart regardless of the failing reason. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Cooldown streams auto-restart"), toDisplayString(" - Try to cooldown streams auto-restart to avoid 2 streams restarting at the same time. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Try next CDN on failure'), toDisplayString(' - When a stream fails to start, jump to next CDN on next run. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Restart delay (s)"), toDisplayString(' - Time to wait before restarting a stream. Default is 30 seconds. ')]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Autorestart random offset (s)"), toDisplayString(" Add a random offset in seconds to the stream auto-restart cron. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Random autostart period (s)'), toDisplayString(" - When starting O11 for the first time, start all streams with a random delay between 0 and this value. Default is 0 (no random delay). ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Seq autostart period (s)"), toDisplayString(" - When starting O11 for the first time, start all streams sequentially every N seconds. Default is 0 (no sequential start). ")])])], -1)), cfg27[60] || (cfg27[60] = e('div', {
'id': "dvb-subtitles"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, "DVB Subtitles"), e('ul', null, [e('li', {
'class': "mb-2"
}, [e("kbd", null, "Disable DVBSubs colors"), toDisplayString(" - Ignore color tags in the input subtitles description. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Disable DVBSubs style'), toDisplayString(" - Ignore special styles in the input subtitles. This fixes some providers with complex subtitles. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, 'Use provider script for DVBSubs'), toDisplayString(' - Call provider script for each subtitle. This allows for operations like translations. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Add overlay on picture'), toDisplayString(" - Add a picture overlay on the output stream. The picture must be stored in 'overlay/[providerid.png'. This option only works with FFmpeg TS HLS/Direct and resident modes. Warning: This option consumes a lot of CPU as all frames are transcoded. Consider using a GPU by selecting the right option in 'HW accel for burned subtitles'. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, 'Always transcode'), toDisplayString(' - Always transcode all frames when burning subtitles. This resolves some output stream issues. If not set, only frames with subtitles will be transcoded. This option only works with FFmpeg TS HLS/Direct mode. ')]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Use X-TIMESTAMP-MAP for VTT"), toDisplayString(" - Use X-TIMESTAMP-MAP from VTT input streams to extract subtitles timestamps. Mandatory for some providers. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "DVBSubs colors filter"), toDisplayString(' - Only output the specified subtitles colors (as well as the default color). Format is color1, color2,... Default is all colors. ')]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "DVBSubs translation src"), toDisplayString(' - When \x27Use provider script for DVBSubs\x27 is selected, select the input stream subtitles language to be passed to the script. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Max autorestart tentative"), toDisplayString(' - How many times it will try to restart a failing stream before giving up. 0 means no limit. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Events start offset (s)"), toDisplayString(" - Add an offset to event on-air start date in seconds. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, 'Events end offset (s)'), toDisplayString(" - Add an offset to event on-air end date in seconds. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "DVBSubs translation dest"), toDisplayString(" - When 'Use provider script for DVBSubs' is selected, select the output stream subtitles language to be passed to the script. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "DVBSubs size"), toDisplayString(" - DVBSubs size can be adjusted with this value, from 0 to 100%. Default is 100 (%). ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "DVBSubs Vertical Offset"), toDisplayString(" - DVBSubs vertical offset can be adjusted with this value, from 0 to 100%. Default is 96 (%). ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, 'DVBSubs quality'), toDisplayString(" - Select DVBSubs subtitles quality from low to high. A better quality means higher CPU consumption. Default is medium. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Burn message"), toDisplayString(' - Burn a static message in the output stream. This option only works with FFmpeg TS HLS/Direct and resident modes. Default is no message. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'HW accel for burned subtitles'), toDisplayString(" - Select HW acceleration to burn subtitles, overlay, or messages. Nvidia and QSV are currently supported options. This defines the options passed to FFmpeg. This option only works with FFmpeg TS HLS/Direct and resident modes. Default is no HW acceleration (full CPU). ")])])], -1)), cfg27[61] || (cfg27[61] = e("div", {
'id': "misc"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, "Misc"), e('ul', null, [e('li', {
'class': "mb-2"
}, [e("kbd", null, 'X-Forwarded-For'), toDisplayString(" - Default X-Forwarded-For to be sent to all HTTP requests, unless overridden by the Headers defined below and in each stream. Default is none. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Pipe command (READ-ONLY)"), toDisplayString(" - When using 'Custom' 'Output Mode', this is the command that will be run using the stream as input PIPE. The %s value is replaced by the 'Pipe' field for each channel. This allows, for instance, to define a custom UDP destination. Default is 'tsplay -stdin %s'. This value CAN'T be edited for obvious security reasons. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "User Agent"), toDisplayString(" - Default User-Agent header to be sent to all HTTP requests, unless overridden by the Headers defined below and in each stream. Default value can be changed from the command-line. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Manifest Headers"), toDisplayString(" - Headers to be passed to every manifest HTTP call. Format is { 'Header1': 'Value', 'Header2': 'Value' } ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Media Headers"), toDisplayString(" - Headers to be passed to every media HTTP call. Format is { 'Header1': 'Value', 'Header2': 'Value' } ")])])], -1)), cfg27[62] || (cfg27[62] = e('hr', {
'class': "my-8!"
}, null, -1)), cfg27[63] || (cfg27[63] = e('div', {
'id': "config-stream-options"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, "Stream options"), e('p', null, "Several options can be selected for each stream."), e('ul', null, [e('li', {
'class': 'mb-2'
}, [e("kbd", null, "First audio track\""), toDisplayString(" - First audio track to the output stream when multiple audio are selected. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, 'Script params/Account selection'), toDisplayString(' - set the script parameters to be added to the other parameters for this channel (typically id=channelid). The account to use with this channel can be selected here, if Provider is chosen, it will use the same account as the providers\x27one. ')]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Autostart"), toDisplayString(" - auto start the stream when starting o11. It is possible to override this option globally using the "), e("kbd", null, "-noautostart"), toDisplayString(" command-line option. If the stream is an event, it will be autostarted only during live window. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "On demand"), toDisplayString(" - automatically start a stream when the internal or a remote player request for it. The stream is then automatically stops when it is not used anymore. Use this option to avoid having all streams running for nothing 24/24. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Speed up'), toDisplayString(" - run all segments download in parallel. It speeds up stream start. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, 'Session manifest'), toDisplayString(" - call the script to automatically get the manifest URL. Usefull when the manifest is changing (check the "), e("strong", null, "Scripts"), toDisplayString(" paragraph for more details). ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'CDM script'), toDisplayString(" - call the script automatically get keys when needed (check the "), e("strong", null, 'Scripts'), toDisplayString(" paragraph for more details). ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Network override'), toDisplayString(" - add new fields to override the global network configuration (check the "), e('strong', null, "Scripts"), toDisplayString(" paragraph for more details). ")]), e('li', {
'class': 'mb-2'
}, [e('kbd', null, 'Mode override'), toDisplayString(' - override running and output modes. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, 'Record event'), toDisplayString(" - record the event and convert it in real-time to a replay. If checked, the event will auto start during it's live window to be recorded. ")]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Record TS"), toDisplayString(' - record the stream on the fly and streamsStore it as a MpegTs in rec/. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Replay manifest"), toDisplayString(" - get all fragments from the manifest. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Ignore update"), toDisplayString(' - don’t autoremove/modify this channel when using the channels or events script (check the '), e('strong', null, "Scripts"), toDisplayString(" section for more details). ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Time range"), toDisplayString(" - select a time range to extract from a manifest. Only works with DASH using times and not numbers. ")]), e('li', {
'class': 'mb-2'
}, [e("kbd", null, "Daily OnAir"), toDisplayString(" - select a time range where the live will be automatically started every day. It will be stopped when not in this daily range. Time is localized based on browser. ")]), e('li', {
'class': "mb-2"
}, [e('kbd', null, "Output field"), toDisplayString(' - list of UPD/SRT outputs or Custom command parameters. ')]), e('li', {
'class': "mb-2"
}, [e("kbd", null, "Logs"), toDisplayString(' - set the channel logging verbosity. This will not be saved, so on next reboot, it will use the global value (set with -v N at startup). ')])])], -1)), cfg27[64] || (cfg27[64] = e('hr', {
'class': "my-8!"
}, null, -1)), e('div', K4, [cfg27[35] || (cfg27[35] = e('p', {
'class': "text-lg font-semibold mb-4"
}, "Scripts", -1)), cfg27[36] || (cfg27[36] = e('p', null, " Scripts play a big role for o11. Each provider should have each own script. It can be either a shell script (.sh) or a python3 script (.py). ", -1)), e('p', null, [cfg27[30] || (cfg27[30] = toDisplayString(" An example of script can be found here ", -1)), e("kbd", null, [e('a', {
'download': "example.py",
'href': '/static/example.py?token=' + createTextVNode(Me).getToken(),
'class': "underline hover:opacity-75 transition-opacity"
}, "example.py", 8, J4)]), cfg27[31] || (cfg27[31] = toDisplayString('. It uses ', -1)), e("kbd", null, [e('a', {
'download': 'o11.py',
'href': '/static/o11.py?token=' + createTextVNode(Me).getToken(),
'class': "underline hover:opacity-75 transition-opacity"
}, "o11.py", 8, Y4)]), cfg27[32] || (cfg27[32] = toDisplayString(". When a script is configured, only it\u2019s name body must be specify. o11 will first try to start the .sh extension and then .py one if not available. Scripts must be stored in the ", -1)), cfg27[33] || (cfg27[33] = e("kbd", null, "scripts", -1)), cfg27[34] || (cfg27[34] = toDisplayString(" directory. ", -1))]), cfg27[37] || (cfg27[37] = e('p', null, [toDisplayString(" Let say we have a provider called "), e('kbd', null, "Provider 1"), toDisplayString(" which script name is "), e("kbd", null, "provider1.py"), toDisplayString(", stored in "), e('kbd', null, "scripts/provider1.py"), toDisplayString(". This script must then be referenced as "), e("kbd", null, "provider1"), toDisplayString(' in the '), e('kbd', null, "Script"), toDisplayString(" field. Some script extra parameters can be specified. ")], -1)), cfg27[38] || (cfg27[38] = e('p', null, ' Depending on the type of script, it will automatically receive the following parameters, additionally to the ones configured by user. ', -1)), cfg27[39] || (cfg27[39] = e('ul', null, [e('li', {
'class': "mb-2"
}, [toDisplayString(" Common to all scripts: "), e("kbd", null, "action=[action type] bind=[bind] proxy=[proxy] doh=[doh] worker-[worker]"), e('ul', null, [e('li', {
'class': "mt-2"
}, [toDisplayString(" Action type can be one of: "), e("kbd", null, "login, pair, manifest, cdm, events, channels or heartbeat")])])]), e('li', {
'class': "mb-2"
}, [toDisplayString("Manifest script: "), e('kbd', null, "action=manifest")]), e('li', {
'class': "mb-2"
}, [toDisplayString(' Cdm script: '), e("kbd", null, "action=cdm drm=[widevine or playready] challenge=[drm challenge] pssh=[pssh used to extract needed keys]")]), e('li', {
'class': "mb-2"
}, [toDisplayString("Events: "), e("kbd", null, "action=events")]), e('li', {
'class': "mb-2"
}, [toDisplayString("Channels: "), e("kbd", null, 'action=channels')]), e('li', {
'class': "mb-2"
}, [toDisplayString(" Heartbeat: "), e("kbd", null, "action=heartbeat heartbeaturl=[heartbeat url returned by manifest script] heartbeatparams=[heartbeat parms returned by manifest script]")])], -1))]), cfg27[65] || (cfg27[65] = e('hr', {
'class': "my-8!"
}, null, -1)), cfg27[66] || (cfg27[66] = e("div", {
'id': "config-manifest-script"
}, [e('p', {
'class': 'text-lg font-semibold mb-4'
}, "Manifest script specifics"), e('p', null, "A manifest script should return a json formatted as followed:"), e("pre", {
'class': 'mb-3 rounded-xl whitespace-pre-wrap'
}, [e("code", {
'class': 'language-json'
}, "{\n \"ManifestUrl\" : [manifest url],\n \"Cdn\" : [\n\t{\n\t 'Name': 'akamai',\n\t 'ManifestUrl': 'http://...'\n\t},\n\t...\n },\n \"Headers\": {\n \"manifest\": {\n 'user-agent': 'mozilla/5.0 (macintosh; intel mac os x 10_15_7) applewebkit/537.36 (khtml, like gecko) chrome/107.0.0.0 safari/537.36',\n 'custom-header': 'it's me',\n ...\n },\n \"media\": {\n 'user-agent': 'mozilla/5.0 (macintosh; intel mac os x 10_15_7) applewebkit/537.36 (khtml, like gecko) chrome/107.0.0.0 safari/537.36'\n 'custom-header': 'it's me',\n ...\n }\n },\n \"Heartbeat\": {\n\t\"Url\" : [heartbeat url],\n\t\"Params\": [param1,param2,...],\n\t\"PeriodMs\" : 5*60*1000\n }\n}")])], -1)), cfg27[67] || (cfg27[67] = e('hr', {
'class': 'my-8!'
}, null, -1)), cfg27[68] || (cfg27[68] = e("div", {
'id': "config-cdm-script"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, 'CDM script specifics'), e('p', null, " A CDM script should return a list of kid:key formatted as followed: "), e("pre", {
'class': "mb-3 rounded-xl"
}, [toDisplayString(''), e('code', {
'class': "language-json"
}, "kid1:key1\nkid2:key2")])], -1)), cfg27[69] || (cfg27[69] = e('hr', {
'class': 'my-8!'
}, null, -1)), cfg27[70] || (cfg27[70] = e("div", {
'id': "config-events-channels-script"
}, [e('p', {
'class': "text-lg font-semibold mb-4"
}, " Events/Channels script specifics "), e('p', null, " A events or channels script should return a list of streams following the same format as the o11 config files: "), e("pre", {
'class': 'mb-3 rounded-xl whitespace-pre-wrap'
}, [toDisplayString(''), e('code', {
'class': "language-json"
}, "{\n \"[Channels or Events]\": [\n {\n // Name of the channel or the title of the event\n \"Name\": \"[name]\",\n // Mode: live or vod\n \"Mode\": \"live\",\n // Use session manifest\n \"SessionManifest\": true,\n // Script parameters to use to retrieve the manifest or keys\n \"ScriptParams\": \"id=123 country=fr\",\n // CDM type (widevine, playready or verimatrix)\n \"CdmType\": \"widevine\",\n // Use cdm script to get keys\n \"UseCdm\": true,\n // Script parameters to use to retrieve keys\n \"Video\": \"best\",\n // Set the audio stream which desc includes 'en'\n \"Audio\": \"desc:en\",\n // Enable On Demand\n \"OnDemand\": false,\n // Enable fragments download speed up (download all required fragments simultaneously to speed up start)\n \"SpeedUp\": true,\n // Autostart stream. For events, this will autostart the stream when in the on air range (time >= Start and time <= End)\n \"Autostart\": true,\n // For events, define UTC start and stop timestamp. They will be autostarted in the onAir window if Autostart or RecordEvent is true\n \"Start\": 1682631577,\n \"End\": 1682632577,\n // For events, define if the event must be recorded and become a replay (only works in direct/hls mode with internal remuxer)\n \"RecordEvent\": true\n },\n ...\n ]\n}")])], -1))]),
'_': 1
})]), cfg27[72] || (cfg27[72] = StaticHTML("