|
本帖最后由 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源
- <font size="3">String tsurl = new String(response.body().bytes(), "UTF-8");
- Pattern TimeShiftURLPattern = Pattern.compile("ChannelID="(.*)",ChannelName=".*",UserChannelID="\\d*",ChannelURL=".*",TimeShift="\\d*",ChannelSDP=".*",TimeShiftURL="(.*)",ChannelLogURL=");
- Matcher TimeShiftURLMatch = TimeShiftURLPattern.matcher(tsurl);
- try {
- JSONArray timeShiftJsonTemp = new JSONArray();
- while (TimeShiftURLMatch.find()) {
- JSONObject timet = new JSONObject();
- timet.put("chid", TimeShiftURLMatch.group(1));
- timet.put("rtspurl", TimeShiftURLMatch.group(2));
- // tvlist += TimeShiftURLMatch.group(1) + ",";
- // tvlist += TimeShiftURLMatch.group(2) + "\r\n";
- timeShiftJsonTemp.put(timet);
- }
- timeShiftJson = timeShiftJsonTemp;
- } catch (Exception e) {
- }</font>
复制代码 保存到timeShiftJson中备用
本地EPG实现:
新建方法setepg
1.获取/iptvepg/frame1194/play_channel.jsp的返回报文 (请在第一篇江苏电信IPTV回看地址探究中保存的wireshark文件中自行查找)
2.利用正则剥离江苏电信原生频道排序信息
- String chsl = new String(response.body().bytes(), "GB2312");
- Pattern channelListPattern = Pattern.compile("channelAllList":(.*),"mixnoAllList":");
- Matcher channelListMatch = channelListPattern.matcher(chsl);
- channelListMatch.find();
- JSONArray channelListJson = new JSONArray(channelListMatch.group(1));
复制代码 3.在openwrt上新建文件/cgi-bin/epgcheck
- #!/usr/bin/lua
- local EpgCheck = require 'EpgCheck'
- EpgCheck.Run()
复制代码 4.在openwrt上新建lua模块EpgCheck
- local EpgCheck = {}
- function EpgCheck.Run()
- io.write("Content-type: text/html\nProgma: no-cache\n\n")
- local time1f = io.popen("ls -l --full-time /www/CCTV1-HD.json")
- local time1 = time1f:read()
- if (time1 == nil)
- then
- print("false")
- else
- local time1date = string.match(time1, '%d+-%d+-%d+')
- local time2f = io.popen("date +"%Y-%m-%d"")
- local time2 = time2f:read()
- if (time1date == time2)
- then
- print("true")
- else
- print("false")
- end
- end
- end
- return EpgCheck
复制代码 这个cgi的作用是减少epg的获取频次,仅在每天第一次启动tvbox时获取所有频道的EPG信息
5.建立频道分类数组
- 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};
- List cctv = Arrays.asList(CCTV);
- Integer[] JSTV = new Integer[] {17,18,19,20,21,22,23,24,25,26,83,107,108,109,110,111,113,115};
- List jstv = Arrays.asList(JSTV);
- 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};
- List dftv = Arrays.asList(DFTV);
- 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};
- List gqtv = Arrays.asList(GQTV);
复制代码 6.遍历之前存储的channelListJson
6.1进行频道分类,并存储到变量tvlist中
- String channelidTemp = channelListJson.getJSONObject(i).get("channelcode").toString();
- String channelname = channelListJson.getJSONObject(i).get("channelname").toString();
- if (!channelname.contains("HD") || channelname.contains("购物")) {
- continue;
- }
- String columncode = channelListJson.getJSONObject(i).get("columncode").toString();
- String mixno = channelListJson.getJSONObject(i).get("mixno").toString();
- String realmixno = channelListJson.getJSONObject(i).get("realmixno").toString();
- for (int j = 0; j < timeShiftJson.length(); j++) {
- if (channelidTemp.equals(timeShiftJson.getJSONObject(j).get("chid"))) {
- if (cctv.contains(i)) {
- tvlist += "CCTV,#genre#" + "\r\n";
- }else if (jstv.contains(i)) {
- tvlist += "江苏,#genre#" + "\r\n";
- }else if (dftv.contains(i)) {
- tvlist += "卫视,#genre#" + "\r\n";
- }else if (gqtv.contains(i)) {
- tvlist += "高清,#genre#" + "\r\n";
- } else {
- tvlist += "其他,#genre#" + "\r\n";
- }
- tvlist += channelname + ",";
- tvlist += timeShiftJson.getJSONObject(j).get("rtspurl") + "\r\n";
- }
- }
复制代码 6.2在进入epg爬取之前,判断路由器上是否已有epg信息,有则跳过下面的代码
- client = new OkHttpClient().newBuilder()
- .build();
- request = new Request.Builder()
- .url("http://192.168.8.1/cgi-bin/epgcheck")
- .get()
- .build();
- response = client.newCall(request).execute();
- String egresult = response.body().string().trim();
- if (egresult.equals("true")) {
- continue;
- }
复制代码 6.3epg爬取
获取/iptvepg/frame1194/CHANNEL_PLAYER_UTILS/datas/prevue_list.jsp报文 (请在第一篇江苏电信IPTV回看地址探究中保存的wireshark文件中自行查找)
通过正则剥离原始epg信息,并转化为tvbox可用格式
- String epgjson = new String(response.body().bytes(), "GB2312");
- JSONObject epg = new JSONObject(epgjson);
- String epglist = epg.get("channelPrevue").toString();
- JSONArray epgJsonBefore = new JSONArray(epglist);
- JSONArray epgJsonAfter = new JSONArray();
- for (int k = 0; k < epgJsonBefore.length(); k++) {
- JSONObject epgitem = new JSONObject();
- String title = epgJsonBefore.getJSONObject(k).get("prevuename").toString();
- String begintimet = epgJsonBefore.getJSONObject(k).get("begintime").toString();
- Pattern timePattern = Pattern.compile("\\d{4}.\\d{2}.\\d{2} (\\d{2}:\\d{2}):\\d{2}");
- Matcher btimeMatch = timePattern.matcher(begintimet);
- btimeMatch.find();
- String begintime = btimeMatch.group(1);
- String endtimet = epgJsonBefore.getJSONObject(k).get("endtime").toString();
- Matcher endtimeMatch = timePattern.matcher(endtimet);
- endtimeMatch.find();
- String endtime = endtimeMatch.group(1);
- epgitem.put("start", begintime);
- epgitem.put("desc", "");
- epgitem.put("end", endtime);
- epgitem.put("title", title);
- epgJsonAfter.put(epgitem);
- }
- Date now = new Date();
- SimpleDateFormat ST = new SimpleDateFormat("yyyy-MM-dd");
- String nowdate = ST.format(now);
- JSONObject epgFinal = new JSONObject();
- epgFinal.put("date", nowdate);
- epgFinal.put("channel_name", channelname);
- epgFinal.put("url", "");
- epgFinal.put("epg_data", epgJsonAfter);
- String epgFinalstring = epgFinal.toString();
复制代码 6.4上传epg信息到路由器
- MediaType mediaType = MediaType.parse("text/plain");
- RequestBody body = RequestBody.create(mediaType, epgFinalstring);
- request = new Request.Builder()
- .url("http://192.168.8.1/cgi-bin/uploadepg")
- .method("POST", body)
- .addHeader("User-Agent", URLEncoder.encode(channelname))
- .addHeader("Content-Type", "text/plain")
- .build();
- client.newCall(request).execute();
复制代码 6.5 /cgi-bin/uploadepg内容
- #!/usr/bin/lua
- local EpgJson = require 'EpgJson'
- EpgJson.Run()
复制代码 6.6lua模块EpgJson内容
- local EpgJson = {}
- require "nixio"
- function EpgJson.Run()
- io.write("Content-type: text/html\nProgma: no-cache\n\n")
- local epgjsonbody = io.read("*all")
- http_headers = nixio.getenv()
- local channame = http_headers['HTTP_USER_AGENT']
- file = io.open(channame .. ".json", "w")
- file:write(epgjsonbody)
- io.close(file)
- end
- return EpgJson
复制代码 通过使用user-agent来传输频道名,以简化lua程序
json放置在body中,以原始text传送
最终文件生成为/www/xxx.json
在huikan方法中调用setepg
在homeContent方法中上传分类好的频道列表
- OkHttpClient client = new OkHttpClient().newBuilder()
- .build();
- MediaType mediaType = MediaType.parse("text/plain");
- RequestBody body = RequestBody.create(mediaType, tvlist);
- Request request = new Request.Builder()
- .url("http://192.168.8.1/cgi-bin/iptvfile")
- .method("POST", body)
- .addHeader("Content-Type", "text/plain")
- .build();
- client.newCall(request).execute();
复制代码 /cgi-bin/iptvfile内容
- #!/usr/bin/lua
- local WebService = require 'WebService'
- WebService.Run()
复制代码 lua模块WebService内容
- local WebService = {}
- function WebService.Run()
- io.write("Content-type: text/html\nProgma: no-cache\n\n")
- local tvlist = io.read("*all")
- print(tvlist)
- file = io.open("tv.txt", "w")
- file:write(tvlist)
- io.close(file)
- end
- return WebService
复制代码 最终频道分类表储存在/www/tv.txt中
接下来我们把源配置文件iptv.json和jar放置在路由器的/www目录下
在iptv.json中我们修改直播源url为本地的tv.txt
epg修改为本地cgi-bin接口getepg
/cgi-bin/getepg内容
- #!/usr/bin/lua
- local GetEpg = require 'GetEpg'
- GetEpg.Run()
复制代码 lua模块GetEpg内容
- local GetEpg = {}
- require "nixio"
- function GetEpg.Run()
- io.write("Content-type: application/json\nProgma: no-cache\n\n")
- http_headers = nixio.getenv()
- local qs = http_headers['QUERY_STRING']
- local channame = string.match(qs, 'ch=(.*)&')
- file = io.open(channame .. ".json", "r")
- local content = file:read "*a"
- print(content)
- file:close()
- end
- return GetEpg
复制代码
接下来我们看看实际效果
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
评分
-
查看全部评分
|