网络直播电视之寻找直播地址
来源:互联网 发布:linux pdf编辑 编辑:程序博客网 时间:2024/05/01 20:19
这种方式也不知道能坚持多长时间,暂时是没有什么问题。方法如下:
访问http://trailers.apple.com/appletv/index.xml
可以看到'http://atv.jianguoke.com/appletv/tv/tv.xml');"onPlay="">
打开http://atv.jianguoke.com/appletv/tv/tv.xml
可以看到直播电视的分类 打开央视直播
http://atv.jianguoke.com/appletv/tv/list_1.xml
可以看到cctv1
http://atv.jianguoke.com/appletv/tv/live_1_1.xml
继续打开可以得到新版的cctv1地址
http://tvhd.ak.live.cntv.cn/cache/1_/seg0/index.m3u8
通过这种方法便可以拿到直播地址了。如果拿人工的方式获取相关数据,毫无疑问累死人不偿命的。我会将有关这些XML解析的方法和函数进行公布,希望给大家提供一定的帮助。
接上文,上文中提到获取网络直播电视地址的方法,但是大量信息需要人工的方式进行处理,过于麻烦。所以本文针对三级的XML解析和下载工作进行处理。
技术点:1、利用tinyXML完成XML的解析工作 tinyxml下载
2、利用libcurl完成xml的下载工作 libcurl下载
公用下载函数:
- // 下载相关的XML
- static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
- {
- size_t nsize=size*nmemb;
- //…在这里保存数据
- string *strHtml=(string*)userp;
- strHtml->append((char*)buffer,nsize);
- return nsize;
- }
- bool downloadXml(const char* fileUrl, string& xmlStr)
- {
- if ("" == fileUrl)
- {
- dxreport("downloadXml: fileUrl is empty ...");
- return false;
- }
- xmlStr = ""; // 清空缓存XML
- CURL* m_curl = curl_easy_init();
- if (NULL == m_curl)
- {
- dxreport("downloadXml: create curl fail ...");
- return false;
- }
- string* str = new string();
- curl_easy_reset(m_curl); //主要是在重复调用GET/POST时,清空curl中的设置
- curl_easy_setopt(m_curl, CURLOPT_URL, fileUrl);
- curl_easy_setopt(m_curl, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(m_curl, CURLOPT_WRITEDATA,(void *)str);
- curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, write_data);
- CURLcode res = curl_easy_perform(m_curl);
- curl_easy_cleanup(m_curl);
- if (res != CURLE_OK || str->length() == 0)
- {
- dxreport("downloadXml: download xml fail! url = %s", fileUrl);
- cout << fileUrl << endl;
- return false;
- }
- xmlStr = *str;
- return true;
- }
解析第一级XML:
- <?xml version="1.0" encoding="UTF-8"?>
- <atv>
- <body>
- <listScrollerSplit id="com.sample.list-scroller-split">
- <header>
- <simpleHeader>
- <title>电视直播</title>
- </simpleHeader>
- </header>
- <menu>
- <sections>
- <menuSection>
- <header>
- <textDivider alignment="left">
- <title>类别选择</title>
- </textDivider>
- </header>
- <items>
- <oneLineMenuItem id="list_1">
- <label>央视直播</label>
- <preview>
- <link>http://atv.jianguoke.com/appletv/tv/list_1.xml</link>
- </preview>
- </oneLineMenuItem>
- </items>
- </menuSection>
- </sections>
- </menu>
- </listScrollerSplit>
- </body>
- </atv>
样例XML如上所示,现在我们开始解析工作。
- // 解析第一级XML
- bool parseFristXml(const char* fileName, list<CHANNEL_INFO>& listChannel)
- {
- string strXml = "";
- if (false == downloadXml(fileName, strXml))
- {
- return false;
- }
- TiXmlDocument* document = new TiXmlDocument();
- if (false == document->Parse(strXml.c_str()))
- {
- return false;
- }
- /*TiXmlDeclaration *decl;
- decl = document->FirstChild()->ToDeclaration();*/
- // 查找到根部
- TiXmlElement* rootElement = document->RootElement();
- TiXmlElement* keyBody = rootElement->FirstChildElement();
- TiXmlElement* keyListScrollerSplit = keyBody->FirstChildElement();
- TiXmlElement* keyHeadFrist = keyListScrollerSplit->FirstChildElement();
- TiXmlElement* keyMenu = keyHeadFrist->NextSiblingElement();
- if (keyMenu == NULL)
- {
- return false;
- }
- // 进入到menu中
- TiXmlElement* keySections = keyMenu->FirstChildElement();
- TiXmlElement* keySectionsMenu = keySections->FirstChildElement();
- TiXmlElement* keySectionsHeaderMenu = keySectionsMenu->FirstChildElement();
- TiXmlElement* keySectionsItems = keySectionsHeaderMenu->NextSiblingElement(); // 发现解析头部
- TiXmlElement* item = keySectionsItems->FirstChildElement(); // 取得第一个标签
- while (item)
- {
- CHANNEL_INFO info;
- TiXmlElement* oneLineMenuItem = item->FirstChildElement(); // 获取lable的内容
- info.name = changeTxtEncoding(oneLineMenuItem->GetText());
- oneLineMenuItem = oneLineMenuItem->NextSiblingElement()->FirstChildElement();
- info.fileUrl = oneLineMenuItem->GetText();
- listChannel.push_back(info); // 存储数据
- item = item->NextSiblingElement(); // 切到下个标记
- }
- return true;
- }
tinyXML函数的具体使用在这里就不累赘了,针对TinyXML解析方法可参见博客的其他相关内容。
解析第二级XML:
- <?xml version="1.0" encoding="UTF-8"?>
- <atv>
- <head>
- <script src="http://atv.jianguoke.com/appletv/video.js"/>
- </head>
- <body>
- <preview>
- <scrollerPreview id="com.sample.scrollerPreview">
- <items>
- <grid id="grid_1" columnCount="5">
- <items>
- <sixteenByNinePoster id="type1_1" alwaysShowTitles="true" accessibilityLabel="" onHoldSelect="savevideofav('http://atv.jianguoke.com/appletv/tv/live_1_1.xml', 'http://atv.jianguoke.com/appletv/tv/img/m_cctv1.png', 'CCTV-1 综合', '5')" onSelect="playvideo('http://atv.jianguoke.com/appletv/tv/live_1_1.xml', 'http://atv.jianguoke.com/appletv/tv/live_1_1.xml', 'CCTV-1 综合', '5')" onPlay="playvideo('http://atv.jianguoke.com/appletv/tv/live_1_1.xml', 'http://atv.jianguoke.com/appletv/tv/live_1_1.xml', 'CCTV-1 综合', '5')">
- <title>CCTV-1 综合</title>
- <image>http://atv.jianguoke.com/appletv/tv/img/m_cctv1.png</image>
- <defaultImage>resource://Poster.png</defaultImage>
- </sixteenByNinePoster>
- <sixteenByNinePoster id="type1_2" alwaysShowTitles="true" accessibilityLabel="" onHoldSelect="savevideofav('http://atv.jianguoke.com/appletv/tv/live_1_2.xml', 'http://atv.jianguoke.com/appletv/tv/img/m_cctv2.png', 'CCTV-2 财经', '5')" onSelect="playvideo('http://atv.jianguoke.com/appletv/tv/live_1_2.xml', 'http://atv.jianguoke.com/appletv/tv/live_1_2.xml', 'CCTV-2 财经', '5')" onPlay="playvideo('http://atv.jianguoke.com/appletv/tv/live_1_2.xml', 'http://atv.jianguoke.com/appletv/tv/live_1_2.xml', 'CCTV-2 财经', '5')">
- <title>CCTV-2 财经</title>
- <image>http://atv.jianguoke.com/appletv/tv/img/m_cctv2.png</image>
- <defaultImage>resource://Poster.png</defaultImage>
- </sixteenByNinePoster>
- </items>
- </grid>
- </items>
- </scrollerPreview>
- </preview>
- </body>
- </atv>
处理函数为:
- // 解析第二级XML
- bool parseSecondXml(list<CHANNEL_INFO> fristXmlChannel, list<CHANNEL_INFO>& secondXmlChannel)
- {
- int len = fristXmlChannel.size();
- if (len == 0)
- {
- dxreport("parseSecondXml: get fristXmlChannel is empty!");
- return false;
- }
- for (int i = 0; i < len; i++)
- {
- CHANNEL_INFO info;
- list<CHANNEL_INFO>::iterator iter = fristXmlChannel.begin();
- info = (*iter);
- fristXmlChannel.pop_front(); // 清除头部的数据
- string strXml = "";
- if (false == downloadXml(info.fileUrl.c_str(), strXml))
- {
- continue;
- }
- // 进行二级解析XML
- TiXmlDocument* document = new TiXmlDocument();
- if (false == document->Parse(strXml.c_str()))
- {
- return false;
- }
- TiXmlElement* element = document->RootElement();
- element = element->FirstChildElement();
- element = element->NextSiblingElement(); // body
- for (int i = 0; i < 6; i++)
- {
- element = element->FirstChildElement();
- }
- // 获取三级XML下载地址
- while (element)
- {
- TiXmlAttribute* attribute = element->FirstAttribute();
- while (attribute)
- {
- string keyName = attribute->Name();
- if (keyName == "onPlay")
- {
- // 获取到的内容如下格式:
- //"playvideo('http://atv.jianguoke.com/appletv/tv/live_1_1.xml', 'http://atv.jianguoke.com/appletv/tv/live_1_1.xml', 'CCTV-1 综合', '5')"
- string strContent = attribute->Value();
- // 解析字符串
- int len = strContent.length();
- string keyStr[4] = {"", "", "", ""};
- string str = "";
- int keyNum = 0;
- for (int i = 0; i < len; i ++)
- {
- if (strContent[i] == '\'')
- {
- if (strContent[i+1] == ',')
- {
- keyStr[keyNum] = str;
- keyNum ++;
- }
- str = "";
- continue;
- }
- str += strContent[i];
- }
- // 存储数据
- CHANNEL_INFO newInfo;
- newInfo.fileUrl = keyStr[0];
- newInfo.name = changeTxtEncoding(keyStr[2].c_str());
- secondXmlChannel.push_back(newInfo);
- }
- attribute = attribute->Next();
- }
- element = element->NextSiblingElement();
- }
- }
- return true;
- }
解析第三级XML:
- <?xml version="1.0" encoding="UTF-8"?>
- <atv>
- <body>
- <videoPlayer id="com.sample.video-player">
- <httpFileVideoAsset id="live_3_5">
- <mediaURL>http://182.140.144.32:8080/playlist/37.m3u8?key=rkH0PG-pfffEkcMUDSZoEwbswucCuObIj1fYeg..</mediaURL>
- <title/>
- <description/>
- <image/>
- </httpFileVideoAsset>
- </videoPlayer>
- </body>
- </atv>
解析函数:
- // 解析最后一级XML
- bool parseEndXml(list<CHANNEL_INFO> secondXmlChannel, list<CHANNEL_INFO>& endXmlChannel)
- {
- int len = secondXmlChannel.size();
- if (len == 0)
- {
- dxreport("parseSecondXml: get fristXmlChannel is empty!");
- return false;
- }
- for (int i = 0; i < len; i++)
- {
- CHANNEL_INFO info;
- list<CHANNEL_INFO>::iterator iter = secondXmlChannel.begin();
- info = (*iter);
- secondXmlChannel.pop_front(); // 清除头部的数据
- string strXml = "";
- if (false == downloadXml(info.fileUrl.c_str(), strXml))
- {
- continue;
- }
- // 进行三级级解析XML
- TiXmlDocument* document = new TiXmlDocument();
- if (false == document->Parse(strXml.c_str()))
- {
- return false;
- }
- TiXmlElement* element = document->RootElement();
- for (int i = 0; i < 4; i++)
- {
- element = element->FirstChildElement();
- }
- CHANNEL_INFO newInfo;
- newInfo.fileUrl = element->GetText();
- newInfo.name = info.name;
- endXmlChannel.push_back(newInfo);
- cout << newInfo.name << ":" << newInfo.fileUrl << endl;
- }
- return true;
- }
以上就是相关处理内容。望给各位有所帮助 ....
- 网络直播电视之寻找直播地址
- 网络直播电视之寻找直播地址(上)
- 网络直播电视之寻找直播地址(下)
- 网络电视在线直播地址大全
- 网络直播电视m3u8
- 网络直播电视m3u8
- 网络直播电视m3u8
- 网络直播电视之M3U8解析篇
- 网络直播电视之M3U8解析篇(上)
- 网络直播电视之M3U8解析篇 (下)
- 网络直播电视之M3U8解析篇 (下)
- 小米盒子直播电视
- 直播地址
- 爱视直播网络电视 v07.0201.01 免费下载
- 马谢电视辩论直播
- 可可直播电视---开通论坛
- 直播
- 直播
- zend studio代码自动提示问题,有的提示正常有的提示不正常,解决方法
- eclipse xml与properties文件字体大小修改
- Linux的中断处理的一些说明
- 使用curl获取web页面
- android ANR分析
- 网络直播电视之寻找直播地址
- 遍历python字典的几种方法
- UltraEdit常用快捷键
- 隐式Intent的本质及用法
- android实现屏幕截图并保存(去除状态栏)
- 用cURL实现HTTP操作
- HAProxy反向代理简单设置
- Codeforces Beta Round #31 (Div. 2, Codeforces format)——C
- VC在局域网中通过http协议获取公网IP地址