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 相关文章推荐
不用GD库生成当前时间的PNG格式图象的程序
Oct 09 PHP
php&amp;java(二)
Oct 09 PHP
用PHP和ACCESS写聊天室(五)
Oct 09 PHP
用PHP的ob_start() 控制您的浏览器cache
Aug 03 PHP
php面向对象全攻略 (三)特殊的引用“$this”的使用
Sep 30 PHP
PHP小程序自动提交到自助友情连接
Nov 24 PHP
php实现的遍历文件夹下所有文件,编辑删除
Jan 05 PHP
PHP 代码规范小结
Mar 08 PHP
html静态页面调用php文件的方法
Nov 13 PHP
PHP发送短信代码分享
Aug 11 PHP
Laravel5.5以下版本中如何自定义日志行为详解
Aug 01 PHP
Laravel5.7框架安装与使用学习笔记图文详解
Apr 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
session 的生命周期是多长
2006/10/09 PHP
php利用cookie实现访问次数统计代码
2011/05/19 PHP
解析在PHP中使用mysqli扩展库对mysql的操作
2013/07/03 PHP
PHP生成验证码时“图像因其本身有错无法显示”的解决方法
2013/08/07 PHP
php从数组中随机选择若干不重复元素的方法
2015/03/14 PHP
用PHP代码给图片加水印
2015/07/01 PHP
PHP简单读取PDF页数的实现方法
2016/07/21 PHP
Laravel+Intervention实现上传图片功能示例
2019/07/09 PHP
潜说js对象和数组
2011/05/25 Javascript
js获取触发事件元素在整个网页中的绝对坐标(示例代码)
2013/12/13 Javascript
JavaScript框架(iframe)操作总结
2014/04/16 Javascript
使用JavaScript开发IE浏览器本地插件实例
2015/02/18 Javascript
ionic在开发ios系统微信时键盘挡住输入框的解决方法(键盘弹出问题)
2016/09/06 Javascript
微信小程序 icon组件详细及实例代码
2016/10/25 Javascript
浅谈javascript中的事件冒泡和事件捕获
2016/12/28 Javascript
工厂模式在JS中的实践
2017/01/18 Javascript
Vue axios 中提交表单数据(含上传文件)
2017/07/06 Javascript
Vue 中使用富文本编译器wangEditor3的方法
2019/09/26 Javascript
electron+vue实现div contenteditable截图功能
2020/01/07 Javascript
微信小程序点击view动态添加样式过程解析
2020/01/21 Javascript
[58:54]EG vs RNG 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
pygame播放音乐的方法
2015/05/19 Python
Python使用Srapy框架爬虫模拟登陆并抓取知乎内容
2016/07/02 Python
Python实现类似比特币的加密货币区块链的创建与交易实例
2018/03/20 Python
Python实现爬虫从网络上下载文档的实例代码
2018/06/13 Python
对python调用RPC接口的实例详解
2019/01/03 Python
pyqt弹出新对话框,以及关闭对话框获取数据的实例
2019/06/18 Python
keras训练曲线,混淆矩阵,CNN层输出可视化实例
2020/06/15 Python
户外活动总结范文
2014/04/30 职场文书
新学期标语
2014/06/30 职场文书
2014年银行员工工作总结
2014/11/12 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
对公司的意见和建议
2015/06/04 职场文书
归途列车观后感
2015/06/17 职场文书
运动会100米加油稿
2015/07/21 职场文书
JavaScript利用html5新方法操作元素类名详解
2021/11/27 Javascript