TX视频真实地址解析及OC编码实现

来源:互联网 发布:汉王扫描软件下载 编辑:程序博客网 时间:2024/06/05 09:34

转载请注明出处:http://blog.csdn.net/cywn_d/article/details/15498155

接近两天的时间,研究了下各大视频网站的视频真实地址解析,目前已测试成功并且写出相应的代码解析成功的有两个。

一个是比较简单的乐视网,获取到的是flv格式的流媒体。

另外一个是稍微复杂一点的腾讯视频,获取到的是IOS可以播放的MP4格式。

先看腾讯视频地址的解析:

首先我们选择一个视频网页地址:http://v.qq.com/boke/page/c/k/t/c0120tujmkt.html

打开谷歌浏览器Chrome,输入网址,打开浏览器自带的开发者工具,打开Network选项


这时候我们可以在里面看到各种数据,这些是访问网页过程中发送的一个个数据包。

我们用到的主要是三个数据包:


getinfo、getkey和那个长长的网址:

http://182.131.19.163/videoctfs.tc.qq.com/c0120tujmkt.p702.1.mp4?sdtfrom=v1000&type=mp4&vkey=4583D5ADFE088C69F470E88B94564AD972421D78F921B5C4A2C9F1C515FA88D90A570AA56B99300A&level=1&sha=7760577b713dcbd4156dabf1407780880c1cfb3d&platform=1&br=71&fmt=hd&sp=0

这个网址实际上就是视频的真实地址,我们可以直接复制到浏览器里面打开,就能得到我们想要的视频。


但我们要做的是在没有查看数据包的情况下,使用代码通过网页地址 http://v.qq.com/boke/page/c/k/t/c0120tujmkt.html 解析出实际的网址。


我们既然能通过数据包查看得到真正的地址,那么可不可以逆向分析,从实际地址去分析出这个地址形成的算法呢?

首先我们再次观察一下这个URL:

http://182.131.19.163/videoctfs.tc.qq.com/c0120tujmkt.p702.1.mp4?sdtfrom=v1000&type=mp4&vkey=4583D5ADFE088C69F470E88B94564AD972421D78F921B5C4A2C9F1C515FA88D90A570AA56B99300A&level=1&sha=7760577b713dcbd4156dabf1407780880c1cfb3d&platform=1&br=71&fmt=hd&sp=0

 

很明显,这是由一个基本的域名加上后面一个不知道是什么东西的数据在加上一坨的参数。

这些参数要怎么得到呢?没错,就是用到前面的两个数据包,一个是getinfo请求,一个是getkey请求。

首先我们看getinfo,network里面点击后可以查看到具体的网址:




http://vv.video.qq.com/getinfo?这个就是getinfo请求d网址,而后面的参数呢?看这里:


http://vv.video.qq.com/getinfo?pid=19F846EBE3D9ABBFEFB1677AB381B7462B3158EC&fp2p=1&platfom=11&charge=0&speed=561&otype=xml&ran=0.515370836481452&appver=3.2.11.162&vids=c0120tujmkt

这个网址访问后得到的是一个XML页面

<root>   <fl>     <cnt>4</cnt>      <fi>       <br>64</br>        <id>1</id>        <name>flv</name>        <sb>1</sb>        <sl>0</sl>     </fi>      <fi>       <br>64</br>        <id>2</id>        <name>mp4</name>        <sb>1</sb>        <sl>0</sl>     </fi>      <fi>       <br>235</br>        <id>10702</id>        <name>hd</name>        <sb>1</sb>        <sl>1</sl>     </fi>      <fi>       <br>64</br>        <id>10703</id>        <name>sd</name>        <sb>1</sb>        <sl>0</sl>     </fi>   </fl>    <hs>0</hs>    <ls>0</ls>    <preview>81</preview>    <s>o</s>    <sfl>     <cnt>0</cnt>   </sfl>    <tm>1384164866</tm>    <vl>     <cnt>1</cnt>      <vi>       <br>71</br>        <ch>0</ch>        <cl>         <ci>           <cd>81.583</cd>            <cmd5>f869b5f3f12372b12ecde2895e7a2173</cmd5>            <cs>6029078</cs>            <idx>1</idx>            <keyid>c0120tujmkt.10702.1</keyid>         </ci>          <fc>1</fc>       </cl>        <fmd5>11f48bc152b79275e3b99e3678afab09</fmd5>        <fn>c0120tujmkt.p702.mp4</fn>        <fs>6029144</fs>        <fst>5</fst>        <lnk>c0120tujmkt</lnk>        <logo>1</logo>        <share>1</share>        <st>2</st>        <td>81.583</td>        <ti>baidu</ti>        <type>3</type>        <ul>         <ui>           <dt>2</dt>            <dtc>0</dtc>            <url>http://182.131.19.158/videoctfs.tc.qq.com/</url>            <vt>301</vt>         </ui>          <ui>           <dt>2</dt>            <dtc>0</dtc>            <url>http://113.142.31.87/videoctfs.tc.qq.com/</url>            <vt>301</vt>         </ui>          <ui>           <dt>2</dt>            <dtc>10</dtc>            <url>http://video.dispatch.tc.qq.com/</url>            <vt>0</vt>         </ui>       </ul>        <vh>360</vh>        <vid>c0120tujmkt</vid>        <videotype>0</videotype>        <vw>640</vw>     </vi>   </vl> </root>


