找回密码
 立即注册
img_loading
智能检测中

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888广告投放联系QQ68610888
查看: 7227|回复: 24

[iptv信源 资源分享或寻求] 江苏电信IPTV直播源(RTSP认证源)在tvbox上播放(技术分析)

  [复制链接]
发表于 2023-12-5 17:46 | 显示全部楼层 |阅读模式
本帖最后由 op351 于 2023-12-5 17:46 编辑

接前两篇帖子
[iptv信源 资源分享或寻求] 江苏电信IPTV回看地址探究 (技术分析)
[iptv信源 资源分享或寻求] 江苏电信IPTV回看源在tvbox上进行播放 (技术分析)
在回看源搞定之后 我尝试将江苏电信的组播源也搬到tvbox来播放(原来在diyp播放)
但是搬过来以后发现换台速度极慢 起码要5秒
所以放弃udpxy转换的模式 转向直接使用江苏电信IPTV的RTSP源进行播放
经过验证 换台流畅度和原配机顶盒达到了差不多的程度 可以接受


本篇 我们就来看看如何使用tvbox来进行江苏电信IPTV RTSP源的抓取,存储和播放
顺带实现江苏电信IPTV原生EPG的抓取,存储和使用
tvbox配置文件存储,获取,全流程本地化也在本篇一并分析


tvbox版本:https://github.com/takagen99/Box takagen99版
路由器:斐讯K3
openwrt版本:23.05


接上回

我们打开jar爬虫项目
在iptvAuth方法的frameset_builder获取到返回报文后
使用正则剥离频道id和rstp源
  1. <font size="3">String tsurl = new String(response.body().bytes(), "UTF-8");
  2.         Pattern TimeShiftURLPattern = Pattern.compile("ChannelID="(.*)",ChannelName=".*",UserChannelID="\\d*",ChannelURL=".*",TimeShift="\\d*",ChannelSDP=".*",TimeShiftURL="(.*)",ChannelLogURL=");
  3.         Matcher TimeShiftURLMatch = TimeShiftURLPattern.matcher(tsurl);
  4.         try {
  5.             JSONArray timeShiftJsonTemp = new JSONArray();
  6.             while (TimeShiftURLMatch.find()) {
  7.                 JSONObject timet = new JSONObject();
  8.                 timet.put("chid", TimeShiftURLMatch.group(1));
  9.                 timet.put("rtspurl", TimeShiftURLMatch.group(2));
  10. //                tvlist += TimeShiftURLMatch.group(1) + ",";
  11. //                tvlist += TimeShiftURLMatch.group(2) + "\r\n";
  12.                 timeShiftJsonTemp.put(timet);
  13.             }
  14.             timeShiftJson = timeShiftJsonTemp;
  15.         } catch (Exception e) {

  16.         }</font>
复制代码
保存到timeShiftJson中备用


本地EPG实现:

