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使用curl发送json格式数据实例
Dec 17 PHP
php多文件上传下载示例分享
Feb 20 PHP
php中替换字符串中的空格为逗号','的方法
Jun 09 PHP
Laravel框架路由配置总结、设置技巧大全
Sep 03 PHP
php计算给定时间之前的函数用法实例
Apr 03 PHP
详解WordPress开发中用于获取分类及子页面的函数用法
Jan 08 PHP
Laravel实现搜索的时候分页并携带参数
Oct 15 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
Nov 23 PHP
PHP防止sql注入小技巧之sql预处理原理与实现方法分析
Dec 13 PHP
让whoops帮我们告别ThinkPHP6的异常页面
Mar 02 PHP
PHP获取类私有属性的3种方法
Sep 10 PHP
laravel7学习之无限级分类的最新实现方法
Sep 30 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
星际争霸教主Flash的ID由来:你永远不会知道他之前的ID是www!
2019/01/18 星际争霸
基于php伪静态的实现详细介绍
2013/04/28 PHP
怎么在Windows系统中搭建php环境
2013/08/31 PHP
php检查日期函数checkdate用法实例
2015/03/19 PHP
PHP弹出对话框技巧详细解读
2015/09/26 PHP
javascript知识点收藏
2007/02/22 Javascript
ExtJS 简介 让你知道extjs是什么
2008/12/29 Javascript
js parseInt(&quot;08&quot;)未指定进位制问题
2010/06/19 Javascript
jQuery获取浏览器中的分辨率实现代码
2013/04/23 Javascript
获取数组中最大最小值方法js代码(自写)
2013/08/12 Javascript
jQuery中bind()方法用法实例
2015/01/19 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
2015/03/18 Javascript
JavaScript实现带播放列表的音乐播放器实例分享
2016/03/07 Javascript
JS实现表单多文件上传样式美化支持选中文件后删除相关项
2016/09/30 Javascript
最全的JavaScript开发工具列表 总有一款适合你
2017/06/29 Javascript
laydate 显示结束时间不小于开始时间的实例
2017/08/11 Javascript
JS中Swiper的使用和轮播图效果
2017/08/11 Javascript
vue项目中引入noVNC远程桌面的方法
2018/03/05 Javascript
js图片查看器插件用法示例
2019/06/22 Javascript
基于vue+axios+lrz.js微信端图片压缩上传方法
2019/06/25 Javascript
[01:08:57]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第二场
2014/05/24 DOTA
Python循环语句之break与continue的用法
2015/10/14 Python
Python的SimpleHTTPServer模块用处及使用方法简介
2018/01/22 Python
python实现字符串和字典的转换
2018/09/29 Python
Python3.5 Pandas模块缺失值处理和层次索引实例详解
2019/04/23 Python
Python数据类型之列表和元组的方法实例详解
2019/07/08 Python
python实现中文文本分句的例子
2019/07/15 Python
Python如何通过Flask-Mail发送电子邮件
2020/01/29 Python
自我鉴定注意事项
2014/01/19 职场文书
大学毕业自我评价
2014/02/02 职场文书
公务员爱岗敬业演讲稿
2014/08/26 职场文书
2014光棍节大学生联谊活动方案
2014/10/10 职场文书
大学生国家助学金感谢信
2015/01/23 职场文书
结婚十年感言
2015/07/31 职场文书
暑假打工感想
2015/08/07 职场文书
js之ajax文件上传
2021/05/13 Javascript