Youku 视频绝对地址获取的方法详解
程序员文章站
2022-06-07 20:41:37
前一阵子为了研究 knlivecommentary 而进行了一系列的关于视频站点的研究。由于knlivecommentary需要能够获取充足的视频源进行测试,所以我们选取了...
前一阵子为了研究 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
其实开始研究解析绝对地址也是为了研究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
上一篇: 使用PHP获取汉字的拼音(全部与首字母)
下一篇: 简单的分级别写日志程序