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 相关文章推荐
PHP4与PHP3中一个不兼容问题的解决方法
Oct 09 PHP
PHP header函数分析详解
Aug 06 PHP
php引用地址改变变量值的问题
Mar 23 PHP
解析php根据ip查询所在地区(非常有用,赶集网就用到)
Jul 01 PHP
PHP 字符串长度判断效率更高的方法
Mar 02 PHP
PHP实现下载断点续传的方法
Nov 12 PHP
php以fastCGI的方式运行时文件系统权限问题及解决方法
May 11 PHP
分享PHP函数实现数字与文字分页代码
Jul 28 PHP
Laravel实现定时任务的示例代码
Aug 10 PHP
PHP通过curl获取接口URL的数据方法
May 31 PHP
Laravel Validator自定义错误返回提示消息并在前端展示
May 09 PHP
PHP实现关键字搜索后描红功能示例
Jul 03 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
文章推荐系统(三)
2006/10/09 PHP
用PHP进行MySQL删除记录操作代码
2008/06/07 PHP
PHP使用DES进行加密与解密的方法详解
2013/06/06 PHP
详解PHP处理字符串类似indexof的方法函数
2017/06/11 PHP
阿里对象存储OSS在laravel框架中的使用方法
2019/10/13 PHP
yii框架结合charjs统计上一年与当前年数据的方法示例
2020/04/04 PHP
Javascript 定时器调用传递参数的方法
2009/11/12 Javascript
给jQuery方法添加回调函数一款插件的应用
2013/01/21 Javascript
原生js做的手风琴效果的导航菜单
2013/11/08 Javascript
浅谈checkbox的一些操作(实战经验)
2013/11/20 Javascript
jquery如何通过name名称获取当前name的value值
2013/12/20 Javascript
javascript事件模型介绍
2016/05/31 Javascript
Jquery组件easyUi实现手风琴(折叠面板)示例
2016/08/23 Javascript
Bootstrap 轮播(Carousel)插件
2016/12/26 Javascript
学习JS中的DOM节点以及操作
2018/04/30 Javascript
对vue事件的延迟执行实例讲解
2018/08/28 Javascript
vue计算属性computed的使用方法示例
2019/03/13 Javascript
JS正则表达式封装与使用操作示例
2019/05/15 Javascript
在Vue中实现随hash改变响应菜单高亮
2020/03/09 Javascript
springboot+vue实现文件上传下载
2020/11/17 Vue.js
Vue如何实现变量表达式选择器
2021/02/18 Vue.js
python爬取网站数据保存使用的方法
2013/11/20 Python
python游戏开发之视频转彩色字符动画
2019/04/26 Python
从列表或字典创建Pandas的DataFrame对象的方法
2019/07/06 Python
pytorch标签转onehot形式实例
2020/01/02 Python
django-csrf使用和禁用方式
2020/03/13 Python
千禧酒店及度假村官方网站:Millennium Hotels and Resorts
2019/05/10 全球购物
Sony C++笔试题
2013/03/10 面试题
动物科学专业毕业生的自我评价
2013/11/29 职场文书
出国考察邀请函
2014/01/21 职场文书
优秀学生干部推荐材料
2014/02/03 职场文书
趣味体育活动方案
2014/02/08 职场文书
政风行风自查自纠报告
2014/10/21 职场文书
小学生表扬稿范文
2015/05/05 职场文书
活动宣传稿范文
2015/07/23 职场文书
详解MongoDB排序时内存大小限制与创建索引的注意事项
2022/05/06 MongoDB