三只鸟Docker使用教程
sanzhiniao
把 某TV 的 DRM 直播流解密后,以标准 HLS 格式提供给任意播放器(VLC / IINA / mpv / PotPlayer 等)。
Docker 一条命令
不带代理
docker run -d --name sanzhiniao --restart=always -p 15678:15678 iptvtop/sanzhiniao带 HTTP 代理(环境变量方式)
docker run -d --name sanzhiniao --restart=always -p 15678:15678 \
-e UTV_PROXY=http://host.docker.internal:7890 iptvtop/sanzhiniao带 HTTP 代理(命令行参数方式)
docker run -d --name sanzhiniao --restart=always -p 15678:15678 \
iptvtop/sanzhiniao --proxy http://192.168.1.10:7890带 SOCKS5 代理
docker run -d --name sanzhiniao --restart=always -p 15678:15678 \
-e UTV_PROXY=socks5://host.docker.internal:1080 iptvtop/sanzhiniaodocker run -d --name sanzhiniao --restart=always -p 15678:15678 \
iptvtop/sanzhiniao --proxy socks5://192.168.1.10:1080host.docker.internal 是 Docker Desktop / 新版 Docker Engine 里指向宿主机的地址,Mac 与 Windows 通用。代理需要认证怎么办
如果代理服务器开启了账号密码认证,直接使用上面的命令会报错:
{
"error": "https://m-epg.cmishow.com:1443/...: Provided proxy credentials are incorrect"
}意思是代理返回了 401/407(Proxy Authentication Required),要求在代理地址里带上用户名密码。
带认证的 HTTP 代理:
docker run -d --name sanzhiniao --restart=always -p 15678:15678 \
iptvtop/sanzhiniao --proxy http://用户名:密码@192.168.1.10:7890带认证的 SOCKS5 代理:
docker run -d --name sanzhiniao --restart=always -p 15678:15678 \
iptvtop/sanzhiniao --proxy socks5://用户名:密码@192.168.1.10:1080环境变量写法同理:
docker run -d --name sanzhiniao --restart=always -p 15678:15678 \
-e UTV_PROXY=http://用户名:密码@192.168.1.10:7890 iptvtop/sanzhiniao注意事项:
- 用户名或密码里有
@、:、/、%等特殊字符时,需要做 URL 编码,例如@→%40、:→%3A、/→%2F、%→%25。 - 先确认代理是否真的开了认证:在宿主机执行
curl -x http://192.168.1.10:7890 -I https://m-epg.cmishow.com:1443/,如果返回407 Proxy Authentication Required,就是代理要求认证;如果 curl 能通而容器报错,多半是容器访问不到该代理地址。 - Clash / mihomo 默认的 mixed 端口(如 7890)一般不要求认证;如果你自己加了
authentication: [user:pass]配置,就必须用带凭据的写法。
docker-compose
services:
sanzhiniao:
image: iptvtop/sanzhiniao:latest
container_name: sanzhiniao
restart: always
ports:
- "15678:15678"
environment:
# 留空 = 直连;按需改成你的代理地址
UTV_PROXY: ""
# UTV_PROXY: "http://host.docker.internal:7890"
# UTV_PROXY: "socks5://host.docker.internal:1080"
# 代理需要认证时:
# UTV_PROXY: "http://用户名:密码@host.docker.internal:7890"
# 需要更多启动参数时用 command 覆盖(会替换默认 CMD):
# command: ["--proxy", "socks5://host.docker.internal:1080", "--channel-cache", "600"]启动:
docker compose up -d使用
启动后打开:
http://<主机IP>:15678/playlist.m3u播放器里添加这个地址即可。也可以单独播放某个频道:
http://<主机IP>:15678/play/<频道ID>.m3u8频道 ID 可以从 /playlist.m3u 里的播放地址看到。
启动参数
| 参数 | 默认值 | 说明 |
|---|---|---|
--host | 0.0.0.0 | 监听地址(容器内必须用 0.0.0.0) |
--port | 15678 | 监听端口 |
--groups | 本地,migu | 要输出的频道分组,逗号分隔 |
--proxy | 无 | 代理地址,支持 http://、socks4://、socks4a://、socks5:// |
--api-mode | auto | auto / adb / direct;容器内无 adb,实际等效 direct |
--channel-cache | 600 | 频道列表 / 详情 / playurl 链接缓存秒数 |
--playlist-cache | 0 | 上游 m3u8 内容缓存秒数(0 = 每次实时拉取) |
环境变量:
| 变量 | 说明 |
|---|---|
UTV_PROXY | 等效 --proxy,未显式传 --proxy 时生效 |
缓存策略
- 频道列表、频道详情、playurl 链接:内存缓存 600s
- 上游 m3u8 内容:默认不缓存,每次
/play实时拉取 - 分片 URL 映射:保留
MEDIA-SEQUENCE - 20之后的滑动窗口,不缓存 ts 内容 - 重启后缓存清空
代理域名清单(Clash / Surge 规则用)
服务端(容器内)实际发起请求的域名只有两类,走 UTV_PROXY 指定的代理:
| 域名 | 用途 | 协议 |
|---|---|---|
m-epg.cmishow.com | 频道列表 / 详情 / 播放地址 API | HTTPS(端口 1443) |
gslb.cdn.hk.chinamobile.com | m3u8 与 TS 分片 | HTTP |
Clash 规则(把这两条放到代理策略前面):
rules:
- DOMAIN-SUFFIX,cmishow.com,PROXY
- DOMAIN-SUFFIX,cdn.hk.chinamobile.com,PROXY播放器侧还会直接访问以下资源(不经过容器,由你的播放器请求;如播放器也走 Clash,可一并加规则):
| 域名 | 用途 |
|---|---|
epg.zsdc.eu.org | 节目单 EPG(播放列表 x-tvg-url) |
cdn.jsdelivr.net | 固定头部的注意事项 logo 与占位媒体流 |
pic-hwcdn.utvlive.top | 频道 logo |
Clash 规则示例:
rules:
# 服务端流量(容器内代理)
- DOMAIN-SUFFIX,cmishow.com,PROXY
- DOMAIN-SUFFIX,cdn.hk.chinamobile.com,PROXY
# 播放器侧资源(按需)
- DOMAIN,epg.zsdc.eu.org,DIRECT
- DOMAIN-SUFFIX,jsdelivr.net,DIRECT
- DOMAIN-SUFFIX,utvlive.top,DIRECT
- MATCH,PROXY说明:CDN 的 m3u8/ts 是明文 HTTP,如果你的 Clash 开了“仅代理加密流量”之类的规则,需要确保 cdn.hk.chinamobile.com 也命中代理或直连策略,视你的网络环境选择。