Skip to content

Your first channel

Define an upstream and channel, start Kiln, and verify playback.

Updated View as Markdown

A playable channel needs two configuration entries: [[upstreams]] identifies the origin, and [[channels]] selects the path and format. Follow these steps to configure the channel and verify playback.

From config to playback

Define the origin

An origin needs an ID and a base URL. Channels reference it with upstream and append path, so moving the origin to another host or port is a one-line change.

kiln.tomltoml
[[upstreams]]
id = "origin"
base_url = "https://origin.example.com:8000"

[upstreams.headers]
X-Custom = "value"

[upstreams.headers] is optional and applies to every outbound request for that origin, which covers origins that require a fixed header.

Define an HLS channel

The shortest useful channel looks like this. id appears in the playback URL, while title and group drive the display name and grouping in the playlist.

kiln.tomltoml
[[channels]]
id = "demo-hls"
title = "Demo HLS"
group = "Demo"
upstream = "origin"
path = "/live/demo-hls"
ingress = "hls"
on_demand = true

ingress accepts only hls and dash, and defaults to hls when omitted. path is required whenever upstream is used; leaving it out fails at startup. The full field list is in Channels.

Add a DASH channel

A DASH channel has the same shape. The differences are ingress and the keys.

kiln.tomltoml
[packager]
keys_file = "kiln.keys"

[[channels]]
id = "demo-dash"
title = "Demo DASH"
group = "Demo"
upstream = "origin"
path = "/live/demo-dash"
ingress = "dash"
on_demand = true

keys_file is a single global kid:key catalog shared by every DASH channel. One enabled DASH channel without it is enough to fail startup outright. See Fine-grained track selection for track and resolution controls.

Write the key file

One kid:key pair per line, in hex. Blank lines and lines starting with # are ignored.

kiln.keystext
# kid:key (hex). Replace with real pairs; never commit production secrets.
000102030405060708090a0b0c0d0e0f:0f0e0d0c0b0a09080706050403020100

Both halves must be 32 hex characters. The kid may be written in dashed UUID form, since dashes are stripped during parsing; the key may not contain dashes. A repeated kid with a different key is an error, while an exact duplicate is collapsed. A file with no usable pair is an error too.

Restart and verify

The key file is fully validated once at startup, so any edit needs a restart, and keys never appear in the admin API. After restarting, confirm the playlist and one playback URL:

TOKEN=$(curl -s http://127.0.0.1:8080/v1/auth/login \
  -H 'content-type: application/json' \
  -d '{"username":"admin","password":"admin"}' | jq -r .token)

curl -s http://127.0.0.1:8080/v1/playlist.m3u -H "authorization: Bearer $TOKEN"
curl -s "http://127.0.0.1:8080/v1/play/demo-hls/index.m3u8?token=$TOKEN"

Both channels should appear in the playlist. Paste a playback URL into any HLS-capable player, or hand the whole playlist to an IPTV client, and you have video. Distribution and playback keys are covered in Playback.

on_demand and autostart

These two switches decide when the upstream connection is opened and when it is released. Either can be used alone, or both together.

Switch Behavior
on_demand Pulls upstream only when something asks for the channel, then stops the session and releases the connection after idle_timeout_sec of inactivity
autostart Starts the channel as soon as the process comes up, retrying with exponential backoff until it succeeds or the process exits

With neither set, on_demand is turned on automatically, so on-demand pulling is the default.

Kiln checks for idle channels every 5 seconds. A channel with no viewers for longer than idle_timeout_sec (90 seconds by default) is stopped, and the next request starts it again. Startup must fetch enough segments before publishing the first playlist, so an on-demand channel takes longer to show its first frame than an always-running one. The delay is controlled by start_segments and inflight_bytes under [packager]; see Media engine for tuning guidance.

A channel without on_demand is never reclaimed for idleness and stays connected once started. The switch also shapes restart behavior after an upstream failure: an on-demand channel that has already passed its idle window ends the session instead of restarting it.

The console does all of this too

Every field above has a form in the admin console, which also offers channel pre-warming, preview, connectivity probing, and bulk M3U import and export. Changes take effect immediately, with no file editing. See Admin console.

The key file is the one exception: it is read from disk only, and editing it requires a restart.

Next

  • Channels: the full field reference, grouping, import and export.
  • Playback: playback keys, access logs, and client setup.
  • Troubleshooting: where to look when a channel will not start.
Navigation

Type to search…

↑↓ navigate↵ selectEsc close