thinkphp5 获取视频gif,视频封面,视频帧数,视频信息
/**
* 替换视频地址
* @param $VideoUrl
* @return mixed
* @param
* @author huangpeng
* @Time 2018/11/27 19:55
*/
function changeVideoURL($VideoUrl){
$videoUrl1=str_replace("%2F","/",$VideoUrl); //视频路径
$videoUrl=str_replace("https://bucket.oss-cn-shenzhen.aliyuncs.com","http://video.***.com",$videoUrl1);
return $videoUrl;
}
/**
* @param $playTime
* @return string
* 简介: 把视频播放时长格式由“01:20:15”改为“90:00”格式
* @param:
* User: huangpeng
* Date: 2019/1/10
* Time: 17:09
*/
function video_play_time($playTime){
$times=strtotime($playTime);
$hour=date("H",$times); //获取小时
$minute=date("i",$times);//分钟
$second=date('s',$times); //秒
$minute=$minute+$hour*60;
if(strlen($minute)==1){
$minutes="0".$minute;
}else{
$minutes=$minute;
}
$res=$minutes.":".$second;
return $res;
}
/**
* 使用ffmpeg获取视频信息 (无法获取视频是否是竖屏还是横屏)
* @param String $file 视频文件
* @return Array
*/
function getVideoInfo($file){
ob_start();
passthru(sprintf(config('FFmpeg'), $file));
$video_info = ob_get_contents();
ob_end_clean();
// 使用输出缓冲,获取ffmpeg所有输出内容
$ret = array();
// Duration: 00:33:42.64, start: 0.000000, bitrate: 152 kb/s
if (preg_match("/Duration: (.*?), start: (.*?), bitrate: (\d*) kb\/s/", $video_info, $matches)){
$ret['duration'] = $matches[1]; // 视频长度
$duration = explode(':', $matches[1]);
$ret['seconds'] = $duration[0]*3600 + $duration[1]*60 + $duration[2]; // 转为秒数
$ret['start'] = $matches[2]; // 开始时间
$ret['bitrate'] = $matches[3]; // bitrate 码率 单位kb
}
// Stream #0:1(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 568x320, 747 kb/s, 29.98 fps, 29.97 tbr, 600 tbn, 1200 tbc (default)
if(preg_match("/Video: (.*?), (.*?),(.*?), (.*?)[,\s]/", $video_info, $matches)){
$ret['vcodec'] = $matches[1]; // 编码格式
$ret['vformat'] = $matches[2]; // 视频格式
// dump($ret);dump($matches['4']);
$n= list($width, $height) = explode('x', $matches[4]);
if(isset($n)){
$ret['resolution'] = $matches[4]; // 网页上传视频分辨率
$ret['width'] = $width;
$ret['height'] = $height;
}else{
$ret['resolution'] = $matches[4]; // 手机上传视频分辨率
$ret['width'] = $width;
$ret['height'] = $height;
}
}
//
// // Stream #0:0: Audio: cook (cook / 0x6B6F6F63), 22050 Hz, stereo, fltp, 32 kb/s
if(preg_match("/Audio: (.*), (\d*) Hz/", $video_info, $matches)){
$ret['acodec'] = $matches[1]; // 音频编码
$ret['asamplerate'] = $matches[2]; // 音频采样频率
}
if(isset($ret['seconds']) && isset($ret['start'])){
$ret['play_time'] = $ret['seconds'] + $ret['start']; // 实际播放时间
}
// $ret['size'] = filesize($file); // 视频文件大小
$ret['rotate']=system("ffmpeg -show_streams | grep rotate");
//获取视频截图
$ret['thumbImg']=getVideoCover($file, "",$ret['width'],$ret['height']);
$video_info = iconv('gbk','utf8', $video_info);
return array($ret, $video_info);
}
/**
* ffmpeg直接获取视频信息 全
* @param $video_file 视频地址
* @return array
* @param
* @author huangpeng
* @Time 2018/11/14 15:03
* # ffmpeg -i test.asf -vframes 30 -y -f gif a.gif #把视频的前30帧转换成一个Gif
*/
//获取视频信息
function get_videoInfo($video_file){
ob_start(); // 使用输出缓冲,获取ffmpeg所有输出内容
$str="ffprobe -v quiet -print_format json -show_format -show_streams -select_streams v ".$video_file;
system($str);
$jsonData=json_decode(ob_get_contents(),true);
ob_end_clean(); // 使用输出缓冲,清除ffmpeg所有输出内容
$res=[];
if($jsonData) {
$streams = $jsonData['streams'][0];
$res['width'] = $streams['width']; //宽度
$res['height'] = $streams['height']; //长度
$res['duration'] = gmstrftime('%H:%M:%S', $streams['duration']); //获取视频长度
$res['tagsCount'] = count($streams['tags']); //获取数量
$format = $jsonData['format'];
if ($res['tagsCount'] == 4) {
$res['rotate'] = $streams['tags']['rotate'];
$res['imgUrl'] = getVideoCover($video_file, '', $res['width'], $res['height']); //获取视频截图
} else {
$res['rotate'] = "";
$res['imgUrl'] = getVideoCover($video_file, '', $res['height'], $res['width']);//获取视频截图
}
$res['videoSize'] = sprintf("%.1f ", ($format['size'] / 1024 / 1000)) . "MB"; //获取视频大小
//获取gif
$res['videoGif'] = get_video_gif($video_file);
//获取webp格式动图
// $res['videoWebp']= get_videoWebp($video_file,"");
return $res;
}else{
return false;
}
}
/*
* 获得视频文件的缩略图
* @file 视频地址
* ,url 缩略图地址
* */
function getVideoCover($file, $time,$width=0,$height=0)
{
$sveFile=ROOT_PATH . 'public' . DS . 'uploads'. DS.'videoImg/' ;
$name=time().mt_rand().".png";
$time=$time?$time:'2';//默认截取第一秒第一帧
// $str=exec("/usr/local/ffmpeg/bin/ffmpeg -ss 10 -i ".$file." 2>&1 -y -f mjpeg -vframes 1 -s 352x240 ".$_SERVER['DOCUMENT_ROOT']."/MVC/include/img/b-%03d.jpg",$out,$status);
// ffmpeg -ss 5 -i http://face.***.com/test/mp4/2018-01-08-56.mp4 -vf rotate=0 -y -f mjpeg -vframes 1 -s 1242*699 /home/test/你的项目/public/uploads/videoImg/%3d.png
// $str= "ffmpeg -ss ".$time." -i ".$file." -y -f mjpeg -vframes 1 -s ".$width."*".$height.$sveFile.$name;
$str= "ffmpeg -ss ".$time." -i ".$file." -y -f mjpeg -vframes 1 -s ".$height."*".$width." ".$sveFile.$name;
$result = system($str);
$saveUrl=$sveFile.$name;
if(Request::instance()->domain()=="https://www.***.com"){
$fileUrl="Img/videoImg/"; //正式地址图片路径
}else{
$fileUrl="test/videoImg/"; //测试地址路径
}
vendor('aliyun.autoload');
$accessKeyId = "***";//去阿里云后台获取秘钥
$accessKeySecret = "***";//去阿里云后台获取秘钥
$endpoint = "oss-cn-shenzhen.aliyuncs.com";//你的阿里云OSS地址
$ossClient = new \OSS\OssClient($accessKeyId, $accessKeySecret, $endpoint);
$bucket = "***";//oss中的文件上传空间
$object = $fileUrl . $name;//想要保存文件的名称
$fname = 'http://face.***.com/' . ltrim($object, './');
try {
$ossClient->uploadFile($bucket, $object, $saveUrl);
if(file_exists($saveUrl)){
unlink($saveUrl);
}
} catch (OssException $e) {
printf($e->getMessage() . "\n");
return;
}
return $fname;
}
/**
* @param $videoUrl 视频地址
* @param $time gif截图
* @return string|void
* @throws \OSS\Core\OssException
* @param 制作调色板 根据调色板制作gif
* @author huangpeng
* @Time 2018/11/14 17:17
*/
function get_videoGif($videoUrl,$time='',$rotate=''){
$sveFile=ROOT_PATH . 'public' . DS . 'uploads'. DS.'videoGif/' ;
$gif=time().mt_rand().".gif";
$saveUrl=$sveFile.$gif;
$time=$time?$time:'3';//默认截取前3s
//ffmpeg -ss 5 -t 5 -i http://image.***.com/feiyiproject/mp4/2018-02-22/5a8e2f70a7df0.mp4 -f gif C:\Users\Alvin\Desktop\imags\4444.gif
//-s用于设定分辨率,-b:v设定视频比特率来压缩大小
//-ss 5 -t 3,从第2秒的地方开始,往后截取5秒钟, -r 用于设定帧数. 通常Gif有15帧左右就比较流畅了
// $str= "ffmpeg -i ".$videoUrl." -vframes ".$time." -y -f gif ".$sveFile.$name;
//使用filter实现宽高减半显示: -vf scale=iw/2:ih/2
//-filter_complex 或 -lavfi
//先制作调色板:
$png=time().mt_rand().".png";
$savePng=$sveFile.$png;
$filters = 'fps=15,scale=-1:281:flags=lanczos';
$colorBlockPng="ffmpeg -v warning -ss 5 -t 3 -i ".$videoUrl." -vf ".$filters.",palettegen -b:v 1300k -bufsize 1300k -maxrate 1500k -r 15 -y ".$savePng;
$resPng=system($colorBlockPng,$status);
if($status==0){
if($_SERVER['HTTP_HOST'] !="www.api.com"){
$str="ffmpeg -v warning -ss 5 -t 3 -i ".$videoUrl." -i ".$savePng." -filter_complex 'fps=15,scale=-1:281:flags=lanczos[x];[x][1:v]paletteuse' -b:v 1300k -bufsize 1300k -maxrate 1500k -r 15 -y ".$saveUrl;
}else{
$str="ffmpeg -v warning -ss 5 -t 3 -i ".$videoUrl." -i ".$savePng." -filter_complex fps=15,scale=-1:281:flags=lanczos[x];[x][1:v]paletteuse -b:v 1300k -bufsize 1300k -maxrate 1500k -r 15 -y ".$saveUrl;
}
$result = system($str." 2>&1",$resStatus);
if($resStatus==0){
if(Request::instance()->domain()=="https://www.***.com"){
$fileUrl="gif/videoGif/"; //正式地址图片路径
}else{
$fileUrl="test/videoGif/"; //测试地址路径
}
vendor('aliyun.autoload');
$accessKeyId = "***";//去阿里云后台获取秘钥
$accessKeySecret = "***";//去阿里云后台获取秘钥
$endpoint = "oss-cn-shenzhen.aliyuncs.com";//你的阿里云OSS地址
$ossClient = new \OSS\OssClient($accessKeyId, $accessKeySecret, $endpoint);
$bucket = "***";//oss中的文件上传空间
$object = $fileUrl . $gif;//想要保存文件的名称
$fname = 'http://image.***.com/' . ltrim($object, './');
try {
if(file_exists($saveUrl) && file_exists($savePng)){
$ossClient->uploadFile($bucket, $object, $saveUrl);
unlink($saveUrl); unlink($savePng);
}
} catch (OssException $e) {
printf($e->getMessage() . "\n");
return;
}
return $fname;
}
}
// if($rotate==90){
// $str="ffmpeg -ss 5 -t 3 -i ".$videoUrl." -vf fps=15,scale=-1:281 -b:v 1000k -bufsize 1000k -maxrate 1500k -r 15 -y -f gif ".$sveFile.$name ;
// }elseif($rotate==180){
// //hflip 水平翻转
// //vflip 垂直翻转
// $str="ffmpeg -ss 5 -t ".$time." -i ".$videoUrl." -vf vflip,hflip -s 499x281 -b:v 1000k -bufsize 1000k -maxrate 1500k -r 15 -y -f gif ".$sveFile.$name ;
// }elseif($rotate==270) {
// $str="ffmpeg -ss 5 -t ".$time." -i ".$videoUrl." -vf transpose=1 -s 499x281 -b:v 1000k -bufsize 1000k -maxrate 1500k -r 15 -y -f gif ".$sveFile.$name ;
// }else {
// $str="ffmpeg -ss 5 -t ".$time." -i ".$videoUrl." -s 499x281 -b:v 1000k -bufsize 1000k -maxrate 1500k -r 15 -y -f gif ".$sveFile.$name ;
// }
}
/**
* @param $videoUrl
* @return string|void
* @简介: 省略调色板制作gif
* @param
* @param
* @author huangpeng
* @Time 2018/12/19 10:54
*/
function get_video_gif($videoUrl){
$sveFile=ROOT_PATH . 'public' . DS . 'uploads'. DS.'videoGif/' ;
$gif=time().mt_rand().".gif";
$saveUrl=$sveFile.$gif;
$time=3;//默认截取前3s
//ffmpeg -ss 5 -t 5 -i http://image.***.com/feiyiproject/mp4/2018-02-22/5a8e2f70a7df0.mp4 -f gif C:\Users\Alvin\Desktop\imags\4444.gif
//-s用于设定分辨率,-b:v设定视频比特率来压缩大小
//-ss 5 -t 3,从第2秒的地方开始,往后截取5秒钟, -r 用于设定帧数. 通常Gif有15帧左右就比较流畅了
// $str= "ffmpeg -i ".$videoUrl." -vframes ".$time." -y -f gif ".$sveFile.$name;
//使用filter实现宽高减半显示: -vf scale=iw/2:ih/2
//-filter_complex 或 -lavfi
//system($str." 2>&1",$Status);查看信息
if($_SERVER['HTTP_HOST'] !="www.api.com"){
$str='ffmpeg -y -ss 5 -t 3 -i '.$videoUrl.' -filter_complex "fps=10,scale=-1:281:flags=lanczos[x];[x]split[x1][x2];[x1]palettegen[p];[x2][p]paletteuse=dither=none" '.$saveUrl;
}else{
$str='ffmpeg -y -ss 5 -t 3 -i '.$videoUrl.' -filter_complex "fps=10,scale=-1:281:flags=lanczos[x];[x]split[x1][x2];[x1]palettegen[p];[x2][p]paletteuse=dither=none" '.$saveUrl;
}
$result = system($str,$Status);
if($Status==0){
if(Request::instance()->domain()=="https://www.***.com"){
$fileUrl="gif/videoGif/"; //正式地址图片路径
}else{
$fileUrl="test/videoGif/"; //测试地址路径
}
vendor('aliyun.autoload');
$accessKeyId = "***";//去阿里云后台获取秘钥
$accessKeySecret = "***";//去阿里云后台获取秘钥
$endpoint = "oss-cn-shenzhen.aliyuncs.com";//你的阿里云OSS地址
$ossClient = new \OSS\OssClient($accessKeyId, $accessKeySecret, $endpoint);
$bucket = "9doke";//oss中的文件上传空间
$object = $fileUrl . $gif;//想要保存文件的名称
$fname = 'http://image.***.com/' . ltrim($object, './');
try {
if(file_exists($saveUrl)){
$ossClient->uploadFile($bucket, $object, $saveUrl);
unlink($saveUrl);
}
} catch (OssException $e) {
printf($e->getMessage() . "\n");
return;
}
return $fname;
}
}
/**
* 制作webp格式动图
* @param $videoUrl
* @param $time
* @return string|void
* @throws \OSS\Core\OssException
* @param
* @author huangpeng
* @Time 2018/11/15 10:24
*/
function get_videoWebp($videoUrl,$time){
$sveFile=ROOT_PATH . 'public' . DS . 'uploads'. DS.'videoGif/' ;
$name=time().mt_rand(0,99).".webp";
$time=$time?:0; //开始时间
$str= "ffmpeg -i ".$videoUrl." -ss ".$time." -t 3 -vcodec libwebp -lossless 0 -q:v 20 -vf scale=iw/2:ih/2 -preset default -loop 0 -an -vsync 0 ".$sveFile.$name;
// $str="ffmpeg -i".$videoUrl."-vf scale=240:-1 -r 10 -lossless 1 -loop 0 -y ".$sveFile.$name;
$result = system($str);
$saveUrl=$sveFile.$name;
if(Request::instance()->domain()=="https://www.***.com"){
$fileUrl="gif/videoGif/"; //正式地址图片路径
}else{
$fileUrl="test/videoGif/"; //测试地址路径
}
vendor('aliyun.autoload');
$accessKeyId = "***";//去阿里云后台获取秘钥
$accessKeySecret = "***";//去阿里云后台获取秘钥
$endpoint = "oss-cn-shenzhen.aliyuncs.com";//你的阿里云OSS地址
$ossClient = new \OSS\OssClient($accessKeyId, $accessKeySecret, $endpoint);
$bucket = "***";//oss中的文件上传空间
$object = $fileUrl . $name;//想要保存文件的名称
$fname = 'http://image.***.com/' . ltrim($object, './');
try {
$ossClient->uploadFile($bucket, $object, $saveUrl);
if(file_exists($saveUrl)){
unlink($saveUrl);
}
} catch (OssException $e) {
printf($e->getMessage() . "\n");
return;
}
return $fname;
}
//获取视频大小
function getVideoSize($video){
$size=sprintf( "%.1f ",($video['size']/1024/1000))."MB";
return $size;
}
//获得视频文件的总长度时间和创建时间
function getVideoTime($file)
{
$vtime = exec("ffmpeg -i " . $file . " 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//");//CuPlayer.com 总长度
// $ctime = date("Y-m-d H:i:s",filectime($file));//创建时间
//$duration = explode(":",$time);
// $duration_in_seconds = $duration[0]*3600 + $duration[1]*60+ round($duration[2]);//CuPlayer.com 转化为秒
return $vtime;
}