Video.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. <?php
  2. defined('BASEPATH') OR exit('No direct script access allowed');
  3. class Video extends CI_Controller {
  4. function __construct(){
  5. parent::__construct();
  6. $this->load->database();
  7. }
  8. //视频列表
  9. public function index(){
  10. $this->load->model('User');
  11. $this->User->Login();
  12. $page = intval($this->input->get_post('page',true));
  13. $page = $page<1?1:$page;
  14. $per_page = 16;
  15. $where = array();
  16. $key = $this->input->get_post('key',true);
  17. $sid = intval($this->input->get_post('sid'));
  18. $cid = intval($this->input->get_post('cid'));
  19. $kstime = $this->input->get_post('kstime',true);
  20. $jstime = $this->input->get_post('jstime',true);
  21. if(!empty($key)) $where['name'] = " like '%".$key."%'";
  22. if($sid>0) $where['sid='] = $sid-1;
  23. if($cid>0) $where['cid='] = $cid;
  24. if(!empty($kstime)) $where['addtime>'] = strtotime($kstime)-1;
  25. if(!empty($jstime)) $where['addtime<'] = strtotime($jstime)+86400;
  26. $where_str = '';
  27. foreach ($where as $key1 => $value) {
  28. if(empty($where_str)){
  29. $where_str .= 'where '.$key1.$value;
  30. }else{
  31. $where_str .= ' and '.$key1.$value;
  32. }
  33. }
  34. $sel_sql = "select * from ".CS_SqlPrefix."video ".$where_str." order by id desc";
  35. $tol_sql = "select count(*) as count from ".CS_SqlPrefix."video ".$where_str;
  36. $total_res = $this->db->query($tol_sql)->row();
  37. $total = $total_res->count;
  38. $totalPages = ceil($total / $per_page)?ceil($total / $per_page):1; // 总页数
  39. $page = ($page>$totalPages)?$totalPages:$page;
  40. $data['nums'] = $total;
  41. if($total<$per_page){
  42. $per_page = $total;
  43. }
  44. $sel_sql .= ' limit '. $per_page*($page-1) .','. $per_page;
  45. $data['video'] = $this->db->query($sel_sql)->result();
  46. $data['vlist'] = $this->db->query("select * from ".CS_SqlPrefix."class order by id asc")->result();
  47. $base_url = site_url('video')."?key=".$key."&sid=".$sid."&cid=".$cid."&kstime=".$kstime."&jstime=".$jstime."&page=";
  48. $data['page_data'] = page_data($total,$page,$totalPages); //获取分页类
  49. $data['page_list'] = admin_page($base_url,$page,$totalPages); //获取分页类
  50. $data['page'] = $page;
  51. $data['sid'] = $sid;
  52. $data['cid'] = $cid;
  53. $data['key'] = $key;
  54. $data['kstime'] = $kstime;
  55. $data['jstime'] = $jstime;
  56. $this->load->view('video.html',$data);
  57. }
  58. //视频详细
  59. public function show($id){
  60. $this->load->model('User');
  61. $this->User->Login();
  62. $id = intval($id);
  63. if($id<1) exit('参数不正确');
  64. $vod = $this->db->query("select * from ".CS_SqlPrefix."video where id=".$id)->row();
  65. $data['vod'] = $vod;
  66. //兼容ppvod平台转移过来的数据
  67. if(!empty($vod->path) && substr($vod->path,-5) == '.m3u8'){
  68. $parr = explode('/', $vod->path);
  69. $len = count($parr)-1;
  70. unset($parr[$len]);
  71. $path = implode('/',array_filter($parr));
  72. $vodpath = $path.'/index.m3u8';
  73. $picpath = $path.'/1.jpg';
  74. $gifpath = $path.'/1.gif';
  75. $data['m3u8url'] = m3u8_link($vodpath);
  76. $data['gifurl'] = m3u8_link($gifpath,'gif');
  77. $picurl = m3u8_link($picpath,'jpg');
  78. }else{
  79. if(empty($vod->pic)){
  80. $vodpath = m3u8_dir($vod->id,$vod->addtime,'m3u8',1);
  81. $picpath = m3u8_dir($vod->id,$vod->addtime,'jpg',1);
  82. $gifpath = m3u8_dir($vod->id,$vod->addtime,'gif',1);
  83. $data['m3u8url'] = m3u8_link($vodpath);
  84. $data['gifurl'] = m3u8_link($gifpath,'gif');
  85. $picurl = m3u8_link($picpath,'jpg');
  86. $data['pic']['jpgurl'] = m3u8_link($picpath,'jpg');
  87. for($i=1;$i<Jpg_Num;$i++){
  88. $data['pic']['jpgurl_'.$i] = m3u8_link($picpath,'jpg',($i+1));
  89. }
  90. }else{
  91. $data['m3u8url'] = m3u8_link($vod->m3u8);
  92. if(Mu_Type == 1){
  93. $data['m3u8url2'] = m3u8_link($vod->m3u8,'m3u8',Mu_Kbps2);
  94. }
  95. $data['gifurl'] = m3u8_link($vod->pic,'gif');
  96. $data['pic']['jpgurl'] = m3u8_link($vod->pic,'jpg');
  97. for($i=1;$i<Jpg_Num;$i++){
  98. $data['pic']['jpgurl_'.$i] = m3u8_link($vod->pic,'jpg',($i+1));
  99. }
  100. }
  101. }
  102. $data['playurl'] = 'http://'.Web_Url.links('play/'.$id);
  103. $this->load->view('show.html',$data);
  104. }
  105. //删除视频
  106. public function del(){
  107. $this->load->model('User');
  108. $this->User->Login();
  109. $ids = $this->input->get_post('id');
  110. if(is_array($ids)){
  111. if(sizeof($ids)<1) getjson('请选择要删除的文件');
  112. foreach ($ids as $key => $value) {
  113. $id = intval($value);
  114. if($id<1) continue;
  115. $row = $this->db->query("select * from ".CS_SqlPrefix."video where id=".$id)->row();
  116. if(!$row) continue;
  117. $this->db->delete('video',array('id'=>$id));
  118. //删除队列
  119. $this->db->delete('queue',array('vid'=>$id));
  120. //删除源文件
  121. unlink($row->path);
  122. //删除M3U8文件
  123. if(Video_M3u8On == 1){
  124. $m3u8path = empty($row->m3u8) ? m3u8_dir($row->id,$row->addtime,'m3u8',1) : $row->m3u8;
  125. $m3u8path = dirname($m3u8path);
  126. if(substr(Mu_Path,0,2) == './'){
  127. deldir(FCPATH.substr(Mu_Path,2).$m3u8path);
  128. }else{
  129. deldir(Mu_Path.$m3u8path);
  130. }
  131. $picpath = empty($row->pic) ? m3u8_dir($row->id,$row->addtime,'jpg',1) : $row->pic;
  132. $picpath = dirname($picpath);
  133. if(substr(Mu_Path,0,2) == './'){
  134. deldir(FCPATH.substr(Mu_Path,2).$picpath);
  135. }else{
  136. deldir(Mu_Path.$picpath);
  137. }
  138. }
  139. }
  140. }else{
  141. $id = intval($ids);
  142. $row = $this->db->query("select * from ".CS_SqlPrefix."video where id=".$id)->row();
  143. if($row){
  144. $this->db->delete('video',array('id'=>$id));
  145. //删除队列
  146. $this->db->delete('queue',array('vid'=>$id));
  147. //删除源文件
  148. unlink($row->path);
  149. //删除M3U8文件
  150. if(Video_M3u8On == 1){
  151. $m3u8path = empty($row->m3u8) ? m3u8_dir($row->id,$row->addtime,'m3u8',1) : $row->m3u8;
  152. $m3u8path = dirname($m3u8path);
  153. if(substr(Mu_Path,0,2) == './'){
  154. deldir(FCPATH.substr(Mu_Path,2).$m3u8path);
  155. }else{
  156. deldir(Mu_Path.$m3u8path);
  157. }
  158. $picpath = empty($row->pic) ? m3u8_dir($row->id,$row->addtime,'jpg',1) : $row->pic;
  159. $picpath = dirname($picpath);
  160. if(substr(Mu_Path,0,2) == './'){
  161. deldir(FCPATH.substr(Mu_Path,2).$picpath);
  162. }else{
  163. deldir(Mu_Path.$picpath);
  164. }
  165. }
  166. }
  167. }
  168. $info['url'] = site_url('video')."?v=".rand(0,999);
  169. getjson($info,0);
  170. }
  171. //查看转码状态
  172. /*
  173. *type : 0转换百分比,1转换成功下一个,2转换失败下一个
  174. *id : 当前id
  175. *nxid : 下一个ID,0表示没有下一个
  176. *pro: 百分比
  177. */
  178. public function getpro(){
  179. //M3U8保存目录
  180. $m3u8_dir = substr(Mu_Path,0,2) == './' ? FCPATH.substr(Mu_Path,2) : Mu_Path;
  181. $v = $this->input->get('v');
  182. $row = $this->db->query("select * from ".CS_SqlPrefix."queue order by id asc limit 1")->row();
  183. if(!$row){
  184. //进入待转码目录
  185. if($v == 'zm' && Mu_Dir != '' && is_dir(Mu_Dir)){
  186. if(substr(Video_Path,0,2) == './'){
  187. $Video_Path = FCPATH.substr(Video_Path,2);
  188. }else{
  189. $Video_Path = Video_Path;
  190. }
  191. $this->load->helper('file');
  192. $dirinfo = dir_file(Mu_Dir);
  193. if(!empty($dirinfo['file'])){
  194. $filename = $dirinfo['file'];
  195. $Mu_Dir = $dirinfo['dir'];
  196. if(substr($Mu_Dir,-1) != '') $Mu_Dir.='/';
  197. //定义允许上传的文件扩展名
  198. $ext_arr = array_filter(explode('|', Up_Ext));
  199. //判断文件后缀
  200. $file_ext = strtolower(trim(substr(strrchr($filename, '.'), 1)));
  201. if(in_array($file_ext, $ext_arr) == false) {
  202. unlink($Mu_Dir.$filename);
  203. exit('不支持的格式');
  204. }
  205. $video_name = safe_replace(str_replace('.'.$file_ext, '', iconv('gbk', 'utf-8',$filename)));
  206. $uploadStr = date('Y').'/'.date('m').'/'.date('d').'/';
  207. creatdir($Video_Path.$uploadStr); //创建目录
  208. $newname = date('YmdHis').rand(1111,9999).'.'.$file_ext;
  209. //video
  210. $data['name'] = $video_name;
  211. $data['path'] = $uploadStr.$newname;
  212. $data['addtime'] = time();
  213. //移动目录
  214. $res = rename($Mu_Dir.$filename,$Video_Path.$uploadStr.$newname);
  215. if($res){
  216. $this->load->library('xyz');
  217. $format = $this->xyz->format($Video_Path.$uploadStr.$newname);
  218. if(empty($format['size']) || empty($format['duration'])){
  219. rename($Video_Path.$uploadStr.$newname,$Mu_Dir.$filename);
  220. exit('ffmpeg error');
  221. }
  222. $data['duration'] = $format['duration'];
  223. $data['size'] = $format['size'];
  224. $data['md5'] = md5_file($Video_Path.$uploadStr.$newname);
  225. //判断歌曲是否存在
  226. $res = $this->db->query("select id from ".CS_SqlPrefix."video where name='".$video_name."'")->row();
  227. if(!$res){
  228. //判断分类是否存在
  229. $carr = explode('/',str_replace(Mu_Dir,'',$Mu_Dir));
  230. $cname = empty($carr[0]) ? $carr[1] : $carr[0];
  231. $cname = safe_replace(iconv('gbk','utf-8',$cname));
  232. if(!empty($cname)){
  233. $rec = $this->db->query("select id from ".CS_SqlPrefix."class where name='".$cname."'")->row();
  234. if($rec){
  235. $data['cid'] = $rec->id;
  236. }else{
  237. $arr2['name'] = $cname;
  238. $arr2['xid'] = 10;
  239. $this->db->insert("class",$arr2);
  240. $data['cid'] = $this->db->insert_id();
  241. }
  242. }
  243. //视频入库
  244. $this->db->insert("video",$data);
  245. $insert_id = $this->db->insert_id();
  246. //路径
  247. $time = time();
  248. $mpath = m3u8_dir($insert_id,$time);
  249. $ppath = m3u8_dir($insert_id,$time,'jpg');
  250. $gpath = m3u8_dir($insert_id,$time,'gif');
  251. $this->db->update('video',array('m3u8'=>$mpath,'pic'=>$ppath),array('id'=>$insert_id));
  252. //queue
  253. $queue['xu'] = 1;
  254. $queue['vid'] = $insert_id;
  255. $queue['jpg'] = $m3u8_dir.$ppath;
  256. $queue['gif'] = $m3u8_dir.$gpath;
  257. $queue['m3u8'] = $m3u8_dir.$mpath;
  258. $queue['path'] = $Video_Path.$uploadStr.$newname;
  259. $queue['duration'] = $format['duration'];
  260. $this->db->insert('queue',$queue);
  261. //多码率
  262. if(Mu_Type == 1){
  263. $ext = end(explode('/', $mpath));
  264. $queue['xu'] = 2;
  265. $queue['m3u8'] = $m3u8_dir.str_replace($ext, Mu_Kbps2.'/'.$ext, $mpath);
  266. $this->db->insert('queue',$queue);
  267. $queue['xu'] = 3;
  268. $queue['m3u8'] = $m3u8_dir.str_replace($ext, Mu_Kbps3.'/'.$ext, $mpath);
  269. $this->db->insert('queue',$queue);
  270. }
  271. }
  272. }
  273. }
  274. }
  275. getjson('视频全部转码完毕');
  276. }
  277. //默认返回数据
  278. $info['type'] = 0;
  279. $info['name'] = $row->name;
  280. $info['id'] = $row->id;
  281. $info['xu'] = $row->xu;
  282. $info['vid'] = $row->vid;
  283. $info['pro'] = 0;
  284. //判断是视频是否存在
  285. $vod = $this->db->query("select id,name,path,size,addtime from ".CS_SqlPrefix."video where id=".$row->vid)->row();
  286. //异常队列,视频不存在队列
  287. if(!$vod){
  288. $this->db->delete('queue',array('id'=>$row->id));//删除队列
  289. getjson($info,0);
  290. }
  291. $row->name = $vod->name;
  292. //判断转码是否完毕
  293. $m3u8_path = $row->m3u8;
  294. if(!file_exists($m3u8_path)){
  295. //失败了,进程还在,需要杀掉进程继续下一个转码
  296. if($row->addtime > 0){
  297. if($row->addtime+120 < time()){
  298. //杀掉进程
  299. $xt = php_uname();
  300. if(strpos($xt, 'Windows') !== false){
  301. exec('taskkill /im ffmpeg.exe /f');
  302. }else{
  303. exec('ps aux | grep "ffmpeg" | cut -c 9-15 | xargs kill -9');
  304. }
  305. if(Mu_Type == 0 || $row->xu == 2){
  306. $this->db->update('video',array('sid'=>2),array('id'=>$row->vid));
  307. }
  308. $this->db->delete('queue',array('id'=>$row->id));//删除队列
  309. $info['type'] = 2;
  310. $nxrow = $this->db->query("select id,vid from ".CS_SqlPrefix."queue order by id asc limit 1")->row();
  311. if($nxrow){
  312. $nxvod = $this->db->query("select name from ".CS_SqlPrefix."video where id=".$nxrow->vid)->row();
  313. $info['nxid'] = $nxrow->id;
  314. $info['nxvid'] = $nxrow->vid;
  315. $info['name'] = $nxvod->name;
  316. }else{
  317. $info['nxid'] = 0;
  318. $info['nxvid'] = 0;
  319. $info['name'] = '';
  320. }
  321. //发送失败API消息
  322. if(Mu_Type == 0 || $row->xu == 2) get_api('api',array('vid'=>$vod->id,'name'=>$vod->name,'code'=>2));
  323. }
  324. }else{
  325. $info['type'] = 1;
  326. $info['id'] = 0;
  327. $info['vid'] = 0;
  328. $info['nxid'] = $row->id;
  329. $info['nxvid'] = $row->vid;
  330. }
  331. getjson($info,0);
  332. }
  333. $m3u8_neir = file_get_contents($m3u8_path);
  334. if(strpos($m3u8_neir,'#EXT-X-ENDLIST')!==false){//转换完毕
  335. $this->db->update('video',array('sid'=>1),array('id'=>$row->vid));
  336. $this->db->delete('queue',array('id'=>$row->id));//删除队列
  337. $nxrow = $this->db->query("select id,vid from ".CS_SqlPrefix."queue order by id asc limit 1")->row();
  338. if($nxrow){
  339. $nxvod = $this->db->query("select name from ".CS_SqlPrefix."video where id=".$nxrow->vid)->row();
  340. $info['nxid'] = $nxrow->id;
  341. $info['nxvid'] = $nxrow->vid;
  342. $info['name'] = $nxvod->name;
  343. }else{
  344. $info['nxid'] = 0;
  345. $info['nxvid'] = 0;
  346. $info['name'] = '';
  347. }
  348. $info['type'] = 1;
  349. //删除源文件
  350. if(Video_SrcOn == 1){
  351. if(Mu_Type == 0 || $row->xu == 2){
  352. unlink($row->path);
  353. }
  354. }
  355. //发送转码完成API消息
  356. get_api('api',array('vid'=>$vod->id,'name'=>$vod->name,'code'=>1));
  357. }else{//转换中
  358. $xt = php_uname();
  359. if(strpos($xt, 'Windows') !== false){
  360. $jc = shell_exec('tasklist');
  361. }else{
  362. $jc = shell_exec('ps aux | less');
  363. }
  364. //这种情况是转码中,进程被结束了
  365. if(strpos($jc, 'ffmpeg') === false && $row->addtime > 0){
  366. if(strpos($m3u8_neir,'.ts') !== false){ //转码没完成,追加结束符
  367. $m3u8_neir .= "\r\n#EXT-X-ENDLIST";
  368. write_file($m3u8_path,$m3u8_neir);
  369. $type = 1;
  370. }else{
  371. $type = 2;
  372. }
  373. //改变状态
  374. $this->db->update('video',array('sid'=>$type),array('id'=>$row->vid));
  375. $this->db->delete('queue',array('id'=>$row->id));//删除队列
  376. $info['type'] = $type;
  377. $nxrow = $this->db->query("select id,vid from ".CS_SqlPrefix."queue order by id asc limit 1")->row();
  378. if($nxrow){
  379. $nxvod = $this->db->query("select name from ".CS_SqlPrefix."video where id=".$nxrow->vid)->row();
  380. $info['nxid'] = $nxrow->id;
  381. $info['nxvid'] = $nxrow->vid;
  382. $info['name'] = $nxvod->name;
  383. }else{
  384. $info['nxid'] = 0;
  385. $info['nxvid'] = 0;
  386. $info['name'] = '';
  387. }
  388. getjson($info,0);
  389. }
  390. $m3u8arr = explode("\n", $m3u8_neir);
  391. $oknum = intval($m3u8arr[count($m3u8arr)-2])+1;
  392. $allnum = ceil($row->duration/(Mu_Time+3));
  393. if($allnum<$oknum){
  394. $pro = 99.99;
  395. }else{
  396. $pro = round($oknum/$allnum*100,2);
  397. }
  398. $info['pro'] = $pro;
  399. }
  400. getjson($info,0);
  401. }
  402. //执行转码
  403. public function transcode(){
  404. $id = intval($this->input->get_post('id'));
  405. if($id < 1) exit('参数错误');
  406. $xt = php_uname();
  407. if(strpos($xt, 'Windows') !== false){
  408. $jc = shell_exec('tasklist');
  409. }else{
  410. $jc = shell_exec('ps aux | less');
  411. }
  412. if(strpos($jc, 'ffmpeg') !== false){
  413. exit('转码中...');
  414. }
  415. $exist = $this->db->query("select * from ".CS_SqlPrefix."queue where id=".$id)->row();
  416. if(!$exist) exit('no exist!');
  417. if(!file_exists($exist->path)){
  418. $this->db->update('video',array('sid'=>2),array('id'=>$exist->vid));
  419. $this->db->delete('queue',array('id'=>$id));//删除队列
  420. exit('视频源文件不存在');
  421. }
  422. //获取视频信息
  423. $vod = $this->db->query("select * from ".CS_SqlPrefix."video where id=".$exist->vid)->row();
  424. if(!$vod){
  425. $this->db->delete('queue',array('id'=>$id));//删除队列
  426. exit('视频不存在');
  427. }
  428. //发送api入库请求
  429. $add['code'] = 0;
  430. $add['vid'] = $vod->id;
  431. $add['cid'] = $vod->cid;
  432. $add['name'] = $vod->name;
  433. $add['size'] = formatsize($vod->size);
  434. $add['duration'] = formattime($vod->duration,1);
  435. //图片和M3U8地址
  436. $add['m3u8url'] = m3u8_link($exist->m3u8);
  437. $add['gifurl'] = m3u8_link($exist->gif,'gif');
  438. $add['jpgurl'] = m3u8_link($exist->jpg,'jpg');
  439. for($i=1;$i<Jpg_Num;$i++){
  440. $n = $i+1;
  441. $add['jpgurl_'.$n] = m3u8_link($exist->jpg,'jpg',$n);
  442. }
  443. $add['playurl'] = 'http://'.Web_Url.links('play/'.$exist->vid);
  444. $res = get_api('add',$add);
  445. //纪录开始转吗时间
  446. $this->db->update('queue',array('addtime'=>time()),array('id'=>$id));
  447. //码率2
  448. if($exist->xu == 2){
  449. define('KBPS', Mu_Kbps2);
  450. define('SIZE', Mu_Size2);
  451. $exist->jpg = '';
  452. $exist->gif = '';
  453. }
  454. //开始转码
  455. $this->load->library('xyz');
  456. $res = $this->xyz->transcode($exist->path,$exist->m3u8,$exist->jpg,$exist->gif);
  457. //把原始文件进行改回原名
  458. if(Video_SrcOn == 0){
  459. //判断多码率
  460. if(Mu_Type == 0 || $res == Mu_Kbps3){
  461. $file_ext = strtolower(trim(substr(strrchr($exist->path, '.'), 1)));
  462. $yname = end(explode('/',$exist->path));
  463. $xpath = str_replace($yname, iconv("UTF-8","GBK//IGNORE",$vod->name).'.'.$file_ext, $exist->path);
  464. rename($exist->path,$xpath);
  465. }
  466. }
  467. echo $res;
  468. }
  469. //同步
  470. public function tongbu(){
  471. $id = intval($this->input->get_post('id'));
  472. if($id < 1) exit('参数错误');
  473. $exist = $this->db->query("select * from ".CS_SqlPrefix."video where id=".$id)->row();
  474. if(!$exist) exit('视频不存在');
  475. //发送api入库请求
  476. $add['code'] = 0;
  477. $add['vid'] = $exist->id;
  478. $add['cid'] = $exist->cid;
  479. $add['name'] = $exist->name;
  480. $add['size'] = formatsize($exist->size);
  481. $add['duration'] = formattime($exist->duration,1);
  482. $add['m3u8url'] = m3u8_link($exist->m3u8);
  483. $add['gifurl'] = m3u8_link($exist->pic,'gif');
  484. $add['jpgurl'] = m3u8_link($exist->pic,'jpg');
  485. for($i=1;$i<Jpg_Num;$i++){
  486. $n = $i+1;
  487. $add['jpgurl_'.$n] = m3u8_link($picpath,'jpg',$n);
  488. }
  489. $add['playurl'] = 'http://'.Web_Url.links('play/'.$id);
  490. echo get_api('add',$add);
  491. }
  492. }