EPG 与 XMLTV 是什么
EPG(Electronic Program Guide,电子节目单)是 IPTV 用户最看重的体验之一。当你在 TiviMate 里看到"央视一套 19:00 新闻联播"这种节目表,背后靠的就是 EPG 数据。
XMLTV 是一个开源项目,定义了一套 XML 格式用于交换电视节目单数据,已成为 IPTV 的事实标准,几乎所有播放器都支持。
数据从哪里来
节目单数据常见来源:
- 电视台官网:央视、卫视等官网会公布每周节目表,可写爬虫抓取
- 开源抓取器:XMLTV 项目自带
tv_grab_*系列脚本,覆盖欧美主流频道 - 合作接口:部分内容方提供 JSON / XML 接口
- 第三方聚合站:如 IPTV-org 等社区维护的 EPG
版权提醒:节目单本身是节目信息,使用问题不大,但频道流可能涉及版权,本站不提供任何流地址。
XMLTV 文件格式
一个最小化的 XMLTV 文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tv SYSTEM "xmltv.dtd">
<tv source-info-url="https://52iptv.cn">
<channel id="cctv1">
<display-name>CCTV-1 综合</display-name>
<icon src="https://example.com/cctv1.png" />
</channel>
<programme start="20260810120000 +0800" stop="20260810123000 +0800"
channel="cctv1">
<title>新闻 30 分</title>
<desc>综合当日重大新闻</desc>
<category>新闻</category>
</programme>
<programme start="20260810190000 +0800" stop="20260810193000 +0800"
channel="cctv1">
<title>新闻联播</title>
<category>新闻</category>
</programme>
</tv>
关键字段:
channel:定义频道,id必须与 m3u 中tvg-id一致programme:单条节目,start/stop格式为YYYYMMDDHHmmss ZZdisplay-name/title/desc/category
使用 tv_grab 抓取
XMLTV 自带许多 grabber,Linux 安装:
apt install -y xmltv
# 列出所有 grabber
tv_grab_* --version
# 以欧洲 DVB 为例,首次交互式配置
tv_grab_eu_tvradio --configure
# 抓取最近 2 天的节目单
tv_grab_eu_tvradio --output epg.xml --days 2
国内频道通常需要自己写脚本抓取。一个简单的 Python 示例:
import requests, datetime
from xml.etree import ElementTree as ET
def now(n):
return (datetime.datetime.now() + datetime.timedelta(days=n)).strftime("%Y%m%d%H%M%S +0800")
tv = ET.Element("tv", {"source-info-url": "https://52iptv.cn"})
# 写一个频道
ch = ET.SubElement(tv, "channel", {"id": "cctv1"})
ET.SubElement(ch, "display-name").text = "CCTV-1 综合"
# 写一条节目
p = ET.SubElement(tv, "programme", {
"start": now(0), "stop": now(0).replace("+0800", " +0800"),
"channel": "cctv1"
})
ET.SubElement(p, "title").text = "新闻联播"
ET.ElementTree(tv).write("epg.xml", encoding="UTF-8", xml_declaration=True)
定时更新:EPG 应每天凌晨更新一次,使用 crontab:
0 3 * * * /usr/local/bin/refresh_epg.sh >> /var/log/epg.log 2>&1
接入播放器
把生成的 epg.xml 放到 Nginx 静态目录:
location /epg.xml {
alias /var/www/epg/epg.xml;
add_header Cache-Control "public, max-age=3600";
add_header Access-Control-Allow-Origin *;
}
在播放器中填入:
- TiviMate:设置 → EPG → 自定义 URL →
https://你的域名/epg.xml - Kodi:PVR IPTV Simple → EPG 设置 → Location Remote → URL
- iMplayer / OTT Navigator:在 EPG 选项中填 URL
同时 m3u 播放列表中每个频道需要带 tvg-id:
#EXTM3U
#EXTINF:-1 tvg-id="cctv1" tvg-name="CCTV-1" tvg-logo="https://example.com/cctv1.png" group-title="央视",CCTV-1 综合
https://example.com/live/cctv1.m3u8
tvg-id 必须与 XMLTV 中 channel 的 id 严格一致,否则节目单对不上号。
结尾
有了 EPG,IPTV 看起来就更像"电视"而不是"视频列表"了。下一篇文章我们聊 SIP 安全,敬请关注。