话不多说 上代码 各位看官 参考吧
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);
}
}