Youku 视频绝对地址获取的方法详解


Posted in PHP onJune 26, 2013

前一阵子为了研究 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
PHP 相关文章推荐
汉字转化为拼音(php版)
Oct 09 PHP
PHP中的生成XML文件的4种方法分享
Oct 06 PHP
PHP关于IE下的iframe跨域导致session丢失问题解决方法
Oct 10 PHP
PHP获取中英混合字符串长度的方法
Jun 07 PHP
将酷狗krc歌词解析并转换为lrc歌词php源码
Jun 20 PHP
PHP使用数组依次替换字符串中匹配项
Jan 08 PHP
php打乱数组二维数组多维数组的简单实例
Jun 17 PHP
Smarty模板常见的简单应用分析
Nov 15 PHP
PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析
Feb 04 PHP
php中文乱码问题的终极解决方案汇总
Aug 01 PHP
PHP Cli 模式设置进程名称的方法
Jun 12 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
Feb 27 PHP
解析php 版获取重定向后的地址(代码)
Jun 26 #PHP
php连接函数implode与分割explode的深入解析
Jun 26 #PHP
解析PHP正则提取或替换img标记属性
Jun 26 #PHP
php 在windows下配置虚拟目录的方法介绍
Jun 26 #PHP
关于PHP自动判断字符集并转码的详解
Jun 26 #PHP
安装apache2.2.22配置php5.4(具体操作步骤)
Jun 26 #PHP
php 批量生成html,txt文件的实现代码
Jun 26 #PHP
You might like
解析PHP中的正则表达式以及模式匹配
2013/06/19 PHP
PHP函数microtime()用法与说明
2013/12/04 PHP
一组PHP可逆加密解密算法实例代码
2014/01/21 PHP
php将12小时制转换成24小时制的方法
2015/03/31 PHP
PHP MYSQL实现登陆和模糊查询两大功能
2016/02/05 PHP
PHP实现的多文件上传类及用法示例
2016/05/06 PHP
CI框架中类的自动加载问题分析
2016/11/21 PHP
php实现简单的守护进程创建、开启与关闭操作
2019/08/13 PHP
PHP优化之批量操作MySQL实例分析
2020/04/23 PHP
js获取url参数的使用扩展实例
2007/12/29 Javascript
获取当前网页document.url location.href区别总结
2008/05/10 Javascript
11款基于Javascript的文件管理器
2009/10/25 Javascript
jQuery中DOM树操作之复制元素的方法
2015/01/23 Javascript
JavaScript定时器和优化的取消定时器方法
2015/07/03 Javascript
jQuery中 delegate使用的问题
2015/07/03 Javascript
javascript实现方法调用与方法触发小结
2016/03/26 Javascript
Bootstrap实现的标签页内容切换显示效果示例
2017/05/25 Javascript
AngularJS获取json数据的方法详解
2017/05/27 Javascript
jquery获取链接地址和跳转详解(推荐)
2017/08/15 jQuery
Vue单页面应用保证F5强刷不清空数据的解决方案
2018/01/31 Javascript
node.js中fs文件系统目录操作与文件信息操作
2018/02/24 Javascript
JavaScript事件冒泡与事件捕获实例分析
2018/08/01 Javascript
electron 安装,调试,打包的具体使用
2019/11/06 Javascript
jQuery表单校验插件validator使用方法详解
2020/02/18 jQuery
[57:31]DOTA2-DPC中国联赛 正赛 SAG vs CDEC BO3 第一场 2月1日
2021/03/11 DOTA
win10环境下python3.5安装步骤图文教程
2017/02/03 Python
Python实现对一个函数应用多个装饰器的方法示例
2018/02/09 Python
解决tensorflow读取本地MNITS_data失败的原因
2020/06/22 Python
利用css3实现的简单的鼠标悬停按钮
2014/11/04 HTML / CSS
html5 canvas移动浏览器上实现图片压缩上传
2016/03/11 HTML / CSS
Html5移动端适配IphoneX等机型的方法
2019/06/25 HTML / CSS
汽车检测与维修应届毕业生求职信
2013/10/19 职场文书
门卫岗位职责
2015/02/09 职场文书
酒店客房服务员岗位职责
2015/04/09 职场文书
幽默导游词开场白
2015/05/29 职场文书
董事长开业致辞
2015/07/29 职场文书