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 相关文章推荐
PHP5.0正式发布 不完全兼容PHP4 新增多项功能
Oct 09 PHP
解决php中Cannot send session cache limiter 的问题的方法
Apr 27 PHP
php 传值赋值与引用赋值的区别
Dec 29 PHP
php中常用的预定义变量小结
May 09 PHP
Laravel 5.0 发布 新版本特性详解
Feb 10 PHP
PHP中的traits实现代码复用使用实例
May 13 PHP
浅谈php错误提示及查错方法
Jul 14 PHP
[原创]ThinkPHP中SHOW_RUN_TIME不能正常显示运行时间的解决方法
Oct 10 PHP
php如何控制用户对图片的访问 PHP禁止图片盗链
Mar 25 PHP
thinkphp5 migrate数据库迁移工具
Feb 20 PHP
PHP上传图片到数据库并显示的实例代码
Dec 20 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
Feb 15 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
windows下升级PHP到5.3.3的过程及注意事项
2010/10/12 PHP
PHP中使用foreach和引用导致程序BUG的问题介绍
2012/09/05 PHP
php基于curl实现的股票信息查询类实例
2016/11/11 PHP
Ajax一统天下之Dojo整合篇
2007/03/24 Javascript
jquery select多选框的左右移动 具体实现代码
2013/07/03 Javascript
前端开发过程中浏览器版本的两种判定方法
2013/10/30 Javascript
javascript中的3种继承实现方法
2016/01/27 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
2016/05/20 Javascript
jquery过滤特殊字符',防sql注入的实现方法
2016/08/17 Javascript
jquery select2的使用心得(推荐)
2016/12/04 Javascript
js监听input输入框值的实时变化实例
2017/01/26 Javascript
利用nodejs监控文件变化并使用sftp上传到服务器
2017/02/18 NodeJs
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
2017/04/13 Javascript
微信小程序 同步请求授权的详解
2017/08/04 Javascript
详解axios 全攻略之基本介绍与使用(GET 与 POST)
2017/09/15 Javascript
解决vue同一slot在组件中渲染多次的问题
2018/09/06 Javascript
JS事件绑定的常用方式实例总结
2019/03/02 Javascript
[07:38]2014DOTA2国际邀请赛 Newbee顺利挺进胜者组赛后专访
2014/07/15 DOTA
Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例
2014/06/10 Python
Django 实现购物车功能的示例代码
2018/10/08 Python
关于tf.TFRecordReader()函数的用法解析
2020/02/17 Python
jupyternotebook 撤销删除的操作方式
2020/04/17 Python
python 实现rolling和apply函数的向下取值操作
2020/06/08 Python
Tensorflow tensor 数学运算和逻辑运算方式
2020/06/30 Python
python 多进程和协程配合使用写入数据
2020/10/30 Python
手把手教你配置JupyterLab 环境的实现
2021/02/02 Python
CSS3 特效范例整理
2011/08/22 HTML / CSS
CSS3弹性盒模型flex box快速入门心得(必看篇)
2016/05/24 HTML / CSS
大学生自我鉴定评语
2014/01/27 职场文书
前台文员职责范本
2014/03/07 职场文书
开业主持词
2014/03/21 职场文书
社团活动总结书
2014/06/27 职场文书
大学生读书笔记大全
2015/07/01 职场文书
公司年会主持词范文!
2019/05/07 职场文书
实习报告范文
2019/07/30 职场文书
创业计划书之小型广告公司
2019/10/22 职场文书