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对字符串的递增运算分析
Aug 08 PHP
php 数组的指针操作实现代码
Feb 08 PHP
php 文本文件的读取效率
Feb 10 PHP
浅析php变量作用域的一些问题
Aug 08 PHP
PHP中include与require使用方法区别详解
Oct 19 PHP
php二维数组合并及去重复的方法
Mar 04 PHP
Ubuntu12下编译安装PHP5.3开发环境
Mar 27 PHP
php常用图片处理类
Mar 16 PHP
Yii遍历行下每列数据的方法
Oct 17 PHP
PHP实现的文件上传类与用法详解
Jul 05 PHP
laravel配置Redis多个库的实现方法
Apr 10 PHP
laravel 判断查询数据库返回值的例子
Oct 11 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调用Google translate_tts api实现代码
2013/08/07 PHP
phpmailer发送邮件之后,返回收件人是否阅读了邮件的方法
2014/07/19 PHP
PHP赋值的内部是如何跑的详解
2019/01/13 PHP
HTML5如何适配 iPhone IOS 底部黑条
2021/03/09 HTML / CSS
Google Map V3 绑定气泡窗口(infowindow)Dom事件实现代码
2013/04/26 Javascript
JavaScript中创建类/对象的几种方法总结
2013/11/29 Javascript
Jquery $.getJSON 在IE下的缓存问题解决方法
2014/10/10 Javascript
jquery插件tytabs.jquery.min.js实现渐变TAB选项卡效果
2015/08/25 Javascript
基于jquery实现日历签到功能
2020/09/11 Javascript
5个最顶级jQuery图表类库插件【jquery插件库】
2016/05/05 Javascript
JS+Canvas绘制动态时钟效果
2017/11/10 Javascript
浅谈webpack4 图片处理汇总
2018/09/12 Javascript
使用mpvue搭建一个初始小程序及项目配置方法
2018/12/03 Javascript
vue实现点击按钮下载文件功能
2019/10/11 Javascript
细述Javascript的加法运算符的具体使用
2019/10/18 Javascript
[48:23]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#1COL VS EG第一局
2016/03/05 DOTA
Python简单计算文件夹大小的方法
2015/07/14 Python
利用pyinstaller打包exe文件的基本教程
2019/05/02 Python
python如何实现数据的线性拟合
2019/07/19 Python
解决TensorFlow GPU版出现OOM错误的问题
2020/02/03 Python
基于梯度爆炸的解决方法:clip gradient
2020/02/04 Python
详解python百行有效代码实现汉诺塔小游戏(简约版)
2020/10/30 Python
通过Python pyecharts输出保存图片代码实例
2020/11/25 Python
用css3实现转换过渡和动画效果
2020/03/13 HTML / CSS
真正的英国宝藏:Mappin & Webb
2019/05/05 全球购物
水务局局长岗位职责
2013/11/28 职场文书
出国留学介绍信
2014/01/13 职场文书
政治表现评语
2014/05/04 职场文书
教师师德师风个人整改方案
2014/09/18 职场文书
2014年环境卫生工作总结
2014/11/24 职场文书
2014员工聘用协议书(最新版)
2014/11/24 职场文书
2015世界地球日活动总结
2015/02/09 职场文书
酒店宣传语大全
2015/07/13 职场文书
《搭石》教学反思
2016/02/18 职场文书
七年级作文之秋游
2019/10/21 职场文书
MySQL分库分表与分区的入门指南
2021/04/22 MySQL