网络直播电视之寻找直播地址

来源:互联网 发布: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下载

   公用下载函数:

[cpp] view plaincopy
  1. // 下载相关的XML  
  2. static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)  
  3. {  
  4.     size_t nsize=size*nmemb;  
  5.   
  6.     //…在这里保存数据  
  7.     string *strHtml=(string*)userp;  
  8.     strHtml->append((char*)buffer,nsize);  
  9.   
  10.     return nsize;  
  11. }  
  12. bool downloadXml(const char* fileUrl, string& xmlStr)  
  13. {  
  14.     if ("" == fileUrl)  
  15.     {  
  16.         dxreport("downloadXml: fileUrl is empty ...");  
  17.         return false;  
  18.     }  
  19.   
  20.     xmlStr = "";            // 清空缓存XML  
  21.     CURL* m_curl = curl_easy_init();  
  22.     if (NULL == m_curl)  
  23.     {  
  24.         dxreport("downloadXml: create curl fail ...");  
  25.         return false;  
  26.     }  
  27.   
  28.     string* str = new string();   
  29.     curl_easy_reset(m_curl);                                                     //主要是在重复调用GET/POST时,清空curl中的设置  
  30.     curl_easy_setopt(m_curl, CURLOPT_URL, fileUrl);  
  31.     curl_easy_setopt(m_curl, CURLOPT_FOLLOWLOCATION, 1);  
  32.     curl_easy_setopt(m_curl, CURLOPT_WRITEDATA,(void *)str);   
  33.     curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, write_data);  
  34.       
  35.     CURLcode res = curl_easy_perform(m_curl);    
  36.     curl_easy_cleanup(m_curl);   
  37.   
  38.     if (res != CURLE_OK || str->length() == 0)  
  39.     {  
  40.         dxreport("downloadXml: download xml fail! url = %s", fileUrl);  
  41.         cout << fileUrl << endl;  
  42.         return false;  
  43.     }  
  44.   
  45.     xmlStr = *str;  
  46.     return true;  
  47. }  


 

   解析第一级XML:

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <atv>  
  3.     <body>  
  4.         <listScrollerSplit id="com.sample.list-scroller-split">  
  5.             <header>  
  6.                 <simpleHeader>  
  7.                     <title>电视直播</title>  
  8.                 </simpleHeader>  
  9.             </header>  
  10.             <menu>  
  11.                 <sections>  
  12.                     <menuSection>  
  13.                         <header>  
  14.                             <textDivider alignment="left">  
  15.                                 <title>类别选择</title>  
  16.                             </textDivider>  
  17.                         </header>  
  18.                         <items>  
  19.                             <oneLineMenuItem id="list_1">  
  20.                                 <label>央视直播</label>  
  21.                                 <preview>  
  22.                                     <link>http://atv.jianguoke.com/appletv/tv/list_1.xml</link>  
  23.                                 </preview>  
  24.                             </oneLineMenuItem>  
  25.                         </items>  
  26.                     </menuSection>  
  27.                 </sections>  
  28.             </menu>  
  29.         </listScrollerSplit>  
  30.     </body>  
  31. </atv>  

     样例XML如上所示,现在我们开始解析工作。


