广东电信 IPTV 单线复用以及 openwrt 实现 IPTV 源代理

发表于 2022-06-07   |   分类于 默认分类   |   访问: 531 次

背景

上文中提到了广东电信的 IPTV 验证过程。虽然知道了验证方法,并且实现了自动提取频道列表,但是由于提取的 rtsp 链接是带验证而且有过期时间的,所以需要定期手动给直播软件更新源。某些直播软件能使用在线源,但是很多是不行的,这就很麻烦了。于是写了一个小程序实现 IPTV 源代理,每天自动刷新源。

IPTV 专线

PPPoE 拨号

首先需要让 IPTV 走专线,不干扰互联网链接。首先需要在路由器进行 IPTV 专线拨号。广东电信的 IPTV 是 VLAN ID 为 45 的 PPPoE 验证。在 Openwrt 中直接创建 iface.45 的接口既可以让 PPPoE 在 VLAN 45 上拨号。但是这里发现,如果已经拨号了互联网,即 VLAN 41 的 PPPoE 拨号,IPTV 拨号会失败。这是因为 MAC 地址和互联网拨号相同,需要给 VLAN 45 的虚拟接口设置另一个 MAC 地址。拨号之后可以获得一个内网地址。

这里给出配置示例,实际上在 luci 中手动添加适配即可:

config device
        option type '8021q'
        option ifname 'enp4s0f1'
        option vid '45'
        option name 'enp4s0f1.45'
        option macaddr '12:34:56:78:9A:BC' # 这里跟 WAN 不一样即可

路由

然后需要让 IPTV 的 IP 走 IPTV 接口。首先确保 wan 和 iptv 接口都勾选了默认网关,然后分别设置跃点。然后利用 mwan3 来实现分流。我这边的配置如下:

config policy 'wan_only'
        list use_member 'wan_member'
        option last_resort 'default'

config policy 'iptv_only'
        list use_member 'iptv_member'
        option last_resort 'default'

config rule 'iptv_rule4'
        option proto 'all'
        option sticky '0'
        option use_policy 'iptv_only'
        option dest_ip '202.105.0.0/16'
        option family 'ipv4'

config rule 'iptv_rule3'
        option proto 'all'
        option sticky '0'
        option use_policy 'iptv_only'
        option dest_ip '183.59.0.0/16'
        option family 'ipv4'

config rule 'iptv_rule2'
        option proto 'all'
        option sticky '0'
        option use_policy 'iptv_only'
        option dest_ip '125.88.52.0/24'
        option family 'ipv4'

config rule 'iptv_rule'
        option proto 'all'
        option sticky '0'
        option use_policy 'iptv_only'
        option dest_ip '59.37.208.0/24'
        option family 'ipv4'

config rule 'wan_rule'
        option proto 'all'
        option sticky '0'
        option use_policy 'wan_only'

config member 'iptv_member'
        option interface 'iptv'
        option metric '20'
        option weight '1'

config member 'wan_member'
        option interface 'wan'
        option metric '1'
        option weight '1'

config globals 'globals'
        option mmx_mask '0x3F00'

config interface 'wan'
        option enabled '1'
        option family 'ipv4'
        option reliability '2'
        option initial_state 'online'
        option track_method 'ping'
        option count '1'
        option size '56'
        option max_ttl '60'
        option check_quality '0'
        option timeout '4'
        option interval '10'
        option failure_interval '5'
        option recovery_interval '5'
        option down '5'
        option up '5'

config interface 'iptv'
        option enabled '1'
        option initial_state 'online'
        option family 'ipv4'
        option track_method 'ping'
        option reliability '1'
        option count '1'
        option size '56'
        option max_ttl '60'
        option check_quality '0'
        option timeout '4'
        option interval '10'
        option failure_interval '5'
        option recovery_interval '5'
        option down '5'
        option up '5'

这里我的互联网接口叫 wan,IPTV 的接口叫 iptv。根据实际情况修改即可。至于分流的 IP 段可以自己用提取的 rtsp 链接跑跑看,然后确定出来的 302 目标。

UPnP

创建 IPTV 拨号之后我才发现,我的 miniupnp 坏掉了,原来是因为 miniupnp 跑去用 iptv 的接口当外网接口了,然后发现是内网 IP 就凉了。
修复很简单,手动改 upnp 的 wan 的接口:

config upnpd 'config'
        option external_iface 'wan'

这里我使用 upnpclient 进行测试。

IPTV 代理

由于爬出来的 RTSP 链接有期限,所以这里使用写了个 rust 程序验证 IPTV 账号,爬取链接,缓存起来,开一个简单的 RTSP 服务,然后把所有请求 302 过去真实目标。
具体逻辑如下:

  1. 监听端口 192.168.1.1:7878
  2. 播放器请求 rtsp://192.168.1.1:7878/{id}
  3. 服务器验证 IPTV 账号,获取频道列表,检查频道 ID 为 {id} 的频道的真实 RTSP 链接
  4. 服务器返回 302,让播放器跳转到真实 RTSP 链接
  5. 播放器播放真实 RTSP 链接

这样下来,只要频道 ID 是稳定的,那就能让局域网的播放器始终使用 rtsp://192.168.1.1:7878/{id} 链接,然后就能获取最新的有效的 RTSP 播放地址了。另外为了避免转台就获取频道列表,可以懒加载频道列表并且缓存起来,一天更新一次。
这里开源了一个实现 https://github.com/yujincheng08/rust-iptv-proxy ,编译(README 有 x86_64 的 openwrt 编译的方法)之后放到 openwrt 下,提供账号密码 MAC 地址和监听地址即可。至于 IPTV 频道列表导出(比如要导出 m3u 文件导入到播放器),可以改改 https://github.com/yujincheng08/tellyget-gd ,把输出链接成 rtsp://{bind_addr}/{channel_id} 即可。

仅有 1 条评论


  1. Ratel

    Openwrt感觉有点难用,本来准备用N1当旁路,直接给我劝退了

    Ratel  June 9th, 2022 at 04:32 pm回复

发表新评论

© 2022 Powered by Typecho & Theme Quark
粤ICP备17055048号