从这些数据我们可以看到一个很明显的<vid>c0120tujmkt</vid>,到这个vid看着很眼熟,没错,就是网页的地址http://v.qq.com/boke/page/c/k/t/c0120tujmkt.html 红色部分,那么我们可以猜测,这个xml应该存储了一些我们要用到的参数。

现在我们要先回到原来的问题,

http://vv.video.qq.com/getinfo?pid=19F846EBE3D9ABBFEFB1677AB381B7462B3158EC&fp2p=1&platfom=11&charge=0&speed=561&otype=xml&ran=0.515370836481452&appver=3.2.11.162&vids=c0120tujmkt

这个网址的参数是怎么得到的呢?

这么多的参数,是不是每一个都有用的,可不可以去掉一些没用参数?经过测试,很幸运的,只需要两个参数,一个是vids,一个是otype.

vids我们已经知道了,就是网页网址的后面那部分,而otype应该是固定的xml,也就是说,我们可以通过访问以下网址得到刚才的xml页面:

http://vv.video.qq.com/getinfo?vids=c0120tujmkt&otype=xml


很好,成功得到了这个xml页面,那这个页面到底有什么用呢?我们暂且先不管,刚才分析了getinfo这个请求,现在我们再接着看getkey这个请求


这个请求大URL是:http://vv.video.qq.com/getkey  参数呢?看下面:


所以完整的url是:

http://vv.video.qq.com/getkey?ran=0.5321996449492872&format=10702&filename=c0120tujmkt.p702.1.mp4&platform=11&otype=xml&chrage=0&vt=301&vid=c0120tujmkt

那么,这些参数是否每一项都是必须的呢?测试了一下,发现只需要这几个参数:format,otype,vid,filename,vt

首先 otype=xml 和vid=c010tujmkt这两项已知道。那么只剩下format,vt以及filename了,这两个参数的值在哪?没错,就在前面getinfo获取的xml页面中

<root>   <fl>     <cnt>4</cnt>      <fi>       <br>64</br>        <id>1</id>        <name>flv</name>        <sb>1</sb>        <sl>0</sl>     </fi>      <fi>       <br>64</br>        <id>2</id>        <name>mp4</name>        <sb>1</sb>        <sl>0</sl>     </fi>      <fi>       <br>235</br>        <id>10702</id>        <name>hd</name>        <sb>1</sb>        <sl>1</sl>     </fi>      <fi>       <br>64</br>        <id>10703</id>        <name>sd</name>        <sb>1</sb>        <sl>0</sl>     </fi>   </fl>    <hs>0</hs>    <ls>0</ls>    <preview>81</preview>    <s>o</s>    <sfl>     <cnt>0</cnt>   </sfl>    <tm>1384218072</tm>    <vl>     <cnt>1</cnt>      <vi>       <br>71</br>        <ch>0</ch>        <cl>         <ci>           <cd>81.583</cd>            <cmd5>f869b5f3f12372b12ecde2895e7a2173</cmd5>            <cs>6029078</cs>            <idx>1</idx>            <keyid>c0120tujmkt.10702.1</keyid>         </ci>          <fc>1</fc>       </cl>        <fmd5>11f48bc152b79275e3b99e3678afab09</fmd5>        <fn>c0120tujmkt.p702.mp4</fn>        <fs>6029144</fs>        <fst>5</fst>        <lnk>c0120tujmkt</lnk>        <logo>1</logo>        <share>1</share>        <st>2</st>        <td>81.583</td>        <ti>baidu</ti>        <type>3</type>        <ul>         <ui>           <dt>2</dt>            <dtc>0</dtc>            <url>http://182.131.19.163/videoctfs.tc.qq.com/</url>            <vt>301</vt>         </ui>          <ui>           <dt>2</dt>            <dtc>0</dtc>            <url>http://113.142.31.87/videoctfs.tc.qq.com/</url>            <vt>301</vt>         </ui>          <ui>           <dt>2</dt>            <dtc>10</dtc>            <url>http://video.dispatch.tc.qq.com/</url>            <vt>0</vt>         </ui>       </ul>        <vh>360</vh>        <vid>c0120tujmkt</vid>        <videotype>0</videotype>        <vw>640</vw>     </vi>   </vl> </root>


