·您当前的位置:首页 > 技术教程 > PHP教程 >

[php]优酷真实视频地址解析算法

时间:2016-05-14 11:55酷播
[php]优酷真实视频地址解析算法,因数据库问题代码显示异常,可能导致代码报错。请自行修正或使用本站提供的api。
因数据库问题代码显示异常,可能导致代码报错。请自行修正或使用本站提供的api。 
  1. 因数据库问题代码显示异常,可能导致代码报错。请自行修正或使用本站提供的api。 
  2. api地址:http://www.ikay.me/youku.php 
  3. <php 
  4. /* 
  5. * Author:ikay 
  6. * 利用优酷的新算法解析 
  7. * http://www.ikay.me/youku.php?id=XODM3NDQ5MDYw&d=3 
  8. * 参数d= 1,2,3? 分别表示标清,高清,超清 
  9. */ 
  10. error_reporting(0); 
  11. class Youku { 
  12.  
  13. const USER_AGENT = “Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36”; 
  14. const REFERER = “http://www.youku.com”; 
  15. const FORM_ENCODE = “GBK”; 
  16. const TO_ENCODE = “UTF-8”; 
  17. private static $base = “http://v.youku.com/player/getPlaylist/VideoIDS/”; 
  18. private static $source = “abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890”; 
  19. private static $sz = ‘-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1’; 
  20. private static $str = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/’; 
  21.  
  22. public static function parse($url){ 
  23. preg_match(“#id\_([\w=]+)#”, $url, $matches); //id里可以有=号 
  24. if (empty($matches)){ 
  25. $html = self::_cget($url); 
  26. preg_match(“#videoId2\s*=\s*\'(\w+)\’#”, $html, $matches); 
  27. if(!$matches) return false; 
  28. } 
  29. //根据you vid 获取相应的视频地址 
  30. return self::_getYouku(trim($matches[1])); 
  31. } 
  32. /** 
  33. * [_cget curl获取数据] 
  34. * @param  [type]  $url     [url地址] 
  35. * @param  boolean $convert [是否转换编码] 
  36. * @param  integer $timeout [超时时间] 
  37. * @return [type]           [description] 
  38. */ 
  39. public static function _cget($url,$convert=false,$timeout=10){ 
  40. $ch=curl_init($url); 
  41. curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 
  42. curl_setopt($ch,CURLOPT_TIMEOUT,$timeout); 
  43. curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout); 
  44. curl_setopt($ch,CURLOPT_USERAGENT,self::USER_AGENT); 
  45. curl_setopt($ch,CURLOPT_REFERER,self::REFERER); 
  46. curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); //跟随301跳转 
  47. curl_setopt($ch,CURLOPT_AUTOREFERER,1); //自动设置referer 
  48. $res=curl_exec($ch); 
  49. curl_close($ch); 
  50. if($convert){ 
  51. $res=mb_convert_encoding($res,self::TO_ENCODE,self::FORM_ENCODE); 
  52. } 
  53. return $res; 
  54. } 
  55.  
  56. //start 获得优酷视频需要用到的方法 
  57. private static function getSid(){ 
  58. $sid = time().(mt_rand(0,9000)+10000); 
  59. return $sid; 
  60. } 
  61.  
  62. private static function getKey($key1,$key2){ 
  63. $a = hexdec($key1); 
  64. $b = $a ^0xA55AA5A5; 
  65. $b = dechex($b); 
  66. return $key2.$b; 
  67. } 
  68.  
  69. private static function getFileid($fileId,$seed){ 
  70. $mixed = self::getMixString($seed); 
  71. $ids = explode(“*”,rtrim($fileId,’*’)); //去掉末尾的*号分割为数组 
  72. $realId = “”; 
  73. for ($i=0;$i<count($ids);$i++){ 
  74. $idx = $ids[$i]; 
  75. $realId .= substr($mixed,$idx,1); 
  76. } 
  77. return $realId; 
  78. } 
  79.  
  80. private static function getMixString($seed){ 
  81. $mixed = “”; 
  82. $source = self::$source; 
  83. $len = strlen($source); 
  84. for($i=0;$i<$len;$i++){ 
  85. $seed = ($seed * 211 + 30031)%65536; 
  86. $index = ($seed / 65536 * strlen($source)); 
  87. $c = substr($source,$index,1); 
  88. $mixed .= $c; 
  89. $source = str_replace($c,””,$source); 
  90. } 
  91. return $mixed; 
  92. } 
  93.  
  94. private static function yk_d($a){ 
  95. if (!$a) { 
  96. return ”; 
  97. } 
  98. $f = strlen($a); 
  99. $b = 0; 
  100. $str = self::$str; 
  101. for ($c = ”; $b < $f;) { 
  102. $e = self::charCodeAt($a, $b++) & 255; 
  103. if ($b == $f) { 
  104. $c .= self::charAt($str, $e >> 2); 
  105. $c .= self::charAt($str, ($e & 3) << 4); 
  106. $c .= ‘==’; 
  107. break; 
  108. } 
  109. $g = self::charCodeAt($a, $b++); 
  110. if ($b == $f) { 
  111. $c .= self::charAt($str, $e >> 2); 
  112. $c .= self::charAt($str, ($e & 3) << 4 | ($g & 240) >> 4); 
  113. $c .= self::charAt($str, ($g & 15) << 2); 
  114. $c .= ‘=’; 
  115. break; 
  116. } 
  117. $h = self::charCodeAt($a, $b++); 
  118. $c .= self::charAt($str, $e >> 2); 
  119. $c .= self::charAt($str, ($e & 3) << 4 | ($g & 240) >> 4); 
  120. $c .= self::charAt($str, ($g & 15) << 2 | ($h & 192) >> 6); 
  121. $c .= self::charAt($str, $h & 63); 
  122. } 
  123. return $c; 
  124. } 
  125. private static function yk_na($a){ 
  126. if (!$a) { 
  127. return ”; 
  128. } 
  129.  
  130. $h = explode(‘,’, self::$sz); 
  131. $i = strlen($a); 
  132. $f = 0; 
  133. for ($e = ”; $f < $i;) { 
  134. do { 
  135. $c = $h[self::charCodeAt($a, $f++) & 255]; 
  136. } while ($f < $i && -1 == $c); 
  137. if (-1 == $c) { 
  138. break; 
  139. } 
  140. do { 
  141. $b = $h[self::charCodeAt($a, $f++) & 255]; 
  142. } while ($f < $i && -1 == $b); 
  143. if (-1 == $b) { 
  144. break; 
  145. } 
  146. $e .= self::fromCharCode($c << 2 | ($b & 48) >> 4); 
  147. do { 
  148. $c = self::charCodeAt($a, $f++) & 255; 
  149. if (61 == $c) { 
  150. return $e; 
  151. } 
  152. $c = $h[$c]; 
  153. } while ($f < $i && -1 == $c); 
  154. if (-1 == $c) { 
  155. break; 
  156. } 
  157. $e .= self::fromCharCode(($b & 15) << 4 | ($c & 60) >> 2); 
  158. do { 
  159. $b = self::charCodeAt($a, $f++) & 255; 
  160. if (61 == $b) { 
  161. return $e; 
  162. } 
  163. $b = $h[$b]; 
  164. } while ($f < $i && -1 == $b); 
  165. if (-1 == $b) { 
  166. break; 
  167. } 
  168. $e .= self::fromCharCode(($c & 3) << 6 | $b); 
  169. } 
  170. return $e; 
  171. } 
  172. private static function yk_e($a, $c){ 
  173. for ($f = 0, $i, $e = ”, $h = 0; 256 > $h; $h++) { 
  174. $b[$h] = $h; 
  175. } 
  176. for ($h = 0; 256 > $h; $h++) { 
  177. $f = (($f + $b[$h]) + self::charCodeAt($a, $h % strlen($a))) % 256; 
  178. $i = $b[$h]; 
  179. $b[$h] = $b[$f]; 
  180. $b[$f] = $i; 
  181. } 
  182. for ($q = ($f = ($h = 0)); $q < strlen($c); $q++) { 
  183. $h = ($h + 1) % 256; 
  184. $f = ($f + $b[$h]) % 256; 
  185. $i = $b[$h]; 
  186. $b[$h] = $b[$f]; 
  187. $b[$f] = $i; 
  188. $e .= self::fromCharCode(self::charCodeAt($c, $q) ^ $b[($b[$h] + $b[$f]) % 256]); 
  189. } 
  190. return $e; 
  191. } 
  192.  
  193. private static function fromCharCode($codes){ 
  194. if (is_scalar($codes)) { 
  195. $codes = func_get_args(); 
  196. } 
  197. $str = ”; 
  198. foreach ($codes as $code) { 
  199. $str .= chr($code); 
  200. } 
  201. return $str; 
  202. } 
  203. private static function charCodeAt($str, $index){ 
  204. static $charCode = array(); 
  205. $key = md5($str); 
  206. $index = $index + 1; 
  207. if (isset($charCode[$key])) { 
  208. return $charCode[$key][$index]; 
  209. } 
  210. $charCode[$key] = unpack(‘C*’, $str); 
  211. return $charCode[$key][$index]; 
  212. } 
  213.  
  214. private static function charAt($str, $index = 0){ 
  215. return substr($str, $index, 1); 
  216. } 
  217. /** 
  218. * [_getYouku description] 
  219. * @param  [type] $vid [视频id] 
  220. * @return [type]      [description] 
  221. */ 
  222. public static function _getYouku($vid){ 
  223. //$link = “http://v.youku.com/player/getPlayList/VideoIDS/{$vid}/Pf/4″; //获取视频信息json 有些视频获取不全(土豆网的 火影忍者) 
  224. $blink = self::$base.$vid; 
  225. $link = $blink.”/Pf/4/ctype/12/ev/1″; 
  226. $retval = self::_cget($link); 
  227. $bretval = self::_cget($blink); 
  228. if ($retval) { 
  229. $rs = json_decode($retval, true); 
  230. $brs = json_decode($bretval, true); 
  231. if(!empty($rs[‘data’][0][‘error’])){ 
  232. return false;  //有错误返回false 
  233. } 
  234. $data = array(); 
  235. $streamtypes = $rs[‘data’][0][‘streamtypes’];  //可以输出的视频清晰度 
  236. $streamfileids = $rs[‘data’][0][‘streamfileids’]; 
  237. $seed = $rs[‘data’][0][‘seed’]; 
  238. $segs = $rs[‘data’][0][‘segs’]; 
  239. $ip = $rs[‘data’][0][‘ip’]; 
  240. $bsegs =  $brs[‘data’][0][‘segs’]; 
  241. list($sid, $token) = explode(‘_’, self::yk_e(‘becaf9be’, self::yk_na($rs[‘data’][0][‘ep’]))); 
  242. foreach ($segs as $key=>$val) { 
  243. if(in_array($key,$streamtypes)){ 
  244. foreach($val as $k=> $v){ 
  245. $no = strtoupper(dechex($v[‘no’])); //转换为16进制 大写 
  246. if(strlen($no) == 1){ 
  247. $no =”0″.$no;  //no 为每段视频序号 
  248. } 
  249. //构建视频地址K值 
  250. $_k = $v[‘k’]; 
  251. if ((!$_k || $_k == ”) || $_k == ‘-1’) { 
  252. $_k = $bsegs[$key][$k][‘k’]; 
  253. } 
  254. $fileId = self::getFileid($streamfileids[$key],$seed); 
  255. $fileId = substr($fileId,0,8).$no.substr($fileId,10); 
  256. $ep = urlencode(iconv(‘gbk’, ‘UTF-8’, self::yk_d(self::yk_e(‘bf7e5f01’, ((($sid . ‘_’) . $fileId) . ‘_’) . $token)))); 
  257. //判断后缀类型 、获得后缀 
  258. $typeArray = array(“flv”=>”flv”,”mp4″=>”mp4″,”hd2″=>”flv”,”3gphd”=>”mp4″,”3gp”=>”flv”,”hd3″=>”flv”); 
  259. //判断视频清晰度 
  260. $sharpness = array(“flv”=>”normal”,”flvhd”=>”normal”,”mp4″=>”high”,”hd2″=>”super”,”3gphd”=>”high”,”3gp”=>”normal”,”hd3″=>”original”); //清晰度 数组 
  261. $fileType = $typeArray[$key]; 
  262. $data[$sharpness[$key]][$k] = “http://k.youku.com/player/getFlvPath/sid/”.$sid.”_00/st/{$fileType}/fileid/”.$fileId.”?K=”.$_k.”&hd=1&myp=0&ts=”.((((($v[‘seconds’].’&ypp=0&ctype=12&ev=1&token=’).$token).’&oip=’).$ip).’&ep=’).$ep;; 
  263. } 
  264. } 
  265. } 
  266. //返回 图片 标题 链接  时长  视频地址 
  267. $data[‘img’] = $rs[‘data’][0][‘logo’]; 
  268. $data[‘title’] = $rs[‘data’][0][‘title’]; 
  269. $data[‘seconds’] = $rs[‘data’][0][‘seconds’]; 
  270. return $data; 
  271. } else { 
  272. return false; 
  273. } 
  274. } 
  275. //end  获得优酷视频需要用到的方法 
  276. } 
  277.  
  278. 说明:调用Youku::parse(‘http://v.youku.com/v_show/id_XNzM4ODk0ODcy.html’)就能得到所有地址。 

 

热门文章推荐

请稍候...

保利威视云平台-轻松实现点播直播视频应用

酷播云数据统计分析跨平台播放器