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+mysql保存和输出文件
Oct 09 PHP
介绍php设计模式中的工厂模式
Jun 12 PHP
php环境配置之CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI比较?
Oct 17 PHP
浅析php变量修饰符static的使用
Jun 28 PHP
destoon出现验证码不显示时的紧急处理方法
Aug 22 PHP
php自定义截取中文字符串-utf8版
Feb 27 PHP
ThinkPHP框架分布式数据库连接方法详解
Mar 14 PHP
降低PHP Redis内存占用
Mar 23 PHP
thinkphp5.0自定义验证规则使用方法
Nov 16 PHP
PHP自定义序列化接口Serializable用法分析
Dec 29 PHP
Laravel 加载第三方类库的方法
Apr 20 PHP
php反射学习之不用new方法实例化类操作示例
Jun 14 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
使用Curl进行抓取远程内容时url中文编码问题示例探讨
2013/10/29 PHP
php检测用户是否用手机(Mobile)访问网站的类
2014/01/09 PHP
Laravel 5框架学习之Eloquent 关系
2015/04/09 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
2020/02/21 PHP
Thinkphp 框架扩展之类库扩展操作详解
2020/04/23 PHP
Jquery Change与bind事件代码
2011/09/29 Javascript
jQuery版仿Path菜单效果
2011/12/15 Javascript
方便实用的jQuery checkbox复选框全选功能简单实例
2013/10/09 Javascript
jQuery实现信息提示框(带有圆角框与动画)效果
2015/08/07 Javascript
js实现横向伸展开的二级导航菜单代码
2015/08/28 Javascript
在网页中插入百度地图的步骤详解
2016/12/02 Javascript
js 博客内容进度插件详解
2017/02/19 Javascript
微信扫码支付零云插件版实例详解
2017/04/26 Javascript
Vue工程模板文件 webpack打包配置方法
2017/12/26 Javascript
vue axios整合使用全攻略
2018/05/24 Javascript
利用Node.js批量抓取高清妹子图片实例教程
2018/08/02 Javascript
Angular2 自定义表单验证器的实现方法
2018/12/14 Javascript
微信网页登录逻辑与实现方法
2019/04/29 Javascript
微信小程序页面滚动到指定位置代码实例
2019/09/07 Javascript
解决layui-open关闭自身窗口的问题
2019/09/10 Javascript
uniapp实现可滑动选项卡
2020/10/21 Javascript
python检查URL是否正常访问的小技巧
2017/02/25 Python
python学生信息管理系统
2018/03/13 Python
Python高级特性 切片 迭代解析
2019/08/23 Python
Django+python服务器部署与环境部署教程详解
2020/03/30 Python
Python requests接口测试实现代码
2020/09/08 Python
使用Filters滤镜弥补CSS3的跨浏览器问题以及兼容低版本IE
2013/01/23 HTML / CSS
CSS3中使用RGBA设置透明度的示例
2015/08/04 HTML / CSS
浅谈基于Canvas的手绘风格图形库Rough.js
2018/03/19 HTML / CSS
周年庆典邀请函范文
2014/01/24 职场文书
优秀学生获奖感言
2014/02/15 职场文书
乡镇网格化管理实施方案
2014/03/23 职场文书
爱心募捐感谢信
2015/01/22 职场文书
公司仓库管理制度
2015/08/04 职场文书
Python机器学习之决策树和随机森林
2021/07/15 Javascript
python区块链实现简版工作量证明
2022/05/25 Python