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实现Socket服务器的代码
Apr 03 PHP
PHP面向对象三大特点学习(充分理解抽象、封装、继承、多态)
May 07 PHP
PHP合并两个数组的两种方式的异同
Sep 14 PHP
php-cli简介(不会Shell语言一样用Shell)
Jun 03 PHP
php mysql_real_escape_string函数用法与实例教程
Sep 30 PHP
php获取字符串中各个字符出现次数的方法
Feb 23 PHP
验证token、回复图文\文本、推送消息的实用微信类php代码
Jun 28 PHP
简单谈谈PHP中的trait
Feb 25 PHP
PHP编程计算两个时间段是否有交集的实现方法(不算边界重叠)
May 30 PHP
PHP的mysqli_stmt_init()函数讲解
Jan 24 PHP
Laravel 默认邮箱登录改成用户名登录的实现方法
Aug 12 PHP
phpmyadmin在宝塔面板里进不去的解决方案
Jul 06 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下通过QRCode类库创建中间带网站LOGO的二维码
2014/07/12 PHP
PHP aes (ecb)解密后乱码问题
2015/06/22 PHP
PHP给源代码加密的几种方法汇总(推荐)
2018/02/06 PHP
PHP实现八皇后算法
2019/05/06 PHP
PHP 枚举类型的管理与设计知识点总结
2020/02/13 PHP
CI框架简单分页类用法示例
2020/06/06 PHP
IE/FireFox具备兼容性的拖动代码
2007/08/13 Javascript
Firefox getBoxObjectFor getBoundingClientRect联系
2008/10/26 Javascript
关于query Javascript CSS Selector engine
2013/04/12 Javascript
Javascript中 关于prototype属性实现继承的原理图
2013/04/16 Javascript
jQuery标签编辑插件Tagit使用指南
2015/04/21 Javascript
JavaScript中访问id对象 属性的方式访问属性(实例代码)
2016/10/28 Javascript
Vue.js组件tab实现选项卡切换
2020/03/23 Javascript
详解使用vue-router进行页面切换时滚动条位置与滚动监听事件
2017/03/08 Javascript
详解如何让InstantClick兼容MathJax、百度统计等
2017/09/12 Javascript
ios设备中angularjs无法改变页面title的解决方法
2018/09/13 Javascript
代码整洁之道(重构)
2018/10/25 Javascript
个人小程序接入支付解决方案
2019/05/23 Javascript
vue实现简单瀑布流布局
2020/05/28 Javascript
vue实现图片上传到后台
2020/06/29 Javascript
详解Python文本操作相关模块
2017/06/22 Python
Python WSGI的深入理解
2018/08/01 Python
python迭代器常见用法实例分析
2019/11/22 Python
Python 利用Entrez库筛选下载PubMed文献摘要的示例
2020/11/24 Python
现代生活方式的家具和装饰:Dot & Bo
2018/12/26 全球购物
必须要使用游标的SQL语句有那些
2012/05/07 面试题
总经理办公室主任岗位职责
2013/11/12 职场文书
市政施工员自我鉴定
2014/01/15 职场文书
高三自我评价
2014/02/01 职场文书
教学改革实施方案
2014/03/31 职场文书
文明倡议书范文
2014/04/15 职场文书
论文指导教师评语
2014/04/28 职场文书
项目建议书怎么写
2014/05/15 职场文书
审计班子对照检查材料
2014/08/27 职场文书
工程质检员岗位职责
2015/04/08 职场文书
导游词之太原天龙山
2020/01/02 职场文书