家里两条宽带一条移动一条电信,目前方案用的vlan实现的IPTV透传,好处是稳定。但受限只能一台机顶盒加装要花钱,感觉不完美。
而组播转单播的好处更多:
不需要vlan设备
不用网线WIFI就能看电视直播
智能电视也可以去掉机顶盒,直接按照TV播放器软件看电视直播
电脑手机按照播放器也能看
但是需要支持UDPXY的路由器,还要抓包获取当地的节目源(每个运行商各地区不一样)
下面开始操作
电信组播转单播
先从机顶盒背面拿到 STBID、 mac
然后把光猫的iptv口查到爱快空闲的WAN口,如果是单wan口的那就把光猫设置vlan绑定,然后把爱快wan口设置成【基于VLAN的混合模式】就可以上网和iptv共用端口了。我这里是多WAN口但是没必要多差一根网线,所以用的VLAN的混合模式
添加一条DHCP线路:vlanid你光猫里设置的、mac填机顶盒mac、option12填机顶盒STBID、option60填SCITV(抓包可以获取)
添加UDPXY 端口任意 只要是空闲的就行
然后l浏览器输入http://路由器IP:8111/status,显示这个表示设置成功了
获取电信直播源
这里我5年前买的8口网关交换机可以得MVP了,里面刚好有端口镜像用来抓包不要太简单。
交换机6口接机顶盒,7口接光猫IPTV,8口接电脑
然后设置8口镜像6口数据包
这时打开机顶盒,电脑打开小鲨鱼就开始跑数据包了
通过分析获取直播源列表步骤:
GET请求:
http://182.138.18.41:8082/EDS/jsp/AuthenticationURL?UserID=xxxxxxxxxxxxxxxx&Action=Login&Mode=MENU&UserToken=xxxxxxxxxxxxx
返回302跳转到指定认证地址,解析拿到320跳转的IP地址
POST请求获取SSID
http://跳转地址/EPG/jsp/ValidAuthenticationHWCTC.jsp
POST请求获取直播列表
http://跳转地址/EPG/jsp/getchannellistHWCTC.jsp
下面是用php写的脚本获取直播列表
<?php
require_once 'Curl.php';
$u = [
'ref' => 'http://yxidt.scrmt.org.cn:8001/UICloudAuthClient/api/authurl',
'url' => 'http://182.138.18.41:8082/EDS/jsp/AuthenticationURL?UserID=xxxxxxxxxxxxxxx&Action=Login&Mode=MENU&UserToken=xxxxxxx'
];
do{
$jieguo = Curl::http_send($u['url'],'GET',null,null,null,$u['ref']);
if(!$jieguo['status'] || $jieguo['status'] != 200){
echo $u['url']."\n请求失败\n\n";
var_dump($jieguo);
break;
}
$header = $jieguo['header'];
preg_match('/Location:(.*)/', $header, $matches);
$redirectUrl = trim(array_pop($matches));
$purl = parse_url($redirectUrl);
$purl['query'] = '';
#
#http://171.211.187.37:33200/EPG/jsp/ValidAuthenticationHWCTC.jsp
$purl['path'] = '/EPG/jsp/ValidAuthenticationHWCTC.jsp';
//$newrl = http_build_url($purl);
$newrl = $purl['scheme'] . '://' . $purl['host'] .(isset($purl['port']) ? ':' . $purl['port'] : '') .$purl['path'] . '?' . $purl['query'];
$form = [
"UserID" => "xxxxxxxxxxxxxxxx",
"Lang" => "0",
"SupportHD" => "1",
"NetUserID" => "",
"Authenticator" => "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"STBType" => "xxxxxxxxxxxx",
"STBVersion" => "xxxxxxxxxxx",
"conntype" => "dhcp",
"STBID" => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
#"userToken" => "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
#"userGroupId" => "715",
#"productPackageId" => "",
#"mac" => "xxxxxxxxxxxxxxxxxxxx",
#"UserField" => "",
#"SoftwareVersion" => "",
#"IsSmartStb" => "",
#"desktopId" => "",
#"stbmaker" => "",
#"XMPPCapability" => "",
#"ChipID" => "",
#"VIP" => ""
];
$jieguo = Curl::http_send($newrl,'POST',null,$form,null,$u['ref']);
if(!$jieguo['status'] || $jieguo['status'] != 200){
echo $newrl."\n请求失败\n\n";
var_dump($jieguo);
break;
}
$cookies = trim($jieguo['cookie'][0]);
preg_match('/name=\"UserToken\" value="(.*)\">/', $jieguo['body'], $matches);
$UserToken = trim(array_pop($matches));
preg_match('/name=\"stbid\" value="(.*)\">/', $jieguo['body'], $matches);
$stbid = trim(array_pop($matches));
preg_match('/name=\"UserID\" value="(.*)\">/', $jieguo['body'], $matches);
$UserID = trim(array_pop($matches));
//var_dump($cookies);
#http://171.211.187.37:33200/EPG/jsp/getchannellistHWCTC.jsp
$purl['path'] = '/EPG/jsp/getchannellistHWCTC.jsp';
$newrl = $purl['scheme'] . '://' . $purl['host'] .(isset($purl['port']) ? ':' . $purl['port'] : '') .$purl['path'] . '?' . $purl['query'];
$form = [
"conntype" => "dhcp",
"UserToken" => $UserToken,
"tempKey" => "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
"stbid" => $stbid,
"SupportHD" => "1",
"UserID" => $UserID,
"Lang" => "1"
];
$jieguo = Curl::http_send($newrl,'POST',$cookies,$form,null,$u['ref']);
if(!$jieguo['status'] || $jieguo['status'] != 200){
echo $newrl."\n请求失败\n\n";
var_dump($jieguo);
break;
}
#用正则提取频道
preg_match_all('/Authentication.CTCSetConfig\((.*)\);/', $jieguo['body'], $matches);
if(!is_array($matches[0])){
echo "频道信息解析失败!\n\n";
break;
}
$carry = array_pop($matches);
$outM3U = '';
#你路由器的UDPXY代理地址
$updhost="http://x.x.x.x:xxxx/udp"
for ($i = 0; $i < count($carry); $i++) {
preg_match('/ChannelName="([^"]*)/', $carry[$i], $matches);
$channelName = trim(array_pop($matches));
//var_dump($channelName);
preg_match('/ChannelURL="([^"]*)/', $carry[$i], $matches);
$channelURL = trim(array_pop($matches));
if($channelURL){
if($updhost){
$outM3U=$outM3U.'#EXTINF:-1,'.$channelName."\n".str_replace("igmp://", $updhost, $channelURL)."\n";
}else {
$outM3U=$outM3U.'#EXTINF:-1,'.$channelName."\n".$channelURL."\n";
}
}
}
#保存数据到文本
file_put_contents("scmsCT.m3u",$outM3U);
header ('Content-type: text/plain; charset=utf-8');
header ('Cache-Control: max-age=60');
header ('Content-Length: '.strlen ($outM3U));
echo $outM3U;
}while(false)
脚本其中的XXXXXX 在抓包获取就行,具体这个参数时效还没测试。
为了能在设备正常访问iptv的内部IP,还要在爱快做一条端口分流,内部IP都走添加的iptv那条线路。具体哪些IP段通过分析数据包,自行添加
http://183.223.113.218:7070/ysten-wtv-epg/epg/wtv/chlist?templateId=&abilityString=%7B%22CITY_CODE%22%3A%2219%22%2C%22COUNTY_CODE%22%3A%22101%22%2C%22VILLAGE_CODE%22%3A%22%22%2C%22abilities%22%3A%5B%22DL-3rd%22%2C%22fcc%22%2C%22NxM%22%2C%22fec%22%2C%224K-1%7Ccp-TENCENT%7CtimeShift%22%2C%22ver-tp%22%5D%2C%22businessGroupIds%22%3A%5B%5D%2C%22deviceGroupIds%22%3A%5B%224142%22%5D%2C%22districtCode%22%3A%22511400%22%2C%22labelIds%22%3A%5B%225140%22%2C%22511%22%5D%2C%22ucsUserAbilityRefresh%22%3A%221711904983721%22%2C%22userGroupIds%22%3A%5B%2251514953%22%5D%2C%22userLabelIds%22%3A%5B%225140%22%2C%22511%22%5D%7D&random=0.32319189538247883
评论区