[cpp] view plaincopy
  1. // 解析第一级XML  
  2. bool parseFristXml(const char* fileName, list<CHANNEL_INFO>& listChannel)  
  3. {  
  4.     string strXml = "";  
  5.     if (false == downloadXml(fileName, strXml))  
  6.     {  
  7.         return false;  
  8.     }  
  9.   
  10.     TiXmlDocument* document = new TiXmlDocument();  
  11.     if (false == document->Parse(strXml.c_str()))  
  12.     {  
  13.         return false;  
  14.     }  
  15.   
  16.     /*TiXmlDeclaration *decl; 
  17.         decl = document->FirstChild()->ToDeclaration();*/  
  18.     // 查找到根部  
  19.     TiXmlElement* rootElement = document->RootElement();  
  20.   
  21.     TiXmlElement* keyBody = rootElement->FirstChildElement();  
  22.     TiXmlElement* keyListScrollerSplit = keyBody->FirstChildElement();  
  23.   
  24.     TiXmlElement* keyHeadFrist = keyListScrollerSplit->FirstChildElement();  
  25.     TiXmlElement* keyMenu = keyHeadFrist->NextSiblingElement();  
  26.     if (keyMenu == NULL)  
  27.     {  
  28.         return false;  
  29.     }  
  30.   
  31.     // 进入到menu中  
  32.     TiXmlElement* keySections = keyMenu->FirstChildElement();  
  33.     TiXmlElement* keySectionsMenu = keySections->FirstChildElement();  
  34.     TiXmlElement* keySectionsHeaderMenu = keySectionsMenu->FirstChildElement();  
  35.     TiXmlElement* keySectionsItems = keySectionsHeaderMenu->NextSiblingElement(); // 发现解析头部  
  36.     TiXmlElement* item = keySectionsItems->FirstChildElement();                    // 取得第一个标签  
  37.     while (item)  
  38.     {  
  39.         CHANNEL_INFO info;  
  40.         TiXmlElement* oneLineMenuItem = item->FirstChildElement(); // 获取lable的内容  
  41.         info.name = changeTxtEncoding(oneLineMenuItem->GetText());  
  42.         oneLineMenuItem = oneLineMenuItem->NextSiblingElement()->FirstChildElement();  
  43.         info.fileUrl = oneLineMenuItem->GetText();  
  44.         listChannel.push_back(info);                               // 存储数据   
  45.         item = item->NextSiblingElement();                          // 切到下个标记  
  46.     }  
  47.     return true;  
  48. }  

       tinyXML函数的具体使用在这里就不累赘了,针对TinyXML解析方法可参见博客的其他相关内容。
      

       解析第二级XML:

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <atv>  
  3.     <head>  
  4.         <script src="http://atv.jianguoke.com/appletv/video.js"/>  
  5.     </head>  
  6.     <body>  
  7.         <preview>  
  8.             <scrollerPreview id="com.sample.scrollerPreview">  
  9.                 <items>  
  10.                     <grid id="grid_1" columnCount="5">  
  11.                         <items>  
  12.                             <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')">  
  13.                                 <title>CCTV-1 综合</title>  
  14.                                 <image>http://atv.jianguoke.com/appletv/tv/img/m_cctv1.png</image>  
  15.                                 <defaultImage>resource://Poster.png</defaultImage>  
  16.                             </sixteenByNinePoster>  
  17.                             <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')">  
  18.                                 <title>CCTV-2 财经</title>  
  19.                                 <image>http://atv.jianguoke.com/appletv/tv/img/m_cctv2.png</image>  
  20.                                 <defaultImage>resource://Poster.png</defaultImage>  
  21.                             </sixteenByNinePoster>  
  22.                         </items>  
  23.                     </grid>  
  24.                 </items>  
  25.             </scrollerPreview>  
  26.         </preview>  
  27.     </body>  
  28. </atv>  

      处理函数为:


[cpp] view plaincopy
  1. // 解析第二级XML  
  2. bool parseSecondXml(list<CHANNEL_INFO> fristXmlChannel, list<CHANNEL_INFO>& secondXmlChannel)  
  3. {  
  4.     int len = fristXmlChannel.size();  
  5.     if (len == 0)  
  6.     {  
  7.         dxreport("parseSecondXml: get fristXmlChannel is empty!");  
  8.         return false;  
  9.     }  
  10.   
  11.     for (int i = 0; i < len; i++)  
  12.     {  
  13.         CHANNEL_INFO info;  
  14.         list<CHANNEL_INFO>::iterator iter = fristXmlChannel.begin();  
  15.         info = (*iter);  
  16.         fristXmlChannel.pop_front();    // 清除头部的数据  
  17.   
  18.         string strXml = "";  
  19.         if (false == downloadXml(info.fileUrl.c_str(), strXml))  
  20.         {  
  21.             continue;  
  22.         }  
  23.   
  24.         // 进行二级解析XML  
  25.         TiXmlDocument* document = new TiXmlDocument();  
  26.         if (false == document->Parse(strXml.c_str()))  
  27.         {  
  28.             return false;  
  29.         }  
  30.   
  31.         TiXmlElement* element = document->RootElement();  
  32.         element = element->FirstChildElement();  
  33.         element = element->NextSiblingElement(); // body  
  34.         for (int i = 0; i < 6; i++)  
  35.         {  
  36.             element = element->FirstChildElement();  
  37.         }  
  38.   
  39.         // 获取三级XML下载地址   
  40.         while (element)  
  41.         {  
  42.             TiXmlAttribute* attribute = element->FirstAttribute();  
  43.             while (attribute)  
  44.             {  
  45.                 string keyName = attribute->Name();  
  46.                 if (keyName == "onPlay")  
  47.                 {  
  48.                     // 获取到的内容如下格式:  
  49.                     //"playvideo('http://atv.jianguoke.com/appletv/tv/live_1_1.xml', 'http://atv.jianguoke.com/appletv/tv/live_1_1.xml', 'CCTV-1 综合', '5')"  
  50.                     string strContent = attribute->Value();  
  51.                       
  52.                     // 解析字符串  
  53.                     int len = strContent.length();  
  54.                     string keyStr[4] = {""""""""};  
  55.                     string str = "";  
  56.                     int keyNum = 0;  
  57.                     for (int i = 0; i < len; i ++)  
  58.                     {  
  59.                         if (strContent[i] == '\'')  
  60.                         {  
  61.                             if (strContent[i+1] == ',')  
  62.                             {  
  63.                                 keyStr[keyNum] = str;  
  64.                                 keyNum ++;  
  65.                             }  
  66.                             str = "";  
  67.                             continue;  
  68.                         }  
  69.                         str += strContent[i];  
  70.                     }  
  71.                       
  72.                     // 存储数据  
  73.                     CHANNEL_INFO newInfo;  
  74.                     newInfo.fileUrl = keyStr[0];  
  75.                     newInfo.name    = changeTxtEncoding(keyStr[2].c_str());  
  76.                     secondXmlChannel.push_back(newInfo);  
  77.                 }  
  78.                 attribute = attribute->Next();  
  79.             }  
  80.               
  81.             element = element->NextSiblingElement();  
  82.         }  
  83.           
  84.   
  85.     }  
  86.       
  87.     return true;  
  88. }  

    

      解析第三级XML:

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <atv>  
  3.     <body>  
  4.         <videoPlayer id="com.sample.video-player">  
  5.             <httpFileVideoAsset id="live_3_5">  
  6.                 <mediaURL>http://182.140.144.32:8080/playlist/37.m3u8?key=rkH0PG-pfffEkcMUDSZoEwbswucCuObIj1fYeg..</mediaURL>  
  7.                 <title/>  
  8.                 <description/>  
  9.                 <image/>  
  10.             </httpFileVideoAsset>  
  11.         </videoPlayer>  
  12.     </body>  
  13. </atv>  

      解析函数:


[cpp] view plaincopy
  1. // 解析最后一级XML  
  2. bool parseEndXml(list<CHANNEL_INFO> secondXmlChannel, list<CHANNEL_INFO>& endXmlChannel)  
  3. {  
  4.     int len = secondXmlChannel.size();  
  5.     if (len == 0)  
  6.     {  
  7.         dxreport("parseSecondXml: get fristXmlChannel is empty!");  
  8.         return false;  
  9.     }  
  10.   
  11.     for (int i = 0; i < len; i++)  
  12.     {  
  13.         CHANNEL_INFO info;  
  14.         list<CHANNEL_INFO>::iterator iter = secondXmlChannel.begin();  
  15.         info = (*iter);  
  16.         secondXmlChannel.pop_front();   // 清除头部的数据  
  17.   
  18.         string strXml = "";  
  19.         if (false == downloadXml(info.fileUrl.c_str(), strXml))  
  20.         {  
  21.             continue;  
  22.         }  
  23.   
  24.         // 进行三级级解析XML  
  25.         TiXmlDocument* document = new TiXmlDocument();  
  26.         if (false == document->Parse(strXml.c_str()))  
  27.         {  
  28.             return false;  
  29.         }  
  30.   
  31.         TiXmlElement* element = document->RootElement();  
  32.         for (int i = 0; i < 4; i++)  
  33.         {  
  34.             element = element->FirstChildElement();  
  35.         }  
  36.         CHANNEL_INFO newInfo;  
  37.         newInfo.fileUrl = element->GetText();  
  38.         newInfo.name    = info.name;  
  39.         endXmlChannel.push_back(newInfo);  
  40.   
  41.         cout << newInfo.name << ":" << newInfo.fileUrl << endl;  
  42.     }  
  43.     return true;  
  44. }  

       
        以上就是相关处理内容。望给各位有所帮助 ....


原创粉丝点击