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 相关文章推荐
杏林同学录(三)
Oct 09 PHP
一个SQL管理员的web接口
Oct 09 PHP
很实用的一个完整email发送程序
Oct 09 PHP
在PHP3中实现SESSION的功能(二)
Oct 09 PHP
10条PHP编程习惯助你找工作
Sep 29 PHP
php for 循环语句使用方法详细说明
May 09 PHP
php网页标题中文乱码的有效解决方法
Mar 05 PHP
php实例分享之二维数组排序
May 15 PHP
文件上传之SWFUpload插件(代码)
Jul 30 PHP
PHP常用的小程序代码段
Nov 14 PHP
PHP打印输出函数汇总
Aug 28 PHP
php版微信数据统计接口用法示例
Oct 12 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时间戳格式化显示友好的时间函数分享
2014/10/21 PHP
ThinkPHP5框架缓存查询操作分析
2018/05/30 PHP
thinkPHP+mysql+ajax实现的仿百度一下即时搜索效果详解
2019/07/15 PHP
javascript 无提示关闭窗口脚本
2009/08/17 Javascript
javascript小数计算出现近似值的解决办法
2010/02/06 Javascript
JavaScript isArray()函数判断对象类型的种种方法
2010/10/11 Javascript
javascript学习笔记(十七) 检测浏览器插件代码
2012/06/20 Javascript
Node.js编程中客户端Session的使用详解
2015/06/23 Javascript
js实现温度计时间样式代码分享
2015/08/21 Javascript
JS实现鼠标滑过链接改变网页背景颜色的方法
2015/10/20 Javascript
Bootstrap轮播插件简单使用方法介绍
2016/06/21 Javascript
js canvas实现适用于移动端的百分比仪表盘dashboard
2017/07/18 Javascript
React.Js添加与删除onScroll事件的方法详解
2017/11/03 Javascript
浅谈Vue CLI 3结合Lerna进行UI框架设计
2019/04/14 Javascript
Vue项目中使用mock.js的完整步骤
2021/01/12 Vue.js
[02:38]2018年度DOTA2最佳劣单位选手-完美盛典
2018/12/17 DOTA
[49:21]完美世界DOTA2联赛循环赛 Ink Ice vs LBZS BO2第二场 11.05
2020/11/06 DOTA
Python正则表达式使用经典实例
2016/06/21 Python
Django模板变量如何传递给外部js调用的方法小结
2017/07/24 Python
python查询mysql,返回json的实例
2018/03/26 Python
详解Python if-elif-else知识点
2018/06/11 Python
详解python中的json和字典dict
2018/06/22 Python
Python调用C++,通过Pybind11制作Python接口
2018/10/16 Python
Python3环境安装Scrapy爬虫框架过程及常见错误
2019/07/12 Python
品管员岗位职责
2013/11/10 职场文书
记者岗位职责
2014/01/06 职场文书
《小儿垂钓》教学反思
2014/02/23 职场文书
《她是我的朋友》教学反思
2014/04/26 职场文书
幸福家庭标语
2014/06/27 职场文书
小学生感恩老师演讲稿
2014/08/28 职场文书
计算机实训报告范文
2014/11/05 职场文书
试用期工作表现自我评价
2015/03/06 职场文书
2015年社区工作总结
2015/04/08 职场文书
如何利用STAR法则制作留学文书?
2019/08/26 职场文书
微信小程序 WeUI扩展组件库的入门教程
2022/04/21 Javascript
Spring Data JPA框架Repository自定义实现
2022/04/28 Java/Android