·您当前的位置:主页 > 技术教程 > 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. * 参数d1,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. //根据you vid 获取相应的视频地址 
  29. return self::_getYouku(trim($matches[1])); 
  30. /** 
  31. * [_cget curl获取数据] 
  32. * @param  [type]  $url     [url地址] 
  33. * @param  boolean $convert [是否转换编码] 
  34. * @param  integer $timeout [超时时间] 
  35. * @return [type]           [description] 
  36. */ 
  37. public static function _cget($url,$convert=false,$timeout=10){ 
  38. $ch=curl_init($url); 
  39. curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); 
  40. curl_setopt($ch,CURLOPT_TIMEOUT,$timeout); 
  41. curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout); 
  42. curl_setopt($ch,CURLOPT_USERAGENT,self::USER_AGENT); 
  43. curl_setopt($ch,CURLOPT_REFERER,self::REFERER); 
  44. curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); //跟随301跳转 
  45. curl_setopt($ch,CURLOPT_AUTOREFERER,1); //自动设置referer 
  46. $res=curl_exec($ch); 
  47. curl_close($ch); 
  48. if($convert){ 
  49. $res=mb_convert_encoding($res,self::TO_ENCODE,self::FORM_ENCODE); 
  50. return $res; 
  51.  
  52. //start 获得优酷视频需要用到的方法 
  53. private static function getSid(){ 
  54. $sid = time().(mt_rand(0,9000)+10000); 
  55. return $sid; 
  56.  
  57. private static function getKey($key1,$key2){ 
  58. $a = hexdec($key1); 
  59. $b = $a ^0xA55AA5A5; 
  60. $b = dechex($b); 
  61. return $key2.$b; 
  62.  
  63. private static function getFileid($fileId,$seed){ 
  64. $mixed = self::getMixString($seed); 
  65. $ids = explode(“*”,rtrim($fileId,’*’)); //去掉末尾的*号分割为数组 
  66. $realId = “”; 
  67. for ($i=0;$i<count($ids);$i++){ 
  68. $idx = $ids[$i]; 
  69. $realId .substr($mixed,$idx,1); 
  70. return $realId; 
  71.  
  72. private static function getMixString($seed){ 
  73. $mixed = “”; 
  74. $source = self::$source; 
  75. $len = strlen($source); 
  76. for($i=0;$i<$len;$i++){ 
  77. $seed = ($seed * 211 + 30031)%65536; 
  78. $index = ($seed / 65536 * strlen($source)); 
  79. $c = substr($source,$index,1); 
  80. $mixed .= $c; 
  81. $source = str_replace($c,””,$source); 
  82. return $mixed; 
  83.  
  84. private static function yk_d($a){ 
  85. if (!$a) { 
  86. return ”; 
  87. $f = strlen($a); 
  88. $b = 0
  89. $str = self::$str; 
  90. for ($c = ”; $b < $f;) { 
  91. $e = self::charCodeAt($a, $b++) & 255; 
  92. if ($b == $f) { 
  93. $c .self::charAt($str, $e >> 2); 
  94. $c .self::charAt($str, ($e & 3) << 4); 
  95. $c .= ‘==’; 
  96. break; 
  97. $g = self::charCodeAt($a, $b++); 
  98. if ($b == $f) { 
  99. $c .self::charAt($str, $e >> 2); 
  100. $c .self::charAt($str, ($e & 3) << 4 | ($g & 240) >> 4); 
  101. $c .self::charAt($str, ($g & 15) << 2); 
  102. $c .= ‘=’; 
  103. break; 
  104. $h = self::charCodeAt($a, $b++); 
  105. $c .self::charAt($str, $e >> 2); 
  106. $c .self::charAt($str, ($e & 3) << 4 | ($g & 240) >> 4); 
  107. $c .self::charAt($str, ($g & 15) << 2 | ($h & 192) >> 6); 
  108. $c .self::charAt($str, $h & 63); 
  109. return $c; 
  110. private static function yk_na($a){ 
  111. if (!$a) { 
  112. return ”; 
  113.  
  114. $h = explode(‘,’, self::$sz); 
  115. $i = strlen($a); 
  116. $f = 0
  117. for ($e = ”; $f < $i;) { 
  118. do { 
  119. $c = $h[self::charCodeAt($a, $f++) & 255]; 
  120. } while ($f < $i && -1 == $c); 
  121. if (-1 == $c) { 
  122. break; 
  123. do { 
  124. $b = $h[self::charCodeAt($a, $f++) & 255]; 
  125. } while ($f < $i && -1 == $b); 
  126. if (-1 == $b) { 
  127. break; 
  128. $e .self::fromCharCode($c << 2 | ($b & 48) >> 4); 
  129. do { 
  130. $c = self::charCodeAt($a, $f++) & 255; 
  131. if (61 == $c) { 
  132. return $e; 
  133. $c = $h[$c]; 
  134. } while ($f < $i && -1 == $c); 
  135. if (-1 == $c) { 
  136. break; 
  137. $e .self::fromCharCode(($b & 15) << 4 | ($c & 60) >> 2); 
  138. do { 
  139. $b = self::charCodeAt($a, $f++) & 255; 
  140. if (61 == $b) { 
  141. return $e; 
  142. $b = $h[$b]; 
  143. } while ($f < $i && -1 == $b); 
  144. if (-1 == $b) { 
  145. break; 
  146. $e .self::fromCharCode(($c & 3) << 6 | $b); 
  147. return $e; 
  148. private static function yk_e($a, $c){ 
  149. for ($f = 0, $i, $e = ”, $h = 0; 256 > $h; $h++) { 
  150. $b[$h] = $h; 
  151. for ($h = 0; 256 > $h; $h++) { 
  152. $f = (($f + $b[$h]) + self::charCodeAt($a, $h % strlen($a))) % 256; 
  153. $i = $b[$h]; 
  154. $b[$h] = $b[$f]; 
  155. $b[$f] = $i; 
  156. for ($q = ($f = ($h = 0)); $q < strlen($c); $q++) { 
  157. $h = ($h + 1) % 256; 
  158. $f = ($f + $b[$h]) % 256; 
  159. $i = $b[$h]; 
  160. $b[$h] = $b[$f]; 
  161. $b[$f] = $i; 
  162. $e .self::fromCharCode(self::charCodeAt($c, $q) ^ $b[($b[$h] + $b[$f]) % 256]); 
  163. return $e; 
  164.  
  165. private static function fromCharCode($codes){ 
  166. if (is_scalar($codes)) { 
  167. $codes = func_get_args(); 
  168. $str = ”; 
  169. foreach ($codes as $code) { 
  170. $str .chr($code); 
  171. return $str; 
  172. private static function charCodeAt($str, $index){ 
  173. static $charCode = array(); 
  174. $key = md5($str); 
  175. $index = $index + 1; 
  176. if (isset($charCode[$key])) { 
  177. return $charCode[$key][$index]; 
  178. $charCode[$key] = unpack(‘C*’, $str); 
  179. return $charCode[$key][$index]; 
  180.  
  181. private static function charAt($str, $index = 0){ 
  182. return substr($str, $index, 1); 
  183. /** 
  184. * [_getYouku description] 
  185. * @param  [type] $vid [视频id] 
  186. * @return [type]      [description] 
  187. */ 
  188. public static function _getYouku($vid){ 
  189. //$link = “http://v.youku.com/player/getPlayList/VideoIDS/{$vid}/Pf/4″; //获取视频信息json 有些视频获取不全(土豆网的 火影忍者) 
  190. $blink = self::$base.$vid; 
  191. $link = $blink.”/Pf/4/ctype/12/ev/1″; 
  192. $retval = self::_cget($link); 
  193. $bretval = self::_cget($blink); 
  194. if ($retval) { 
  195. $rs = json_decode($retval, true); 
  196. $brs = json_decode($bretval, true); 
  197. if(!empty($rs[‘data’][0][‘error’])){ 
  198. return false;  //有错误返回false 
  199. $data = array(); 
  200. $streamtypes = $rs[‘data’][0][‘streamtypes’];  //可以输出的视频清晰度 
  201. $streamfileids = $rs[‘data’][0][‘streamfileids’]; 
  202. $seed = $rs[‘data’][0][‘seed’]; 
  203. $segs = $rs[‘data’][0][‘segs’]; 
  204. $ip = $rs[‘data’][0][‘ip’]; 
  205. $bsegs =  $brs[‘data’][0][‘segs’]; 
  206. list($sid, $token) = explode(‘_’, self::yk_e(‘becaf9be’, self::yk_na($rs[‘data’][0][‘ep’]))); 
  207. foreach ($segs as $key=>$val) { 
  208. if(in_array($key,$streamtypes)){ 
  209. foreach($val as $k=> $v){ 
  210. $no = strtoupper(dechex($v[‘no’])); //转换为16进制 大写 
  211. if(strlen($no) == 1){ 
  212. $no =”0″.$no;  //no 为每段视频序号 
  213. //构建视频地址K值 
  214. $_k = $v[‘k’]; 
  215. if ((!$_k || $_k == ”) || $_k == ‘-1’) { 
  216. $_k = $bsegs[$key][$k][‘k’]; 
  217. $fileId = self::getFileid($streamfileids[$key],$seed); 
  218. $fileId = substr($fileId,0,8).$no.substr($fileId,10); 
  219. $ep = urlencode(iconv(‘gbk’, ‘UTF-8’, self::yk_d(self::yk_e(‘bf7e5f01’, ((($sid . ‘_’) . $fileId) . ‘_’) . $token)))); 
  220. //判断后缀类型 、获得后缀 
  221. $typeArray = array(“flv”=>”flv”,”mp4″=>”mp4″,”hd2″=>”flv”,”3gphd”=>”mp4″,”3gp”=>”flv”,”hd3″=>”flv”); 
  222. //判断视频清晰度 
  223. $sharpness = array(“flv”=>”normal”,”flvhd”=>”normal”,”mp4″=>”high”,”hd2″=>”super”,”3gphd”=>”high”,”3gp”=>”normal”,”hd3″=>”original”); //清晰度 数组 
  224. $fileType = $typeArray[$key]; 
  225. $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;; 
  226. //返回 图片 标题 链接  时长  视频地址 
  227. $data[‘img’] = $rs[‘data’][0][‘logo’]; 
  228. $data[‘title’] = $rs[‘data’][0][‘title’]; 
  229. $data[‘seconds’] = $rs[‘data’][0][‘seconds’]; 
  230. return $data; 
  231. } else { 
  232. return false; 
  233. //end  获得优酷视频需要用到的方法 
  234.  
  235. 说明:调用Youku::parse(‘http://v.youku.com/v_show/id_XNzM4ODk0ODcy.html’)就能得到所有地址。 

 

热门文章推荐

请稍候...