前端

如何通获取腾讯视频源地址达到免广告的目的

今天介绍如何通过接口获取腾讯视频的源地址来打到免广告或者下载的目的。因为周末一直在弄博客网站视频的问题,用的云播放器video++在引用腾讯视频时无法播放,后来发现必须引用视频的源地址,然后由此引出了一系列坑。。。

首先,我们在腾讯主页上随便打开一个视频,比如这个我家汪汪汪的奋斗目标,视频地址是

https://v.qq.com/x/page/t0539o5jeej.html

我们可以很明显得看到"t0539o5jeej",这其实是该视频的唯一ID,然后我们通过chrome的调试模式进行抓包,在network选项卡,如果没有数据就ctrl+f5刷新一下,对size列排序,找到文件最大的地址

这就是视频的源地址,双击进去看就找到了,简单吧。。。当然没这么简单

这个是视频的源地址没错,但是我们仔细观察他的url就会又发现

http://182.254.72.13/vhot2.qqvideo.tc.qq.com/
AfIQcj7DiCDuGIxP_MFODdSyoqXYbf1YOndQ2KfDOqMU/
t0539o5jeej.p701.1.mp4?
sha=&
sdtfrom=v1010&
guid=f90fba80b9d9021189dd23200a45c2cb&
vkey=823A322C096BD93D6CFEDD2B4B157D3A24DC07153BA23649B20F6986522550C923199EB05D140D635AEAB196D20721DB54E2B5F9EDBCCEBEB944C997D734B5797468B6ADE1438A4341FC485B53586855FB698F455644EEE5E29EA5F849661A52DEA09B713FCECD9B6D35BFF8B2B3009A8C7F98970998FBEA
&platform=2
&ocid=233643948
&ocid=1534587146

居然是http协议,仔细一想这个应该是纯的视频服务器集群或者CDN的地址,第三行有我们熟悉的视频ID,第七行是最重要的vkey,然后我们回到原来视频的页面,继续分析一下http报头里面有没有价值信息

看到头部Cache-Control字段过期时间是max-age=7200,也就是2个小时,还有E-tag来配置缓存策略,可以猜测腾讯视频源地址不是永久的,2小时过期就打不开原来的链接了,源地址中的vkey用来验证是否过期。那么就坑爹了,我们要是想在其他网站引用无广告的源地址,2小时就会失效要修改url,这可如何是好?别急,接下来慢慢分析。

首先我们对源地址做处理,试验去掉不同的参数看能否访问正常,发现只有vkey是必须的。那么这个vkey怎么来的呢?我在网上找了很久,终于找到几个相关的接口。

//获取vinfo接口
http://vv.video.qq.com/getvinfo
//获取vkey接口
http://vv.video.qq.com/getvkey
//获取info接口
http://vv.video.qq.com/getinfo
//获取vkey接口
http://vv.video.qq.com/getkey
//获取h5vinfo接口
http://h5vv.video.qq.com/getinfo
//获取h5vkey接口额
http://h5vv.video.qq.com/getkey

他们2个一组,功能都是类似的,只是有些参数要求不一样,我们使用第二组接口,因为我经过很多次尝试发现这组接口对参数要求没那么严格

首先我们需要获取视频的info

http://vv.video.qq.com/getinfo?otype=json&appver=3%2E2%2E19%2E333&platform=11&defnpayver=1&vid=$vid

其他参数我都指定好了,大家不需要修改,只需要修改最后一个vid,就是前面的视频ID,我们以"t0539o5jeej"这个ID为例,请求它返回的JSON串如下

