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静态类
Nov 25 PHP
用PHP伪造referer突破网盘禁止外连的代码
Jun 15 PHP
一步一步学习PHP(8) php 数组
Mar 05 PHP
php的一些小问题
Jul 03 PHP
php class中public,private,protected的区别以及实例分析
Jun 18 PHP
PHP随机生成随机个数的字母组合示例
Jan 14 PHP
使用php方法curl抓取AJAX异步内容思路分析及代码分享
Aug 25 PHP
php中array_multisort对多维数组排序的方法
Jun 21 PHP
PHP实现生成唯一会员卡号
Aug 24 PHP
PHP递归获取目录内所有文件的实现方法
Nov 01 PHP
php实现根据身份证获取精准年龄
Feb 26 PHP
php变量与字符串的增删改查操作示例
May 07 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
关于laravel-admin ueditor 集成并解决刷新的问题
2019/10/21 PHP
JSON 入门指南 想了解json的朋友可以看下
2009/08/26 Javascript
JQuery上传插件Uploadify使用详解及错误处理
2010/04/27 Javascript
引用 js在IE与FF之间的区别详细解析
2013/11/20 Javascript
JS控件ASP.NET的treeview控件全选或者取消(示例代码)
2013/12/16 Javascript
document.write的几点使用心得
2014/05/14 Javascript
thinkphp实现无限分类(使用递归)
2015/12/19 Javascript
JavaScript+CSS无限极分类效果完整实现方法
2015/12/22 Javascript
jquery跟随屏幕滚动效果的实现代码
2016/04/13 Javascript
使用JQ完成表格隔行换色的简单实例
2017/08/25 Javascript
AngularJS中下拉框的高级用法示例
2017/10/11 Javascript
vue中使用iview自定义验证关键词输入框问题及解决方法
2018/03/26 Javascript
详解离线安装npm包的几种方法
2018/11/25 Javascript
Vue 2.0 侦听器 watch属性代码详解
2019/06/19 Javascript
js tab栏切换代码实例解析
2019/09/03 Javascript
JS面向对象实现飞机大战
2020/08/26 Javascript
vue项目打包后请求地址错误/打包后跨域操作
2020/11/04 Javascript
vue从后台渲染文章列表以及根据id跳转文章详情详解
2020/12/14 Vue.js
[01:57]DOTA2上海特锦赛小组赛解说单车采访花絮
2016/02/27 DOTA
python中zip和unzip数据的方法
2015/05/27 Python
使用Python更换外网IP的方法
2018/07/09 Python
使用sklearn之LabelEncoder将Label标准化的方法
2018/07/11 Python
python修改txt文件中的某一项方法
2018/12/29 Python
python多环境切换及pyenv使用过程详解
2019/09/27 Python
如何通过Django使用本地css/js文件
2020/01/20 Python
Python爬取YY评级分数并保存数据实现过程解析
2020/06/01 Python
深入浅析python 中的self和cls的区别
2020/06/20 Python
浅析Python的命名空间与作用域
2020/11/25 Python
美国家具网站:Cymax
2016/09/17 全球购物
100%植物性、有机、即食餐:Sakara Life
2018/10/25 全球购物
线程的基本概念、线程的基本状态以及状态之间的关系
2012/10/26 面试题
自荐信怎么写好
2013/11/11 职场文书
规范化管理年活动总结
2014/08/29 职场文书
旷课检讨书
2015/01/26 职场文书
Python如何快速找到多个字典中的公共键(key)
2022/04/29 Python
一文搞懂PHP中的抽象类和接口
2022/05/25 PHP