format就是name=hd的那个id的值,而filename中间还差了一个参数,差了一个1

<fi><br>235</br><id>10702</id><name>hd</name><sb>1</sb><sl>1</sl></fi>


猜测是这边某一项的值。vt很明显的可以看到是301

接下来继续访问这个精简后的URL:

http://vv.video.qq.com/getkey?format=10702&filename=c0120tujmkt.p702.1.mp4&otype=xml&vid=c0120tujmkt&vt=301

 我们可以得到这样一个xml页面:

 

<root>   <br>73901.15625</br>    <ct>604800</ct>    <key>A8D78BE1265F483EEBA868059788106553C7DB3522A9C21BD74690189132D4B74BB5BB4C14407D28</key>    <level>1</level>    <levelvalid>1</levelvalid>    <s>o</s>    <sha>7760577b713dcbd4156dabf1407780880c1cfb3d</sha>    <sp>0</sp>    <sr>0</sr> </root>

这里面哪些参数有用呢,先不管,先回过头看看第一次解析到的视频真实地址:

http://182.131.19.163/videoctfs.tc.qq.com/c0120tujmkt.p702.1.mp4?sdtfrom=v1000&type=mp4&vkey=4583D5ADFE088C69F470E88B94564AD972421D78F921B5C4A2C9F1C515FA88D90A570AA56B99300A&level=1&sha=7760577b713dcbd4156dabf1407780880c1cfb3d&platform=1&br=71&fmt=hd&sp=0

这个URL去掉不必要的参数后为:

http://182.131.19.163/videoctfs.tc.qq.com/c0120tujmkt.p702.1.mp4?type=mp4&vkey=4583D5ADFE088C69F470E88B94564AD972421D78F921B5C4A2C9F1C515FA88D90A570AA56B99300A&level=1&sha=7760577b713dcbd4156dabf1407780880c1cfb3d&fmt=hd


http://182.131.19.163/videoctfs.tc.qq.com/这个网址可以在getinfo获取的xml中找到:

<ui>

<dt>2</dt>

<dtc>0</dtc>

<url>http://182.131.19.163/videoctfs.tc.qq.com/</url>

<vt>301</vt>

</ui>

vt也可以在其中找到。

c0120tujmkt.p702.1.mp4这个就是filename.

type=mp4这个值就是我们要获取的视频的格式

fmt=hd这个要与id10702对应。

vkey=4583D5ADFE088C69F470E88B94564AD972421D78F921B5C4A2C9F1C515FA88D90A570AA56B99300A

sha=7760577b713dcbd4156dabf1407780880c1cfb3d

这两个就是 getkey获取到的xml里面的值。


那么,整理一下过程:

1.首先拿到我们要访问的视频的网页地址:

 http://v.qq.com/boke/page/c/k/t/c0120tujmkt.html 

取出其中红色部分。

2.将红色部分加入下面的网址变成http://vv.video.qq.com/getinfo?vids=c0120tujmkt&otype=xml 

3.从获取的xml页面中取出以下几项参数的值:

 fmt,format,filename,vt,url

url就是视频的url前缀,例子中是http://182.131.19.163/videoctfs.tc.qq.com/

够造出如下地址: 

http://vv.video.qq.com/getkey?format=10702&filename=c0120tujmkt.p702.1.mp4&otype=xml&vid=c0120tujmkt&vt=301  

4.访问后得到两个参数,key 和sha

最终形成了视频d真实地址:

 http://182.131.19.163/videoctfs.tc.qq.com/c0120tujmkt.p702.1.mp4?type=mp4&vkey=4583D5ADFE088C69F470E88B94564AD972421D78F921B5C4A2C9F1C515FA88D90A570AA56B99300A&level=1&sha=7760577b713dcbd4156dabf1407780880c1cfb3d&fmt=hd