{
    "dltype": 1, 
    "exem": 0, 
    "fl": {
        "cnt": 3, 
        "fi": [
            {
                "id": 10703, 
                "name": "sd", 
                "lmt": 0, 
                "sb": 1, 
                "cname": "标清;(270P)", 
                "br": 35, 
                "drm": 0, 
                "video": 1, 
                "fs": 18589422, 
                "sl": 0
            }, 
            {
                "id": 10712, 
                "name": "hd", 
                "lmt": 0, 
                "sb": 1, 
                "cname": "高清;(480P)", 
                "br": 60, 
                "drm": 0, 
                "video": 1, 
                "fs": 32735880, 
                "sl": 1
            }, 
            {
                "id": 10701, 
                "name": "shd", 
                "lmt": 0, 
                "sb": 1, 
                "cname": "超清;(720P)", 
                "br": 65, 
                "drm": 0, 
                "video": 1, 
                "fs": 68612302, 
                "sl": 0
            }
        ]
    }, 
    "fp2p": 0, 
    "hs": 0, 
    "ip": "222.248.11.246", 
    "ls": 0, 
    "preview": 525, 
    "s": "o", 
    "sfl": {
        "cnt": 0
    }, 
    "tm": 1503244112, 
    "vl": {
        "cnt": 1, 
        "vi": [
            {
                "br": 60, 
                "ch": 0, 
                "cl": {
                    "fc": 1, 
                    "ci": [
                        {
                            "idx": 1, 
                            "cs": 32735878, 
                            "cd": "525.188", 
                            "cmd5": "992efb35be1845d8a55f6af4916a7ade", 
                            "keyid": "t0539o5jeej.10712.1"
                        }
                    ]
                }, 
                "ct": 21600, 
                "drm": 0, 
                "dsb": 0, 
                "fclip": 1, 
                "fmd5": "36de73abdd85137f88eff0e3a68c8024", 
                "fn": "t0539o5jeej.p712.mp4", 
                "fs": 32735880, 
                "fst": 5, 
                "fvkey": "33FEFD43332418B57CA35A9CC0773BEDE848AAB530F0ED3C87015292B540F1462AA69AD636F6F5BF225EB02B7B06CC105B3FEAB353B075688939835F2C86139DB70514FFD1CF2A7366BBEE44411212706ADE0E72023969E68BAF85CBAA0A55E2", 
                "head": 0, 
                "hevc": 0, 
                "iflag": 0, 
                "level": 0, 
                "lnk": "t0539o5jeej", 
                "logo": 1, 
                "mst": 8, 
                "pl": null, 
                "share": 1, 
                "sp": 0, 
                "st": 2, 
                "tail": 0, 
                "td": "525.188", 
                "ti": "棒棒的边牧nana", 
                "type": 3, 
                "ul": {
                    "ui": [
                        {
                            "url": "http://116.77.75.11/vhot2.qqvideo.tc.qq.com/AkSZ9ClY3fvx3tRRqXHSRXG3K4KLs4odhMn0B_BxX3pI/", 
                            "vt": 200, 
                            "dtc": 0, 
                            "dt": 2
                        }, 
                        {
                            "url": "http://116.77.75.12/vhot2.qqvideo.tc.qq.com/AkSZ9ClY3fvx3tRRqXHSRXG3K4KLs4odhMn0B_BxX3pI/", 
                            "vt": 200, 
                            "dtc": 0, 
                            "dt": 2
                        }, 
                        {
                            "url": "http://116.77.75.15/vhot2.qqvideo.tc.qq.com/AkSZ9ClY3fvx3tRRqXHSRXG3K4KLs4odhMn0B_BxX3pI/", 
                            "vt": 200, 
                            "dtc": 0, 
                            "dt": 2
                        }, 
                        {
                            "url": "http://video.dispatch.tc.qq.com/6685031/", 
                            "vt": 0, 
                            "dtc": 0, 
                            "dt": 2
                        }
                    ]
                }, 
                "vh": 480, 
                "vid": "t0539o5jeej", 
                "videotype": 0, 
                "vr": 0, 
                "vst": 2, 
                "vw": 848, 
                "wh": 1.7666667, 
                "wl": {
                    "wi": [ ]
                }
            }
        ]
    }
}

我们看到这个视频有3种画质,我们需要的是url, 有3个,任选一个就行,url后面拼接视频地址的时候有用,再就是画质里面的ID,以这里的720p为例,id是"10712",我们需要把开头的"10"替换成"p",然后前面加上VID,也是就是"t0539o5jeej", 最后加上.mp4,这里有朋友会问为啥一定是mp4呢,还记得调用这个地址时候我指定了有些参数要大家不要修改吗,那些参数决定视频是mp4格式的。最后得到的视频文件地址是"t0539o5jeej.p712.mp4", 经过试验,诸如"t0539o5jeej.p712.0.mp4", "t0539o5jeej.p712.1.mp4"都是可以的,太大的数字不行,不过我们用默认的就可以了。得到文件名有什么用呢,哈哈,这个就是用来获取vkey的参数之一啦,接下来调用获取vkey地址

http://vv.video.qq.com/getkey?otype=json&platform=11&format=10712&vid=vid&filename=filename

我们需要更改三个参数

  • platform: 就是视频画质里的ID
  • 这个就无需再解释啦
  • filename: 视频文件名


调用接口,得到的json如下

{
    "br": 130643.32, 
    "ct": 21600, 
    "filename": "t0539o5jeej.p701.mp4", 
    "ip": "222.248.11.246", 
    "key": "EACE8B3A0A390C0C5CFD8B2AE9F3D5184373D3FB16C956EA2C51325CB27DA7614B8D060D1A7B12EB73E54A3EE068B37EE2594BA6429F5CF9198E3FB62736F3C0BFC64C93D367DE9E71826AD261232B33E98DFA58B95B3DCEB0718BC63E3021B2", 
    "keyid": "t0539o5jeej.10701.1", 
    "level": 0, 
    "levelvalid": 1, 
    "s": "o", 
    "sp": 0, 
    "sr": 0
}

好了,这个key才是我们需要的vkey,接下来组装视频源地址,很简单

url+filename+"?vkey=$vkey"

最后得到的地址是

