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中HTTP方式下的Gzip压缩传输方法举偶
Feb 15 PHP
三个类概括PHP的五种设计模式
Sep 05 PHP
php比较多维数组中值的大小排序实现代码
Sep 08 PHP
深入php数据采集的详解
Jun 02 PHP
深入file_get_contents与curl函数的详解
Jun 25 PHP
PHP中exec函数和shell_exec函数的区别
Aug 20 PHP
php实现简单的MVC框架实例
Sep 23 PHP
PHP编程获取音频文件时长的方法【基于getid3类】
Apr 20 PHP
PHP实现的只保留字符串首尾字符功能示例【隐藏部分字符串】
Mar 11 PHP
PHP中Session ID的实现原理实例分析
Aug 17 PHP
Yii框架数据库查询、增加、删除操作示例
Oct 14 PHP
Git命令之分支详解
Mar 02 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
Chrome Web App开发小结
2014/09/04 PHP
js常见表单应用技巧
2008/01/09 Javascript
JavaScript 弹出窗体点击按钮返回选择数据的实现
2010/04/01 Javascript
jquery.AutoComplete.js中文修正版(支持firefox)
2010/04/09 Javascript
jquery DOM操作 基于命令改变页面
2010/05/06 Javascript
jquery异步请求实例代码
2011/06/21 Javascript
extjs3 combobox取value和text案例详解
2013/02/06 Javascript
js动态生成指定行数的表格
2013/07/11 Javascript
JS简单生成两个数字之间随机数的方法
2016/08/03 Javascript
javascript 中的console.log和弹出窗口alert
2016/08/30 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
2016/10/10 Javascript
移动端点击态处理的三种实现方式
2017/01/12 Javascript
webpack多入口多出口的实现方法
2018/08/17 Javascript
JavaScript利用键盘码控制div移动
2020/03/19 Javascript
JavaScript ES 模块的使用
2020/11/12 Javascript
Vue如何实现变量表达式选择器
2021/02/18 Vue.js
vue 使用 v-model 双向绑定父子组件的值遇见的问题及解决方案
2021/03/01 Vue.js
Python 字符串操作方法大全
2014/03/11 Python
一个基于flask的web应用诞生(1)
2017/04/11 Python
Python 中 Virtualenv 和 pip 的简单用法详解
2017/08/18 Python
python实现顺序表的简单代码
2018/09/28 Python
Python循环中else,break和continue的用法实例详解
2019/07/11 Python
python实现单链表的方法示例
2019/09/03 Python
Python倒排索引之查找包含某主题或单词的文件
2019/11/13 Python
基于Python检测动态物体颜色过程解析
2019/12/04 Python
tensorflow2.0的函数签名与图结构(推荐)
2020/04/28 Python
OpenCV 之按位运算举例解析
2020/06/19 Python
Python Opencv实现单目标检测的示例代码
2020/09/08 Python
应用数学专业求职信
2014/03/14 职场文书
竞聘演讲稿精彩开头和结尾
2014/05/14 职场文书
乡镇2014法制宣传日活动总结
2014/11/01 职场文书
2015出纳试用期工作总结
2014/12/12 职场文书
校长师德表现自我评价
2015/03/04 职场文书
个人借条范本
2015/05/25 职场文书
唐山大地震观后感
2015/06/05 职场文书
安全生产协议书
2016/03/22 职场文书