以下是我根据这个过程编写的Objective-C代码: 


- (NSString*)resovleQqVideoUrl:(NSString*) qqVideoUrl{    //解析出腾讯视频网页中的视频地址    static NSString* qqVideoPrefixUrl=@"http://vv.video.qq.com/getinfo?type=xml&vids=";    static NSString* qqVideoPrefixUrl2=@"http://vv.video.qq.com/getkey?";    int loc=5;    for(int i=0;i<qqVideoUrl.length;i++){        NSString *s = [qqVideoUrl substringWithRange:NSMakeRange(i, 1)];        if([s isEqualToString:@"/"])            loc=i;    }        NSString* vid=[qqVideoUrl substringWithRange:NSMakeRange(loc+1,qqVideoUrl.length-6-loc)];    NSString* xmlUrl=[NSString stringWithFormat:@"%@%@",qqVideoPrefixUrl,vid];            //NSError* error;    NSURLRequest* request=[NSURLRequest requestWithURL:[NSURL URLWithString:xmlUrl]];        NSData* response=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];    NSString *xmlContent = [[NSString alloc]initWithBytes:[response bytes]length:[response length]encoding:NSUTF8StringEncoding];        NSError *parseError = nil;    NSDictionary *xmlDictionary = [XMLReader dictionaryForXMLString:xmlContent error:parseError];        NSDictionary* tmpDic=[[[xmlDictionary objectForKey:@"root"] objectForKey:@"fl"] objectForKey:@"fi"];    //得到词典中所有Value值    NSEnumerator * enumeratorValue = [tmpDic objectEnumerator];    NSString* format;    NSString* sl;    //快速枚举遍历所有Value的值    for (NSObject* object in enumeratorValue) {        NSDictionary* dic =(NSDictionary*)object;        if([[[dic objectForKey:@"name"] objectForKey:@"text"] isEqualToString:@"hd"]){            format=[[dic objectForKey:@"id"] objectForKey:@"text"];            sl=[[dic objectForKey:@"sl"] objectForKey:@"text"];        }    }        NSArray* tmpDicArray=[[[[[xmlDictionary objectForKey:@"root"] objectForKey:@"vl"] objectForKey:@"vi"] objectForKey:@"ul"] objectForKey:@"ui"];    //得到词典中所有Value值    NSDictionary* tmpDic2=[tmpDicArray firstObject];    NSString* url;    NSString* vt;    url=[[tmpDic2 objectForKey:@"url"] objectForKey:@"text"];    vt=[[tmpDic2 objectForKey:@"vt"] objectForKey:@"text"];               /* NSDictionary* tmpDic2=[[[[[xmlDictionary objectForKey:@"root"] objectForKey:@"vl"] objectForKey:@"vi"] objectForKey:@"cl"] objectForKey:@"fn"];*/    NSString* tmpStr=[[[[[xmlDictionary objectForKey:@"root"] objectForKey:@"vl"] objectForKey:@"vi"] objectForKey:@"fn"] objectForKey:@"text"];        NSString* fileName=[NSString stringWithFormat:@"%@.%@.mp4",[tmpStr substringToIndex:tmpStr.length-4],sl];    NSString* type=@"xml";        NSString* xmlUrl2=[NSString stringWithFormat:@"%@format=%@&type=%@&vid=%@&filename=%@&vt=%@",qqVideoPrefixUrl2,format,type,vid,fileName,vt];        NSURLRequest* request2=[NSURLRequest requestWithURL:[NSURL URLWithString:xmlUrl2]];        NSData* response2=[NSURLConnection sendSynchronousRequest:request2 returningResponse:nil error:nil];    NSString *xmlContent2 = [[NSString alloc]initWithBytes:[response2 bytes]length:[response2 length]encoding:NSUTF8StringEncoding];        NSDictionary *xmlDictionary2 = [XMLReader dictionaryForXMLString:xmlContent2 error:parseError];        NSString* key=[[[xmlDictionary2 objectForKey:@"root"] objectForKey:@"key"] objectForKey:@"text"];    NSString* sha=[[[xmlDictionary2 objectForKey:@"root"] objectForKey:@"sha"] objectForKey:@"text"];        NSString* realUrl=[NSString stringWithFormat:@"%@%@?type=mp4&vkey=%@&sha=%@&fmt=hd",url,fileName,key,sha];    NSLog(@"%@",realUrl);    return realUrl;} 



原创粉丝点击