程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> Youku 視頻絕對地址獲取的方法詳解

Youku 視頻絕對地址獲取的方法詳解

編輯:關於PHP編程

    前一陣子為了研究 KnLiveCommentary 而進行了一系列的關於視頻站點的研究。由於KnLiveCommentary需要能夠獲取充足的視頻源進行測試,所以我們選取了 Youku(優酷)一個比較大的視頻網站來進行測試。
    其實開始研究解析絕對地址也是為了研究Youku 的自帶播放器,順便去除廣告什麼的。後來我們就把Youku 的播放器用 ASV6 (ActionScript Viewer 6)“反編譯”了一下,達到了驚人的效果。

    Youku的視頻采取了加密+動態的獲取方式,視頻地址需要訪問網站動態獲取,而結果則還需經過解密等操作。

    復制代碼 代碼如下:
    $base_url = 'http://v.youku.com/player/getPlayList/VideoIDS/'; //獲取視頻信息的地址 基地址
    $_VIDEO_ID = $_GET['vid']; //從GET裡面把Video Id提取
    if($_VIDEO_ID=='')
    $_VIDEO_ID = 'XMjY0ODE1MDA0'; //我比較懶,測試的時 候就固定了一個
    $ch = curl_init(); //開啟cURL對象
    curl_setopt($ch, CURLOPT_URL, $base_url . $_VIDEO_ID); //獲取這個視頻的信息的地址
    curl_setopt($ch, CURLOPT_HEADER, 1); //要 HEADER
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_REFERER, 'http://v.youku.com/v_show/id_' . $_VIDEO_ID); //給一個假的"REFERER"
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); //把現在的浏覽器User Agent傳遞給服務器
    curl_setopt($ch, CURLOPT_NOBODY, 0);
    $content = curl_exec($ch); //執行!!!
    curl_close($ch); /*下面解析*/
    preg_match(‘~”seed”s*:s*(d+)s*,~iUs',$content,$seed);
    preg_match(‘~{s*”(flv|mp4)”s*:s*”(.*)”s*}~iUs',$content,$encoded);
    preg_match(‘~”key1″s*:s*”(.*)”s*,~iUs',$content,$key1);
    preg_match(‘~”key2″s*:s*”(.*)”s*,~iUs',$content,$key2);
    //從返回的JSON串中提取必要信息 seed, encoded_url, key1, key2
    class decoder{
    var $randomSeed = 0;
    var $cg_str=”";
    function __construct($seed){
    $this->randomSeed = $seed;
    }
    function ran(){
    $this->randomSeed = (($this->randomSeed * 211)+30031)%65536;
    return ($this->randomSeed / 65536);// 根據舊的 Seed 計算新的Seed,並且返回一個Seed的比例位置 [0,1)
    }
    function cg_hun(){ //估計這個叫 “CG混”,反正ASV解的函數就是這個名字
    $this->cg_str="";
    $sttext = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/:._-1234567890'; //默認字符串(最大)
    $len = strlen($sttext); //獲取其長度
    for($i=0;$i<$len;$i++){
    $cuch = (int)($this->ran()*strlen($sttext)); //獲取字符串 Seed比例 位置的字符下標
    $this->cg_str.=$sttext[$cuch]; //把字母讀出來
    $sttext = str_replace($sttext[$cuch],”,$sttext); //刪掉這個讀出來的字母(到 0 就停)
    }
    }
    function decode($string){
    $output=”";
    $this->cg_hun();
    $expl = explode(‘*',$string); //把 1*23*34*45*56* 這個字符串打散
    for($i=0;$i<count($expl)-1;$i++){
    $output.=$this->cg_str[(int)$expl[$i]]; //獲取數字位代表的 cg_hun 打亂字符串字符,自此解密完成
    }
    return $output; //OK拉
    }
    function decode_key($key1,$key2){
    $key = hexdec($key1); //兩個Key都是HEX
    $key = $key ^ -1520786011; //這個原來也是個8 位HEX,後來被我用計算器算了數值,因為這樣方便PhP位運算
    return $key2 . dechex($key); //合成最終 Key
    }
    }//解密類,用這個很方便$new = new decoder((int)$seed[1]);
    $fileid = $new->decode($encoded[2]);
    $key = $new->decode_key($key1[1],$key2[1]);
    //把數據喂進去,計算//地址載構成
    $s7 = substr($fileid,10,strlen($fileid));
    $s5 = substr($fileid,0,8);
    $s6 = substr($fileid,6,2);
    // 拆開$s4 = '00′;//注意這是一個 HEX 值,即00表示視頻第一個分段,01第二個 0f第十五個…依此類推$sid = time() . mt_rand(10,99) . '1000′ . mt_rand(30,80) . '00′;//獲取一個隨機的SID,給服務器(其實不會被檢查)
    $d_ADDR = ‘http://f.youku.com/player/getFlvPath/sid/‘ . $sid . ‘_'. $s4 . ‘/st/' . $encoded[1] . ‘/fileid/' . $file_id;
    echo $d_ADDR . ‘?K=' . $key;
    //最後把地址輸出


    請注意,由於Youku 更換算法/格式上面的方法已經不能處理所有情況,我來描述下現在的流程:
    1.訪問http://v.youku.com/player/getPlayList/VideoIDS/[ID]
    2.獲得文件,同時解析”streamfileids”:{“flv”:”加密地址”,”mp4″:”加密地址”,”等等等”:”加密地址”
    3.按照上面的方法破解加密地址
    4.獲取分段數目和K
    {“mp4″:[{“no”:”0“,”size”:”18367795″,”seconds”:”421″,”k”:”281ff2875db680bb261c02ce“},{“no”:”1“,”size”:”19045091″,”seconds”:”421″,”k”:”45398cdd4aa44968261c02ce“},
    ……
    5.合成地址,不過每個分段的K都采用上面獲得的新K

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved