Kiln 会下载已启用的 XMLTV 源,将节目与频道匹配,再合并成一份节目单。播放器只需访问 /v1/epg.xml.gz,无需了解背后有多少个来源。
工作方式
- 节目单源在管理控制台的「节目单」页维护,结果保存在 SQLite 中,不需要改配置文件。
- 内置预设源默认全部停用。首次使用时必须手动启用至少一个,或者添加自定义源。
- 配置文件里的
[[epg.sources]]只在数据库中还没有任何源记录时写入一次,之后一律以数据库为准。 - 没有 EPG 总开关。是否对外输出节目单,只取决于「有没有已启用的源」。Lite 构建不提供节目单,配置里出现任何已启用的 EPG 源都会让进程拒绝启动。
[epg]
cache = true
cache_dir = "./data/epg"
refresh_interval_min = 360
max_refresh_concurrency = 0
max_source_bytes = 67108864
default_timezone = "UTC"
serve_timezone = "keep"启用源
在「节目单」页启用一个内置源,或添加自定义源,填写可访问的 XMLTV 地址,.xml 与 .xml.gz 都支持。
首次刷新
点击「立即刷新」。Kiln 会立刻抓取全部已启用的源,并按源列出频道数、节目数与失败原因。
确认匹配
在频道页面为「待确认」和「未匹配」的频道指定对应的节目单频道。只有匹配成功的频道才会进入对外输出,参见 频道管理。
缓存模式
cache 与 cache_dir 一起决定原始 XMLTV 的保存方式,共三种组合。
cache = true,cache_dir 指向一个目录,缺省为 {data_dir}/epg。
每个源的原始 XMLTV 以「JSON 头加正文」的形式落盘,带长度与 SHA-256 校验,写入时先写临时文件再原子替换。缓存跨重启存活,抓取时会带上 If-None-Match 与 If-Modified-Since,源没有变化时直接命中 304。抓取或解析失败时,可以退回上一次的缓存内容继续对外提供。
cache = true,且 cache_dir = "memory"(:memory: 等价)。
条件请求与失败回退的行为与磁盘一致,但不产生任何磁盘写入,进程重启后需要重新完整下载一遍。适合只读根文件系统,或不希望在数据目录里堆积大文件的部署。
cache = false。
不保存原始 XMLTV,也就没有条件请求与失败回退。此外,每次访问 /v1/epg.xml 或 /v1/epg.xml.gz 都会先同步刷新一遍全部源,再渲染响应。
刷新
refresh_interval_min默认 360。进程启动后先立即刷新一次,之后按此间隔滚动刷新。max_refresh_concurrency为0表示所有源同时刷新;正数表示同时最多刷新这么多个源。- 在
server.resource_mode = "auto"(默认值)下,0与过大的正数都会根据探测到的 CPU 和内存降低到安全值,进入低资源档位时固定为 1。constrained同样固定为 1,performance则完全不做这类调整。取值细节见 配置参考。
手动刷新用 POST /v1/admin/epg/refresh,需要 refresh 权限。没有任何已启用的源时返回 409。刷新按源独立进行,个别源失败不会影响其它源,响应里会带回每个源的最新状态。
体积上限
max_source_bytes 默认 64 MiB(67108864),作用于解压之后的 XMLTV 正文。
- 下载超限时本轮抓取失败,已有数据保持可用并被标记为过期,不会被半截内容覆盖。
- 缓存中已经超限的条目同样会被丢弃,不参与回退。
- 在
auto模式下,这个值也会随可用内存降低:内存低于 256 MiB 时降到 4 MiB,其余低资源档位按内存量在 4 MiB 到 64 MiB 之间取值。
时区
- 每个源都可以单独设置 IANA 时区,用于解析源里没有带偏移标注的时间戳。控制台中新建的自定义源默认使用
UTC。 default_timezone是源未声明时区时的兜底,必须是合法的 IANA 名称,非法值会导致启动时配置校验失败。serve_timezone目前只接受keep:输出保留每条节目原有的 UTC 偏移,Kiln 不会把全部时间统一换算到某个时区。填其它值同样会导致配置校验失败。
逐源出口
每个源都有独立的出口设置,与全局出站路由配合使用。
| 取值 | 含义 |
|---|---|
direct |
默认值,直接连接,不参与出站路由规则 |
auto |
跟随全局出站路由,按规则决定直连还是走某条线路 |
| 某条线路的 id | 固定走这条线路,忽略路由规则 |
对外输出
| 路径 | 鉴权 | 说明 |
|---|---|---|
GET /v1/epg.xml |
无 | 合并后的 XMLTV |
GET /v1/epg.xml.gz |
无 | 同一份内容的 gzip 版本 |
GET /v1/logo/{id} |
无 | 频道台标,命中内置台标表时回源代取 |
- 输出只包含匹配成功的频道。频道 ID 会被改写成 Kiln 自己的频道 ID,对应节目一并改写,播放器因此可以直接用 M3U 里的
tvg-id对上号。 /v1/playlist.m3u以及播放密钥下的分发列表,会在#EXTM3U上带x-tvg-url指向/v1/epg.xml.gz。- 没有任何已启用的源时,两个端点返回一份合法但为空的 XMLTV,而不是 404。
- gzip 结果会在内存中缓存一份,源数据或频道列表变化后自动失效;压缩后体积超过
max_source_bytes的四分之一(最多 8 MiB)时不缓存,直接返回。 - 台标端点会将频道的
epg_name(留空时使用标题)标准化,再查询内置台标表并依次尝试候选地址。单张图片最大 2 MiB;成功时使用一小时公共缓存,并通过X-Kiln-Logo-Source标明实际来源。没有候选地址时返回 404;存在候选地址但全部下载失败时返回 502。台标下载同样使用该频道的网络出口。
管理端接口
| 方法与路径 | 权限 |
|---|---|
GET /v1/admin/epg/presets、/v1/admin/epg/sources、/v1/admin/epg/matches |
read |
POST /v1/admin/epg/sources、PUT /v1/admin/epg/sources/{id} |
write |
DELETE /v1/admin/epg/sources/{id} |
delete |
POST /v1/admin/epg/refresh |
refresh |
更新与删除需要带 If-Match 版本号,冲突时返回 409。删除内置预设源是隐藏而不是物理删除,其它接口的完整说明见 API 参考。