新建方法setepg
1.获取/iptvepg/frame1194/play_channel.jsp的返回报文 (请在第一篇江苏电信IPTV回看地址探究中保存的wireshark文件中自行查找)
2.利用正则剥离江苏电信原生频道排序信息
  1. String chsl = new String(response.body().bytes(), "GB2312");
  2.                 Pattern channelListPattern = Pattern.compile("channelAllList":(.*),"mixnoAllList":");
  3.                 Matcher channelListMatch = channelListPattern.matcher(chsl);
  4.                 channelListMatch.find();
  5.                 JSONArray channelListJson = new JSONArray(channelListMatch.group(1));
复制代码
3.在openwrt上新建文件/cgi-bin/epgcheck

  1. #!/usr/bin/lua
  2. local EpgCheck = require 'EpgCheck'
  3. EpgCheck.Run()
复制代码
4.在openwrt上新建lua模块EpgCheck
  1. local EpgCheck = {}

  2. function EpgCheck.Run()
  3.     io.write("Content-type: text/html\nProgma: no-cache\n\n")
  4.     local time1f = io.popen("ls -l --full-time /www/CCTV1-HD.json")
  5.     local time1 = time1f:read()
  6.     if (time1 == nil)
  7.     then
  8.         print("false")
  9.     else
  10.         local time1date = string.match(time1, '%d+-%d+-%d+')
  11.         local time2f = io.popen("date +"%Y-%m-%d"")
  12.         local time2 = time2f:read()
  13.         if (time1date == time2)
  14.         then
  15.             print("true")
  16.         else
  17.             print("false")
  18.         end
  19.     end
  20. end

  21. return EpgCheck
复制代码
这个cgi的作用是减少epg的获取频次,仅在每天第一次启动tvbox时获取所有频道的EPG信息
5.建立频道分类数组
  1. Integer[] CCTV = new Integer[] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,140,152};
  2.             List cctv = Arrays.asList(CCTV);
  3.             Integer[] JSTV = new Integer[] {17,18,19,20,21,22,23,24,25,26,83,107,108,109,110,111,113,115};
  4.             List jstv = Arrays.asList(JSTV);
  5.             Integer[] DFTV = new Integer[] {17,32,33,34,35,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,57,58,59,60,61,62,63,64,65,77,85,86,87,107,116,117,118,119,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,137,138,139,141,142};
  6.             List dftv = Arrays.asList(DFTV);
  7.             Integer[] GQTV = new Integer[] {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,25,26,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,52,54,57,58,59,66,67,68,69,70,71,72,73,74,75,76,77,79,80,81,82,105,106,120,140,142,143,155,156,157};
  8.             List gqtv = Arrays.asList(GQTV);
复制代码
6.遍历之前存储的channelListJson
6.1进行频道分类,并存储到变量tvlist中
  1. String channelidTemp = channelListJson.getJSONObject(i).get("channelcode").toString();
  2.                     String channelname = channelListJson.getJSONObject(i).get("channelname").toString();
  3.                     if (!channelname.contains("HD") || channelname.contains("购物")) {
  4.                         continue;
  5.                     }
  6.                     String columncode = channelListJson.getJSONObject(i).get("columncode").toString();
  7.                     String mixno = channelListJson.getJSONObject(i).get("mixno").toString();
  8.                     String realmixno = channelListJson.getJSONObject(i).get("realmixno").toString();
  9.                     for (int j = 0; j < timeShiftJson.length(); j++) {
  10.                         if (channelidTemp.equals(timeShiftJson.getJSONObject(j).get("chid"))) {
  11.                             if (cctv.contains(i)) {
  12.                                 tvlist += "CCTV,#genre#" + "\r\n";
  13.                             }else if (jstv.contains(i)) {
  14.                                 tvlist += "江苏,#genre#" + "\r\n";
  15.                             }else if (dftv.contains(i)) {
  16.                                 tvlist += "卫视,#genre#" + "\r\n";
  17.                             }else if (gqtv.contains(i)) {
  18.                                 tvlist += "高清,#genre#" + "\r\n";
  19.                             } else {
  20.                                 tvlist += "其他,#genre#" + "\r\n";
  21.                             }
  22.                             tvlist += channelname + ",";
  23.                             tvlist += timeShiftJson.getJSONObject(j).get("rtspurl") + "\r\n";
  24.                         }
  25.                     }
复制代码
6.2在进入epg爬取之前,判断路由器上是否已有epg信息,有则跳过下面的代码
  1. client = new OkHttpClient().newBuilder()
  2.                     .build();
  3.             request = new Request.Builder()
  4.                     .url("http://192.168.8.1/cgi-bin/epgcheck")
  5.                     .get()
  6.                     .build();
  7.             response = client.newCall(request).execute();
  8.             String egresult = response.body().string().trim();
  9. if (egresult.equals("true")) {
  10.                         continue;
  11.                     }
