话不多说 上代码 各位看官 参考吧
require 'vedio.ext.php'; $file = '文件地址 绝对路径'; $video = new videoExt(); $file_info = pathinfo($file); $video_id = $file_info['filename']; // 视频名作为视频的id $tmp_dir = ''; // 切片的临时目录绝对路径 if (!file_exists($tmp_dir)) { mkdir($tmp_dir, 0777, true); } //如果临时目录不为空,清空目录 $tmp_dir_files = scandir($tmp_dir); $tmp_dir_files = array_diff($tmp_dir_files, ['..', '.']); if (!empty($tmp_dir_files)) { foreach ($tmp_dir_files as $key => $tmp_file) { unlink($tmp_dir . $tmp_file); } } $compressed_video = $tmp_dir.$video_id.'.mp4'; // 压缩后的视频 $video->compress($file, $compressed_video); // 压缩视频
// ts文件的远程存放地址 $remote_url = $tmp_dir.$video_id; $remote_preview_url = $tmp_dir.$video_id.DIRECTORY_SEPARATOR.'auto'; $duration = $video->get_duration($compressed_video); // 获取视频时长 $video_cover = $video->get_cover($compressed_video, 5, $tmp_dir); // 获取视频图片 // 切片 $m3u8_file = $video->m3u8($compressed_video, 5, $remote_url, $tmp_dir); // 视频切片
unlink($video_cover);
unlink($m3u8_file);
// 生成5分钟预览 $preview_m3u8_file = $video->m3u8($compressed_video, 5, $remote_preview_url, $tmp_dir, 30);
vedio.ext.php 文件
<?php /* * 视频扩展类, 该类主要用于下载视频, 处理视频(获取视频信息, 压缩, 合并, 切片, 截屏等)操作 */ class videoExt { /** * 断点下载远程文件 * @param string $remote_file 远程文件url, 如 http://video.sanhao.com/video/opencourse/204/204.mp4 * @param string $local_dir 本地路径, 如 /usr/share/nginx/html/php_services/data/video_slice/ * @param string $filename 文件名, 如 212.mp4 * @return bool * @throws Exception */ public function download($remote_file, $local_dir, $filename) { if (!file_exists($local_dir)) { mkdir($local_dir, 0777, true); } try { $remote_file_pointer = fopen($remote_file, 'rb'); $local_file_pointer = fopen($local_dir . $filename, 'wb'); while (!feof($remote_file_pointer)) { $tmp = fread($remote_file_pointer, 8192); // 每次下载8M fwrite($local_file_pointer, $tmp); } fclose($remote_file_pointer); fclose($local_file_pointer); return true; } catch (Exception $e) { throw new Exception($e->getMessage(), $e->getCode()); } } /** * 获取视频长度,单位为秒 * @param string $filename 视频文件的绝对路径, 如/usr/share/nginx/html/data/video_slice/212.mp4 * @return int $time */ public function get_duration($filename) { $cmd = 'ffmpeg -i ' . $filename . ' 2>&1 | grep \'Duration\' | cut -d \' \' -f 4 | sed s/,//'; $content = exec($cmd); if (!$content || $content == '') return 0; $tmp = explode(':', $content); $time = $tmp[0] * 3600 + $tmp[1] * 60 + intval($tmp[2]); return $time; } /** * 生成视频略缩图, 默认取第5秒, 返回略缩图的绝对路径 * @param string $filename 文件的绝对路径 * @param int $time 截取时间 * @param string $dist_dir 缩略图的绝对存储路径 * @return string */ public function get_cover($filename, $time = 5, $dist_dir) { $file_info = pathinfo($filename); $cover_file = $dist_dir . $file_info['filename'] . '.jpg'; exec("ffmpeg -i " . $filename . " -y -f mjpeg -ss " . $time . " -t 0.001 " . $cover_file . ""); return $cover_file; } /** * 压缩视频, 减少视频体积 * @param string $filename 文件的绝对路径 * @param string $new_filename 压缩文件的绝对路径 */ public function compress($filename, $new_filename) { $cmd = 'ffmpeg -i ' . $filename . ' -c:v libx264 -crf 18 ' . $new_filename; exec($cmd); } /** * 视频切片, 默认切片大小为5秒, 返回m3u8文件的绝对路径 * @param string $filename 文件的绝对路径 * @param int $interval 切片长度 * @param string $remote_url 远程访问地址, 只到目录层, * 如完整路径为 http://video.sanhao.com/dev/record/204/204-001.ts * 那么$remote_url为 http://video.sanhao.com/dev/record/204/ * @param string $dist_dir 本地存储ts文件和m3u8文件的绝对路径 * @param int $duration 总切片长度,单位秒 * @return string */ // public function m3u8($filename, $interval = 5, $remote_url, $dist_dir){ // $file_info = pathinfo($filename); // $transfer_ts_file = $dist_dir . $file_info['filename'] .'.ts'; // $m3u8_file = $dist_dir . $file_info['filename'] .'.m3u8'; // $cmd = 'ffmpeg -i '. $filename . ' -vcodec libx264 -crf 18 '. $transfer_ts_file; // $rs = exec($cmd); // // $cmd = 'ffmpeg -i '. $transfer_ts_file .' -c copy -map 0 -f segment -segment_list '. $m3u8_file; // $cmd .= ' -segment_time '. $interval .' -segment_list_entry_prefix '. $remote_url . ' '; // $cmd .= $dist_dir . $file_info['filename'] .'-%03d.ts'; // $rs = exec($cmd); // @unlink($transfer_ts_file); // return $m3u8_file; // } public function m3u8($filename, $interval = 5, $remote_url, $dist_dir, $duration = 0) { $file_info = pathinfo($filename); $m3u8_file = $dist_dir . $file_info['filename'] . '.m3u8'; $cmd = 'ffmpeg '; if ($duration > 0) { $time = $this->seconds2time($duration); $cmd .= '-ss 0 -t '.$time.' '; } $cmd .= '-i ' . $filename . ' -c copy -map 0 -f segment -segment_list ' . $m3u8_file; $cmd .= ' -segment_time ' . $interval . ' -segment_list_entry_prefix ' . $remote_url . ' '; $cmd .= $dist_dir . $file_info['filename'] . '-%03d.ts'; $rs = exec($cmd); return $m3u8_file; } /** * 把秒数转换为时分秒的格式 * @param int $times 秒数 * @return string 时分秒字符串 */ public function seconds2time($times) { $result = '00:00:00'; if ($times > 0) { $hour = floor($times / 3600); $minute = floor(($times - 3600 * $hour) / 60); $second = floor((($times - 3600 * $hour) - 60 * $minute) % 60); $result = $hour . ':' . $minute . ':' . $second; } return $result; } }
ffmpeg操作类
<?php /* * ffmpeg操作类 */ class ffmpeg{ //视频长度 public static function len($room_no, $name){ $cmd = 'ffmpeg -i '.DATA.$room_no.DIRECTORY_SEPARATOR.$name.'.mp4 2>&1 | grep \'Duration\' | cut -d \' \' -f 4 | sed s/,//'; // var_dump($cmd); $content = exec($cmd); if(!$content || $content == '') return 0; $tmp = explode(':', $content); $time = $tmp[0]*3600 + $tmp[1]*60 + intval($tmp[2]); return $time; } //视频复制 public static function copy($room_no, $name, $file){ $cmd = 'ffmpeg -i '.$file.' -s 320*240 '.DATA.$room_no.DIRECTORY_SEPARATOR.$name.'.mp4'; // SayTool::log($cmd); return exec($cmd); } //视频删除 public static function rm($room_no, $name){ return unlink(DATA.$room_no.DIRECTORY_SEPARATOR.$name.'.mp4'); } //视频切片 public static function m3u8($room_no){ $room_id = str_replace('sanhao', '', $room_no); //转换成ts $cmd = 'ffmpeg -i '.DATA.$room_no.DIRECTORY_SEPARATOR.$room_no.'.mp4 -vcodec libx264 '.DATA.$room_no.DIRECTORY_SEPARATOR.$room_no.'.ts'; var_dump($cmd); $rs = exec($cmd); //切片视频 $cmd = 'segmenter -i '.DATA.$room_no.DIRECTORY_SEPARATOR.$room_no.'.ts -d 10 -p '.DATA.$room_no.DIRECTORY_SEPARATOR.'m3u8/video -m '.DATA.$room_no.DIRECTORY_SEPARATOR.$room_id.'.m3u8 -u http://video.sanhao.com/record/'; var_dump($cmd); $rs = exec($cmd); } }