Xyz.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. <?php
  2. if (!defined('BASEPATH')) exit('No direct script access allowed');
  3. class Xyz {
  4. function __construct() {
  5. set_time_limit(0);
  6. if(substr(Mu_Ffpath,0,2) == './'){
  7. $Mu_Ffpath = FCPATH.substr(Mu_Ffpath,2);
  8. }else{
  9. $Mu_Ffpath = Mu_Ffpath;
  10. }
  11. if(substr($Mu_Ffpath,-1) != '/') $Mu_Ffpath .= '/';
  12. $xt = php_uname();
  13. if(strpos($xt, 'Windows') !== false){
  14. $this->zmpath = 'packs/zimu.ass';
  15. $this->sypath = 'packs/logo';
  16. $this->ffmpeg = $Mu_Ffpath.'ffmpeg.exe';
  17. $this->ffprobe = $Mu_Ffpath.'ffprobe.exe';
  18. }else{
  19. $this->zmpath = FCPATH.'packs/zimu.ass';
  20. $this->sypath = FCPATH.'packs/logo';
  21. $this->ffmpeg = $Mu_Ffpath.'ffmpeg';
  22. $this->ffprobe = $Mu_Ffpath.'ffprobe';
  23. }
  24. $ip = '/' == DIRECTORY_SEPARATOR ? $_SERVER['SERVER_ADDR'] : gethostbyname($_SERVER['SERVER_NAME']);
  25. $json = get_curl('http://api.m3u8.ctcms.cn/api?ip='.$ip);
  26. $arr = json_decode($json,1);
  27. // if(empty($arr['msg']) || $arr['msg'] == 'no') exit('授权已到期');
  28. }
  29. public function transcode($src_path,$m3u8_path='',$jpg_path='',$gif_path='') {
  30. $src_path = str_replace("//","/",str_replace("\\","/",$src_path));
  31. $m3u8_path = str_replace("//","/",str_replace("\\","/",$m3u8_path));
  32. $obj_path = dirname($m3u8_path);
  33. mkdirss($obj_path);
  34. $m3u8_time = Mu_Time; //ts时长
  35. //jpg + gif
  36. if(!empty($jpg_path)) $jpg = $this->vodtojpg($src_path,$jpg_path);
  37. if(!empty($gif_path)) $gif = $this->vodtogif($src_path,$gif_path);
  38. //获取格式命令
  39. $format = $this->format($src_path);
  40. //字幕+水印
  41. $watermark = $this->watermark_zm();
  42. //加密
  43. $aes = $this->m3u8aes($obj_path);
  44. //缩放
  45. $Mu_Size = defined('SIZE') ? SIZE : Mu_Size;
  46. $change = !empty($Mu_Size) ? '-s '.$Mu_Size : '';
  47. $Mu_Kbps = defined('KBPS') ? (int)KBPS : (int)Mu_Kbps;
  48. $bit_rate = (int)$format['bit_rate'];
  49. $kbps = '';
  50. if($bit_rate > 0){
  51. $bit = $bit_rate / 1000;
  52. if($Mu_Kbps > 0 && $bit > $Mu_Kbps){
  53. $kbps = '-b:v '.$Mu_Kbps.'k';
  54. }
  55. }
  56. //跳过片头
  57. $pttime = Mu_PtTime == 0 ? '' : '-ss '.formattime(Mu_PtTime,1);
  58. //速度
  59. $prearr = array('ultrafast','superfast','veryfast','faster','fast','medium','slow','slower');
  60. $Mu_Preset = defined('Mu_Preset') ? Mu_Preset : 'fast';
  61. if(!in_array($Mu_Preset, $prearr) || $Mu_Preset == 'medium') $Mu_Preset = '';
  62. $preset = !empty($Mu_Preset) ? '-preset:v '.$Mu_Preset : '';
  63. //执行转换
  64. $extarr = explode(',', $format['ext']);
  65. if(in_array('mp4', $extarr) && empty($watermark)){
  66. $make_command = $this->ffmpeg.' '.$pttime.' -y -i '.$src_path.' '.$change.' '.$kbps.' '.$preset.' -codec copy -vbsf h264_mp4toannexb -map 0 -f segment -segment_list '.$m3u8_path.' -segment_time '.$m3u8_time.' '.$obj_path.'/%04d.ts';
  67. }elseif($format['audio']=='aac' && $format['video'] == 'h264'){
  68. $make_command = $this->ffmpeg.' '.$pttime.' -y -i '.$src_path.' '.$watermark.' '.$change.' '.$kbps.' '.$preset.' -hls_time '.$m3u8_time.' '.$aes.' -hls_segment_filename '.$obj_path.'/%04d.ts -hls_list_size 0 '.$m3u8_path;
  69. }else{
  70. $make_command = $this->ffmpeg.' '.$pttime.' -y -i '.$src_path.' '.$watermark.' '.$change.' '.$kbps.' '.$preset.' -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time '.$m3u8_time.' '.$aes.' -hls_segment_filename '.$obj_path.'/%04d.ts '.$m3u8_path;
  71. }
  72. $result = exec($make_command,$arr,$log);
  73. if($log == 0){
  74. return defined('KBPS') ? KBPS : 'm3u8ok';
  75. }else{
  76. return '';
  77. }
  78. }
  79. //获取视频格式信息
  80. public function format($src_path){
  81. $src_path = str_replace("//","/",str_replace("\\","/",$src_path));
  82. $arr = array(
  83. 'video' => '',
  84. 'audio' => '',
  85. 'duration' => 0,
  86. 'width' => 0,
  87. 'height' => 0,
  88. 'dis_ratio' => '',
  89. 'size' => 0,
  90. 'bit_rate' => 0
  91. );
  92. if(empty($src_path)) return $arr;
  93. $format_command = $this->ffprobe.' -v quiet -print_format json -show_format -show_streams '.$src_path;
  94. $format = shell_exec($format_command);
  95. $json = json_decode($format);
  96. $audio = '';$video = '';
  97. foreach($json->streams as $row){
  98. if($row->codec_type=='video'){
  99. $arr['video'] = $row->codec_name;
  100. $arr['duration'] = $row->duration;
  101. $arr['width'] = $row->width;
  102. $arr['height'] = $row->height;
  103. $arr['dis_ratio']= $row->display_aspect_ratio;
  104. }
  105. if($row->codec_type=='audio'){
  106. $arr['audio'] = $row->codec_name;
  107. }
  108. }
  109. if(empty($arr['duration'])) $arr['duration'] = $json->format->duration;
  110. $arr['size'] = $json->format->size;
  111. $arr['bit_rate'] = $json->format->bit_rate;
  112. $arr['ext'] = $json->format->format_name;
  113. return $arr;
  114. }
  115. //视频截图JPG
  116. function vodtojpg($src_path,$obj_path){
  117. if(Jpg_On==1) return 'no';
  118. mkdirss(dirname($obj_path));
  119. $Jpg_Size = Jpg_Size;
  120. $size = !empty($Jpg_Size)?'-s '.Jpg_Size:'';
  121. $filename = end(explode('/', $obj_path));
  122. if(strpos($filename,'[xu]') !== false){
  123. $jpg_path = str_replace('[xu]', '1', $obj_path);
  124. }else{
  125. $jpg_path = $obj_path;
  126. }
  127. $jpg_command = $this->ffmpeg.' -y -i '.$src_path.' -y -f image2 -ss '.Jpg_Time.' '.$size.' -t 0.001 '.$jpg_path;
  128. $jpg = exec($jpg_command,$arr,$log);
  129. //多张图
  130. if(Jpg_Num > 1){
  131. for($i=1;$i<Jpg_Num;$i++){
  132. $n = $i+1;
  133. if(strpos($obj_path, '[xu]') === false){
  134. $jpg_path2 = str_replace($filename, $n.'_'.$filename, $obj_path);
  135. }else{
  136. $jpg_path2 = str_replace('[xu]', $n, $obj_path);
  137. }
  138. $jpg_pos = Jpg_Time*$n;//截图时间点
  139. $jpg_command = $this->ffmpeg.' -y -i '.$src_path.' -y -f image2 -ss '.$jpg_pos.' '.$size.' -t 0.001 '.$jpg_path2;
  140. $jpg = exec($jpg_command,$arr,$log);
  141. }
  142. }
  143. if($log==0){
  144. return 'ok';
  145. }else{
  146. return 'no';
  147. }
  148. }
  149. //截取GIF
  150. function vodtogif($src_path,$obj_path){
  151. if(Gif_On==1) return 'no';
  152. mkdirss(dirname($obj_path));
  153. $gif_pos = Gif_Time;//开始位置
  154. $gif_len = Gif_Len;//截取时长
  155. $Gif_Size = Gif_Size;
  156. $size = !empty($Gif_Size)?'-s '.Gif_Size:'';
  157. if(strpos($obj_path,'[xu]') !== false){
  158. $obj_path = str_replace('[xu]', '1', $obj_path);
  159. }
  160. $gif_command = $this->ffmpeg.' -y -ss '.$gif_pos.' -t '.$gif_len.' -i '.$src_path.' '.$size.' -f gif '.$obj_path;
  161. $gif = exec($gif_command,$arr,$log);
  162. if($log==0){
  163. return 'ok';
  164. }else{
  165. return $gif_command;
  166. }
  167. }
  168. //水印OR字幕
  169. function watermark_zm(){
  170. $cmd = '';
  171. //左上
  172. if(Wm_On == 1){
  173. $cmd = '-vf "movie='.$this->sypath.'.png[wm1];[in][wm1]overlay='.Wm_Lt.'[out]"';
  174. }
  175. //右上
  176. if(Wm_On2 == 1){
  177. $mar_arr = explode(':', Wm_Lt2);
  178. $mar1 = intval($mar_arr[0]);
  179. $mar2 = intval($mar_arr[1]);
  180. $wm = 'overlay=main_w-overlay_w-'.$mar1.':'.$mar2;
  181. if(empty($cmd)){
  182. $cmd = '-vf "movie='.$this->sypath.'2.png[wm2];[in][wm2]'.$wm.'[out]"';
  183. }else{
  184. $cmd = str_replace('[in]', 'movie='.$this->sypath.'2.png[wm2];[in][wm2]'.$wm.'[a];[a]', $cmd);
  185. }
  186. }
  187. //左下
  188. if(Wm_On3 == 1){
  189. $mar_arr = explode(':', Wm_Lt3);
  190. $mar1 = intval($mar_arr[0]);
  191. $mar2 = intval($mar_arr[1]);
  192. $wm = 'overlay='.$mar1.':main_h-overlay_h-'.$mar2;
  193. if(empty($cmd)){
  194. $cmd = '-vf "movie='.$this->sypath.'3.png[wm3];[in][wm3]'.$wm.'[out]"';
  195. }else{
  196. $cmd = str_replace('[in]', 'movie='.$this->sypath.'3.png[wm3];[in][wm3]'.$wm.'[b];[b]', $cmd);
  197. }
  198. }
  199. //右下
  200. if(Wm_On4 == 1){
  201. $mar_arr = explode(':', Wm_Lt4);
  202. $mar1 = intval($mar_arr[0]);
  203. $mar2 = intval($mar_arr[1]);
  204. $wm = 'overlay=main_w-overlay_w-'.$mar1.':main_h-overlay_h-'.$mar2;
  205. if(empty($cmd)){
  206. $cmd = '-vf "movie='.$this->sypath.'4.png[wm4];[in][wm4]'.$wm.'[out]"';
  207. }else{
  208. $cmd = str_replace('[in]', 'movie='.$this->sypath.'4.png[wm4];[in][wm4]'.$wm.'[c];[c]', $cmd);
  209. }
  210. }
  211. if(Wm_Zm == 1){
  212. if(empty($cmd)){
  213. $cmd = '-vf "ass='.$this->zmpath.'"';
  214. }else{
  215. $cmd = str_replace('[in]', 'ass='.$this->zmpath.'[asub];[asub]', $cmd);
  216. }
  217. }
  218. return $cmd;
  219. }
  220. //m3u8加密
  221. function m3u8aes($path){
  222. if(Mu_On == 1) return '';
  223. $src_str = '0123456789abcdefghijklmnopqrstuvwxyz';
  224. $aes_key = substr(str_shuffle($src_str), 0, 16);
  225. if(substr($path, -1)!='/') $path .= '/';
  226. if(!is_dir($path)) mkdir($path,0777,true);
  227. $fp =fopen($path.'key.key', 'w');
  228. fwrite($fp, $aes_key);
  229. fclose($fp);
  230. $keyinfo = "key.key\n".$path."key.key";
  231. $fp = fopen($path.'key_info', 'w');
  232. fwrite($fp, $keyinfo);
  233. fclose($fp);
  234. return '-hls_key_info_file '.$path.'key_info';
  235. }
  236. }