复制代码
6.3epg爬取
获取/iptvepg/frame1194/CHANNEL_PLAYER_UTILS/datas/prevue_list.jsp报文  (请在第一篇江苏电信IPTV回看地址探究中保存的wireshark文件中自行查找)
通过正则剥离原始epg信息,并转化为tvbox可用格式
  1. String epgjson = new String(response.body().bytes(), "GB2312");
  2.                     JSONObject epg = new JSONObject(epgjson);
  3.                     String epglist = epg.get("channelPrevue").toString();
  4.                     JSONArray epgJsonBefore = new JSONArray(epglist);
  5.                     JSONArray epgJsonAfter = new JSONArray();
  6.                     for (int k = 0; k < epgJsonBefore.length(); k++) {
  7.                         JSONObject epgitem = new JSONObject();
  8.                         String title = epgJsonBefore.getJSONObject(k).get("prevuename").toString();
  9.                         String begintimet = epgJsonBefore.getJSONObject(k).get("begintime").toString();
  10.                         Pattern timePattern = Pattern.compile("\\d{4}.\\d{2}.\\d{2} (\\d{2}:\\d{2}):\\d{2}");
  11.                         Matcher btimeMatch = timePattern.matcher(begintimet);
  12.                         btimeMatch.find();
  13.                         String begintime = btimeMatch.group(1);
  14.                         String endtimet = epgJsonBefore.getJSONObject(k).get("endtime").toString();
  15.                         Matcher endtimeMatch = timePattern.matcher(endtimet);
  16.                         endtimeMatch.find();
  17.                         String endtime = endtimeMatch.group(1);
  18.                         epgitem.put("start", begintime);
  19.                         epgitem.put("desc", "");
  20.                         epgitem.put("end", endtime);
  21.                         epgitem.put("title", title);
  22.                         epgJsonAfter.put(epgitem);
  23.                     }
  24.                     Date now = new Date();
  25.                     SimpleDateFormat ST = new SimpleDateFormat("yyyy-MM-dd");
  26.                     String nowdate = ST.format(now);
  27.                     JSONObject epgFinal = new JSONObject();
  28.                     epgFinal.put("date", nowdate);
  29.                     epgFinal.put("channel_name", channelname);
  30.                     epgFinal.put("url", "");
  31.                     epgFinal.put("epg_data", epgJsonAfter);
  32.                     String epgFinalstring = epgFinal.toString();
复制代码
6.4上传epg信息到路由器
  1. MediaType mediaType = MediaType.parse("text/plain");
  2.                     RequestBody body = RequestBody.create(mediaType, epgFinalstring);
  3.                     request = new Request.Builder()
  4.                             .url("http://192.168.8.1/cgi-bin/uploadepg")
  5.                             .method("POST", body)
  6.                             .addHeader("User-Agent", URLEncoder.encode(channelname))
  7.                             .addHeader("Content-Type", "text/plain")
  8.                             .build();
  9.                     client.newCall(request).execute();
复制代码
6.5 /cgi-bin/uploadepg内容
  1. #!/usr/bin/lua
  2. local EpgJson = require 'EpgJson'
  3. EpgJson.Run()
复制代码
6.6lua模块EpgJson内容
  1. local EpgJson = {}
  2. require "nixio"

  3. function EpgJson.Run()
  4.    io.write("Content-type: text/html\nProgma: no-cache\n\n")
  5.    local epgjsonbody = io.read("*all")
  6.       http_headers = nixio.getenv()
  7.       local channame = http_headers['HTTP_USER_AGENT']
  8.       file = io.open(channame .. ".json", "w")
  9.    file:write(epgjsonbody)
  10.    io.close(file)
  11. end

  12. return EpgJson
复制代码
通过使用user-agent来传输频道名,以简化lua程序
json放置在body中,以原始text传送
最终文件生成为/www/xxx.json


