频道是 Kiln 的核心对象。每个频道由上游地址、输入格式和运行策略组成,对外提供一个播放地址,并在播放列表中占一行。下面按配置顺序介绍各个字段。
频道模型
标识与展示
id:频道的唯一标识,出现在播放地址、播放列表的tvg-id属性和访问日志里。改动它等于换一条频道,播放器侧的收藏与记录都会失效。title:显示名称,留空时回退为id。group:分组名,写进播放列表的group-title属性。logo_url:台标地址。留空且内置台标候选源命中时,播放列表会改指向/v1/logo/{id},由 Kiln 代取。epg_id、epg_name、epg_source:节目单匹配用的字段,epg_name留空时取title。详见 节目单 EPG。
节目源
节目源有两种写法,二选一:
upstream+path:upstream引用[[upstreams]]里的id,path拼接在该上游的base_url之后。path以http://或https://开头时按绝对地址处理,不再拼接。source_url:直接写完整地址。填了它就不需要upstream与path,并且该频道不会继承任何上游级请求头。
ingress 决定这条源怎么被处理,取值 hls 或 dash,留空按 hls 处理:
hls:同源分片代理,播放列表在返回前被改写,分片按需回源。dash:按全局kid:key本地解密后重封装为 HLS。启用状态下的 DASH 频道要求[packager].keys_file已配置,否则保存时报错。
运行方式
on_demand:无人观看时回收上游连接。打开后频道受空闲回收管辖。autostart:进程启动时主动拉起,不等第一个观众。idle_timeout_sec:空闲多久算无人观看,小于等于 0 时归一为90秒。只对on_demand频道生效。max_viewers:同时在看的观众上限。大于 0 时启用观众租约,超额的新观众收到 429;留空或 0 表示不限制。restart_on_failure:上游断流后自动重启。DASH 频道保存时会被强制打开。
两个开关组合出管理控制台里的三种运行方式:
autostart |
on_demand |
控制台标签 | 行为 |
|---|---|---|---|
| 关 | 开 | 有观众时启动 | 首个观众触发启动,空闲后回收 |
| 开 | 开 | 启动时预热 | 进程启动即拉起,空闲后仍会回收 |
| 开 | 关 | 始终运行 | 进程启动即拉起,不参与空闲回收 |
两个开关都关闭时,on_demand 会被自动打开,不存在既不预热也不按需的频道。
媒体选择
以下字段只作用于 DASH 频道的重封装路径,HLS 频道走同源代理,不做轨道计划:
prefer_height:目标分辨率高度。为 0 或留空时采用[ffmpeg].prefer_height。preferred_audio_languages:按优先级排列的音轨语言代码数组,例如["zh", "en"]。selection:更精确的轨道选择,可分别对视频、音频与字幕指定模式和具体轨道。packager:为当前频道指定封装引擎,取值与[packager].engine相同。留空时使用全局设置;填写其他值会导致配置校验失败。
精确选择轨道
视频可设为自动选择、限制最高分辨率,或精确指定一条轨道;音频可按语言偏好选择,也可以只接受指定轨道;字幕还可以完全关闭。轨道可以按 key、语言、角色、编码、分辨率,或 DASH 中的 AdaptationSet 和 Representation ID 匹配。exact 与 only 要求填写轨道条件,否则配置校验会失败。
使用 ffmpeg 引擎时,字幕仅支持 auto 和 off。全部字段与取值见 频道配置参考。
请求头
user_agent:该频道回源时使用的 User-Agent。headers:该频道回源时附加的请求头。与上游级headers合并,同名键以频道级为准。
固定请求头只会发送到源地址的同源请求。跨域重定向与播放列表中的外部资源不会收到这些请求头;HTTPS 的 FFmpeg 兼容路径如果无法保证同源,会直接拒绝请求,避免凭据泄漏。
停用
disabled 为真的频道不会出现在频道列表与播放列表里,播放请求按找不到处理。停用状态下的 DASH 频道即使还没配置全局密钥文件也允许保存,方便先落盘再补密钥。
上游定义
上游只在配置文件里定义,用来让多条频道共享同一个源站的地址与凭据:
[[upstreams]]
id = "origin"
base_url = "http://127.0.0.1:5050"
[upstreams.headers]
X-Custom = "value"id:频道通过upstream字段引用它。base_url:源站基础地址,频道的path拼接在它后面。headers:注入到该上游所有频道回源请求里的请求头,频道级headers可以逐键覆盖。
对应的频道写法:
[[channels]]
id = "hls-demo"
title = "Demo HLS"
group = "Demo"
upstream = "origin"
path = "/live/demo-hls"
ingress = "hls"
on_demand = true
autostart = false配置文件与管理控制台
两者不是同一份数据,边界值得记清楚:
- 频道:只有在首次启动且频道表为空时,Kiln 才会把配置文件里的
[[channels]]写入数据库。此后以数据库为准,改配置文件不会同步过去,也不会覆盖控制台里的改动。批量调整已有频道时,请使用控制台或管理接口。 - 上游:
[[upstreams]]始终只从配置文件读取,控制台不能新增或修改上游。频道保存时会校验引用的upstream是否存在于配置里,不存在直接拒绝。 - 对外基础地址:
server.public_base_url首次启动时写入设置表,之后以设置表为准,可以在控制台里改。 - 出站线路与 EPG 源:同样只在首次启动时写入,之后以数据库为准。
lite 变体不创建数据库,频道完全来自配置文件且只读,管理接口不可用。
启用与停用
- 单条频道通过
disabled字段启停,控制台的开关和管理接口都是改这个字段。 - 批量操作对应
POST /v1/admin/channels/enable-all与POST /v1/admin/channels/disable-all,需要write权限。 - 停用不会删除频道定义,也不会改变它在列表中的位置,但会立即停止当前播放会话,并让频道从对外列表中消失。
M3U 导入导出
导入
导入分预览与应用两步,都走 POST /v1/admin/import/m3u,由请求里的 apply 决定。预览返回每一条的动作与原因,确认后再应用。
解析与生成规则:
- 读取
#EXTINF行上的group-title、tvg-logo、tvg-id与tvg-name属性,以及行尾的标题。 - 频道
id由tvg-id生成 slug,没有就用标题,再没有就用地址里的路径;重名依次追加-2、-3,最长 48 个字符。 - 地址以
.mpd结尾推断为dash,其余为hls。 - 导入的频道一律写
source_url,并清空upstream与path。 - 新建的频道默认打开
on_demand,空闲超时 90 秒。 - 已存在同
id的频道视为更新,只有非空字段才覆盖原值。 - 地址非法或校验不通过的条目会被跳过,并在预览结果里标注原因。
- 导入不会删除列表里没有出现的频道。
- 应用时会带上预览时读到的修订号,期间被别处改过的频道会让整批返回 409,避免覆盖他人改动。
导出
POST /v1/admin/exports/m3u 返回一份可直接给播放器的 M3U 文件。它会自动创建一枚不限频道范围的播放密钥,播放列表里所有地址都落在 /p/{token}/play/ 前缀下,绝不嵌入管理员凭据。不再需要这份导出时,在控制台的「播放访问控制」里撤销对应密钥即可让它整体失效。
自检:warmup、probe 与 preview
三个接口经常被混用,但用途完全不同,都需要 refresh 权限。
probe:只测源,不建会话
POST /v1/admin/channels/{id}/probe 对上游做一次探测,全程不创建会话、不产生媒体。HLS 频道拉取一次源地址、读取开头一小段,返回状态码、内容类型、最终地址与耗时;DASH 频道解析 manifest,按 prefer_height 与 selection 做一次轨道计划,并校验全局密钥是否配齐。控制台的新建页还能用 POST /v1/admin/source-probes 探测尚未保存的草稿。适合排查地址、请求头与线路是否通。
warmup:提前拉起会话
POST /v1/admin/channels/{id}/warmup 在后台启动会话;频道已在运行时只刷新一次活跃时间。接口立刻返回 202,不等第一份播放列表就绪,所以它的成功只代表启动流程已经开始。用途是消掉按需频道的冷启动延迟。
preview:拿一枚临时播放凭据
POST /v1/admin/channels/{id}/preview 签发一枚 5 分钟有效的预览凭据,返回带 ?token= 的完整播放地址,供控制台内置播放器直接打开。预览凭据只能播放,调用任何管理接口都会被拒绝,因此可以安全地临时分享给同事验证画面。
排查顺序通常是 probe 先确认源可达,再 warmup 确认能起会话,最后 preview 确认画面正常。三步都过还有问题,转到 故障排查。