http://182.254.8.67/vhot2.qqvideo.tc.qq.com/ApV5_uyVI2SiXm5s88lHo01aRqCNXddnDsQ3PkkDKgCE/t0539o5jeej.p701.1.mp4?vkey=F2B5F17E2DE89BAE1CBAB27F7B085D58E8B942AE711D2BFBFDF7EF6B8AAB2E87654EA00A0056ECB0A9D0E3D6F014A0F28753C97EC19E3CDF7EA4BF1442F74EB99FC78BB12F0004DA0EF5525A8EB00455CFB99E853B3562139688F2A5FE5C57E8BA4E89466191FAC209418091BB396043310C98FB64308D95

好了,以上就是获取原地址的全过程,博客的视频无广告引用终于解决了,因为二次开发是php,压根不懂,鼓捣了一下午php接口调用和字符串验证处理终于搞定,附上php获取的代码

<meta charset="utf-8">
<?php
//定义常量参数
define('DB_HOST','localhost');
define('DB_USER','wordpress');
define('DB_PWD','yourdatabasepassword');//密码
define('DB_NAME','wordpress');


$connect = mysql_connect(DB_HOST,DB_USER,DB_PWD) or die('数据库连接失败,错误信息:'.mysql_error());
//echo $connect;//Resource id #2 
mysql_select_db(DB_NAME,$connect) or die('数据库连接错误,错误信息:'.mysql_error());
    
//定义函数get_url(),用来获取tencent视频源地址
function get_url($url_get) {
 
    $testurl = "vv.video.qq.com/getinfo?otype=json&platform=11&defnpayver=1&vid=$url_get";  // test url
    $ch = curl_init();  // create curl resource       
    curl_setopt($ch, CURLOPT_URL, $testurl);  // set url $testurl   
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //return the transfer as a string
    curl_setopt($ch, CURLOPT_HEADER, 0);
    $output = curl_exec($ch); // $output contains the output string       
    curl_close($ch); // close curl resource to free up system resourcesa
    $output = substr($output,13);
    $output = substr($output,0,strlen($output)-1);
    $json =json_decode($output,TRUE);
    if(!$json)
    {
        $ret = json_last_error();
        print_r($ret);   //打印为: 4,查错误信息表,可知是语法错误

    }
   $new_vid = $json['vl']['vi'][0]['lnk']; //从处理过的json数组里面获取vid,这一步不必须,因为VID应该是不会变的
   $domain= $json['vl']['vi'][0]['ul']['ui'][0]['url']; //获取url的非参数部分
   $format = end($json['fl']['fi'])['id']; //清晰度格式ID
   $filename = $new_vid.'.p'.((int)substr($format,-4)).".mp4"; //拼接文件名,'10'换成'p'
   $temp = str_replace('.', '%2E', $filename); //将'.'换成url编码'%2E'
   $key_api = "http://vv.video.qq.com/getkey?otype=json&platform=11&format=$format&vid=$new_vid&filename=".str_replace('.', '%2E', $filename);
   $ch1 = curl_init();  // create curl resource       
   curl_setopt($ch1, CURLOPT_URL, $key_api);  // set url $testurl   
   curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1); //return the transfer as a string
   curl_setopt($ch1, CURLOPT_HEADER, 0);
   $output1 = curl_exec($ch1);
   curl_close($ch1);
   $output1 = substr($output1,13);
   $output1 = substr($output1,0,strlen($output1)-1);
   $json2 = json_decode($output1,TRUE);
   $keyid = $json2['keyid'];
   $keyidtemp = strstr($keyid, ".");
   $filename = $new_vid.".p".substr($keyidtemp, 3, strlen($keyidtemp)).".mp4";
   $vkey = $json2['key'];
   $download_url = $domain.$filename."?vkey=$vkey"; //拼接最终的源地址
   return $download_url; //返回源地址
}
    
// 定义函数存入数据库,如果有记录就UPDATE,没有就INSERT
function store_url($vid_store, $url_store) {
    //print_r($url_store);   
    $query_temp = "INSERT INTO wp_videos(
          vid,
          video_url,
          exp_time)
    VALUES (
    '$vid_store',
    '$url_store',
    NOW()
    ) ON DUPLICATE KEY UPDATE video_url = '$url_store', exp_time = NOW(), modified_times = modified_times + 1;";
   
    @mysql_query($query_temp) or die('functionsinsert错误:'.mysql_error());
}

//@mysql_query($query) or die('新增错误:'.mysql_error());
$query = "SELECT meta_value FROM wp_postmeta WHERE meta_key = 'video_url'";
$result = mysql_query($query) or die('sql语句错误:'.mysql_error()); //获取后台设置的vid
// 此处将获取的sql结果集复制给数组用来遍历
while($row = mysql_fetch_array($result)){
$resultarr[] = $row;
}
$length = count($resultarr);
// 循环遍历vid获取地址并存储
for($temp = 0; $temp < $length; $temp++){
    $vid_temp = $resultarr[$temp][0];
    $url_result = get_url($vid_temp);
    store_url($vid_temp, $url_result);
}

?> 

全部介绍完毕,如有问题请联系站主,下周末会给大家带来GCP的负载均衡和全球CDN配置。

(2)

本文由 永烁星光 作者:linus 发表,转载请注明来源!

关键词:,

热评文章

发表评论