在huikan方法中调用setepg
在homeContent方法中上传分类好的频道列表
  1. OkHttpClient client = new OkHttpClient().newBuilder()
  2.                     .build();
  3.             MediaType mediaType = MediaType.parse("text/plain");
  4.             RequestBody body = RequestBody.create(mediaType, tvlist);
  5.             Request request = new Request.Builder()
  6.                     .url("http://192.168.8.1/cgi-bin/iptvfile")
  7.                     .method("POST", body)
  8.                     .addHeader("Content-Type", "text/plain")
  9.                     .build();
  10.             client.newCall(request).execute();
复制代码
/cgi-bin/iptvfile内容
  1. #!/usr/bin/lua
  2. local WebService = require 'WebService'
  3. WebService.Run()
复制代码
lua模块WebService内容
  1. local WebService = {}

  2. function WebService.Run()
  3.    io.write("Content-type: text/html\nProgma: no-cache\n\n")
  4.    local tvlist = io.read("*all")
  5.    print(tvlist)
  6.    file = io.open("tv.txt", "w")
  7.    file:write(tvlist)
  8.    io.close(file)
  9. end

  10. return WebService
复制代码
最终频道分类表储存在/www/tv.txt中

接下来我们把源配置文件iptv.json和jar放置在路由器的/www目录下

在iptv.json中我们修改直播源url为本地的tv.txt
epg修改为本地cgi-bin接口getepg

/cgi-bin/getepg内容
  1. #!/usr/bin/lua
  2. local GetEpg = require 'GetEpg'
  3. GetEpg.Run()
复制代码
lua模块GetEpg内容
  1. local GetEpg = {}
  2. require "nixio"

  3. function GetEpg.Run()
  4.    io.write("Content-type: application/json\nProgma: no-cache\n\n")
  5.    http_headers = nixio.getenv()
  6.    local qs = http_headers['QUERY_STRING']
  7.         local channame = string.match(qs, 'ch=(.*)&')
  8.        file = io.open(channame .. ".json", "r")
  9.        local content = file:read "*a"
  10.        print(content)
  11.        file:close()
  12. end

  13. return GetEpg
复制代码


接下来我们看看实际效果




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

评分

参与人数 2恩山币 +2 收起 理由
玉宇科技 + 1 大神,能告诉一下,Authenticator的具体是.
奔驰的小野马 + 1 感谢你的分享,无论怎样,你都是最无私的人.

查看全部评分

只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
发表于 2023-12-5 18:00 来自手机 | 显示全部楼层
?b,太厉害了。
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-5 18:05 | 显示全部楼层
不明觉厉
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-5 18:25 | 显示全部楼层
感谢分享,一看这行文就知道什么叫专业~
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-5 18:58 | 显示全部楼层
厉害
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-5 20:08 | 显示全部楼层
插眼,表示好多看不懂
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-5 20:32 | 显示全部楼层
太深澳了,最好写一个转换软件,把m3u和txt直接转换成tvbox节目列表文件
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-5 21:22 | 显示全部楼层
很好,就是有点看不懂
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-6 08:11 | 显示全部楼层
厉害,就是看不懂
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-6 16:02 | 显示全部楼层
大佬真厉害
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-6 16:59 | 显示全部楼层
就是看不懂
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-7 10:49 | 显示全部楼层
mark一下
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-8 09:34 | 显示全部楼层
小白只有干瞪眼的份了 期待有一天能有插件
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-8 10:14 | 显示全部楼层
需要好好思考一下
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-12-8 11:12 | 显示全部楼层
太专业了,要是一键复制黏贴就好了
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

欢迎大家光临恩山无线论坛

只谈技术、莫论政事!切勿转播谣言!为了你也为了他人。
只谈技术、莫论政事!(点击见详情) 切记不要随意传播谣言,把自己的日子过安稳了就行,为了自己好也为了大家好。 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。

查看 »

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

GMT+8, 2025-6-28 08:09

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

| 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com

快速回复 返回顶部 返回列表