php如何截取出视频中的指定帧作为图片

一、总结

一句话总结:截取视频指定帧为图片,php ffmpeg扩展已经完美实现,并且php ffmpeg是开源的

二、php如何截取出视频中的指定帧作为图片

截取视频指定帧为图片,php ffmpeg扩展已经完美实现:

1
2
3
4
5
6
$movie = new ffmpeg_movie( $video_filePath );
$ff_frame = $movie ->getFrame(1);
$gd_image = $ff_frame ->toGDImage();
$img = "./test.jpg" ;
imagejpeg( $gd_image , $img );
imagedestroy( $gd_image );

然而问题来了,智能手机拍摄的视频,由于拍摄方向不同,视频会被旋转,并带上meta信息rotate,当你相对视频截取frame图片的时候,如果有rotate信息的视频,frame也是旋转的,因此你需要将截取的图片相应的旋转。

然后php ffmpeg扩展并无法获知rotation信息(php ffmpeg扩展文档),但可以通过ffmpeg命令行获取:

/usr/local/ffmpeg/bin/ffprobe test.mp4 -show_streams  | grep rotate
用php简单封装下如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function get_video_orientation( $video_path ) {
   $cmd = "/usr/local/ffmpeg/bin/ffprobe " . $video_path . " -show_streams 2>/dev/null" ;
   $result = shell_exec( $cmd );
   
   $orientation = 0;
   if ( strpos ( $result , 'TAG:rotate' ) !== FALSE) {
     $result = explode ( "\n" , $result );
     foreach ( $result as $line ) {
       if ( strpos ( $line , 'TAG:rotate' ) !== FALSE) {
         $stream_info = explode ( "=" , $line );
         $orientation = $stream_info [1];
       }
     }
   }
   return $orientation ;
}

使用imagerotate()函数就可以旋转截图:

1
2
3
4
5
6
7
8
9
$movie = new ffmpeg_movie( $video_filePath );
$frame = $movie ->getFrame(1);
$gd = $frame ->toGDImage();
if ( $orientation = $this ->get_video_orientation( $video_filePath )) {
   $gd = imagerotate( $gd , 360- $orientation , 0);
}
$img = "./test.jpg" ;
imagejpeg( $gd , $img );
imagedestroy( $gd_image );

最后还有一个麻烦事,不是所有的播放器和浏览器都可对video识别orientation并自动rotate,如果你想对视频进行旋转,可通过ffmpeg命令解决:

/usr/local/ffmpeg/bin/ffmpeg -i input.mp4 -vf 'transpose=3' -metadata:s:v:0 rotate=0

参考:php截取视频指定帧为图片_php技巧_脚本之家
https://www.jb51.net/article/84359.htm

三、ffmpeg-php扩展

php视频缩略图,较常用的是ffmpeg-php

1: 安装 ffmpeg

ffmpeg的下载链接  http://ffmpeg.org/download.html

解压安装包

tar -jxvf ffmpeg-x.x.tar.bz2

进入目录

cd ffmpeg-x.x

编译安装

./configure --enable-shared && make && make install

安装完成之后 执行 ffmpeg -version

如果能够出现类似下列信息,说明ffmpeg安装成功。

ffmpeg version 2.5.11 Copyright (c) 2000-2016 the FFmpeg developers
built on Apr 17 2017 16:47:15 with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-11)
configuration: --enable-shared
libavutil      54. 15.100 / 54. 15.100
libavcodec     56. 13.100 / 56. 13.100
libavformat    56. 15.102 / 56. 15.102
libavdevice    56.  3.100 / 56.  3.100
libavfilter     5.  2.103 /  5.  2.103
libswscale      3.  1.101 /  3.  1.101
libswresample   1.  1.100 /  1.  1.100

 2 安装ffmpeg-php

官方的下载链接

https://sourceforge.net/projects/ffmpeg-php/files/ffmpeg-php/

官方版本已经很久很久不更新了,我在centos 7 + php5.6&php7.1   centos6.5+php5  试了都不行。在configure完 make的时候会报错。

后来在github上找了一个版本。在centos7.2+php5.5.6 上编译安装成功 (centos7 + php7.1还是不行)

地址:    git clone https://github.com/tony2001/ffmpeg-php.git

也可以访问我的百度云盘进行下载

https://pan.baidu.com/s/1skQTVlj

进入 ffmpeg-php目录 进行编译扩展

/usr/local/php/bin/phpize

./configure --with-php-config=/usr/local/php/bin/php-config

make && make install

注意(如果make之后出现错误,那就是ffmpeg-php版本的问题,别再折腾了,换版本吧(或者降低php版本试试))。

在php的配置文件 php.ini中 添加

extension=ffmpeg.so

重启php。在 phpinfo()中查看有无ffmpeg信息。

有的话就OK

或者执行

/usr/local/php/bin/php -i |grep ffmpeg

 要是有输出的话OK

参考:ffmpeg-php扩展 - 思此狂 - 博客园
https://www.cnblogs.com/jkklearn/p/6737467.html

二、PHP的ffmpeg使用

因为项目需求,同事写了一个ffmpeg的类,但是因为临时来了一个其他的项目,所以这个未完成的类就交给我来完成,所以我就把这个类的完成过程记录一下

<?php
include('FFmpegSupport.php');
//http://blog.csdn.net/doublefi123/article/details/24325159 基本用法
class FFmpegManage
{/*** ffmpeg默认结构:ffmpeg  [全局选项] [输入文件选项] -i (输入文件路径) [输出文件选项] (输出文件路径)* 其中[]括号里的是可选,()括号里的是必选的*/private $ExecString = 'ffmpeg.exe '; //命令语句private $GlobalOptions = ''; //全局选项private $ErrMessage = array(); //错误信息private $InputFileOptionsString = ''; //输入文件选项private $InputFileOptions = array(); //输入文件选项数组private $InputFilePath = array(); //输入文件路径private $OutFileOptions = ''; //输出文件选项private $OutFilePath = ''; //输出文件路径private $OutFileTybe = ''; //输入文件的后缀名//可配置参数private $config = array('startTime'=>1,        //文件开始时间'fmt'=>1,               //文件格式'codec'=>1,             //解码器'audioCodec'=>1,       //音频解码器'bitRate'=>1,           //比特率'sampleRate'=>1,        //采样率'audioChannels'=>1,    //声道数'endTime'=>1,           //结束时间'timeLength'=>1,        //文件时间长度);/**$Config = array('inputFilePath'            =>  array(),   //输入路径(不能为空)'outputFilePath'                => '',     //输出路径(不能为空)//输入文件选项(为空时不执行)'fileOption'        =>array('studyTime'             => '',               //文件开始时间'fmt'                    => '',              //文件格式'codec'                  => '',             //解码器'audioCodec'            => '',              //音频解码器'bitRate'               => '',              //比特率'sampleRate'            => '',              //采样率'audioChannels'         => '',             //声道数'endTime'                => '',            //结束时间'timeLength'             => '',            //文件时间长度),);**/public function setConfig($config){@$fileOption = $config['fileOption'];@$inputFilePath =  $config['inputFilePath'];@$outputFilePath =  $config['outputFilePath'];//判断是否有输入或输出路径if(empty($inputFilePath) && empty($outputFilePath)){$this->setErrMessage('inputFilePath and outputFilePath is null');}//获取输入文件路径if(!is_array($inputFilePath)){$filePathArray = explode('+',$inputFilePath);}else{$filePathArray = $inputFilePath;}if(!empty($fileOption))//遍历输入文件路径foreach($filePathArray as $filePath){//将配置信息进行遍历foreach($fileOption as $key => $value){//判断配置信息是否正确,如果不正确跳过if(!empty($this->config[$key]) && !empty($value)){//加载配置$this->$key($value);}}//判断文件是否能进行写入if( file_exists( $filePath ) ){//将输入配置与输入文件进行关联$this->InputFilePath[] = '-i ' . $filePath . ' ';$this->InputFileOptions[] = '-i ' . $filePath . ' '.$this->InputFileOptionsString;$this->InputFileOptionsString = '';}else{$this->setErrMessage('Input File is not Exist!!');}}$this->OutFileTybe = substr( $outputFilePath , -4 );$this->OutFilePath = $outputFilePath . ' ';return $this;}/*** 设置ffmpeg执行时对所有选项都回答yes,例文件已存在,要覆盖的时候程序会等待回答yes or on ,有时候不添加会出错* @return $this*/public function setAnswerAllYes(){$this->GlobalOptions .= ' -y ';return $this;}配置信息载入/*** 强制设定文件的格式,需要使用ffmpeg当前版本支持的名称(缺省使用扩展名称)* @param $_fileType String 文件类型*/private function fmt( $_fileType ){empty( $_fileType ) ?$this->setErrMessage( 'File Type is empty!!'):$this->InputFileOptionsString .= '-f ' . $_fileType . ' ';}/*** 设置输入文件的起始时间点,在此时间点开始读取数据 ,* @param $_time int 起始时间(单位:秒s)*/private function startTime( $_time ){$_time = (int)$_time;empty($_time) && ($_time < 0) ?$this->setErrMessage( " $_time must be biger than 0"):$this->InputFileOptionsString .= '-ss ' . $_time . ' ';}/*** 指定解码器,需输入此版本支持的解码器* @param $_codecName*/private function codec( $_codecName ){empty( \FFmpegSupport::$InputProtocolsArray[ $_codecName ] )  && empty( \FFmpegSupport::$OutputProtocolsArray[ $_codecName ] ) ?$this->setErrMessage( 'This versions ffmpeg is not support this codec!!' ):$this->InputFileOptionsString .= '-c ' . $_codecName . ' ';}/***指定音频解码器* @param $_audioCodecName String 解码器名称,需输入此版本ffmpeg支持的解码器*/private function audioCodec( $_audioCodecName ){empty( \FFmpegSupport::$InputProtocolsArray[ $_audioCodecName ] )  && empty( \FFmpegSupport::$OutputProtocolsArray[ $_audioCodecName ] ) ?$this->setErrMessage( 'This versions ffmpeg is not support this codec!!' ):$this->InputFileOptionsString .= '-acodec ' . $_audioCodecName . ' ';}/*** 设置音频流的采样率* 可以使用的采样率* 8,000 Hz - 电话所用采样率, 对于人的说话已经足够* 11,025 Hz* 22,050 Hz - 无线电广播所用采样率* 32,000 Hz - miniDV 数码视频 camcorder、DAT (LP mode)所用采样率* 44,100 Hz - 音频 CD, 也常用于 MPEG-1 音频(VCD, SVCD, MP3)所用采样率* 47,250 Hz - 商用 PCM 录音机所用采样率* 48,000 Hz - miniDV、数字电视、DVD、DAT、电影和专业音频所用的数字声音所用采样率* 50,000 Hz - 商用数字录音机所用采样率* 96,000 或者 192,000 Hz - DVD-Audio、一些 LPCM DVD 音轨、BD-ROM(蓝光盘)音轨、和 HD-DVD (高清晰度 DVD)音轨所用所用采样率* 2.8224 MHz - Direct Stream Digital 的 1 位 sigma-delta modulation 过程所用采样率。* @param $_audioSampleRate int 音频采样率,单位Hz*/private function sampleRate( $_audioSampleRate ){$_audioSampleRate < 1 ?$this->setErrMessage( 'AudioSampleRate can not smaller than 0!!'):$this->InputFileOptionsString .= '-ar ' . $_audioSampleRate . ' ';}/*** 设置音频流的比特率* @param $_audioBitRate int 音频比特率,单位bps*/private function bitRate( $_audioBitRate ){$_audioBitRate < 1 ?$this->setErrMessage( 'BitRate can not smaller than 0!!'):$this->InputFileOptionsString .= '-ab ' . $_audioBitRate . ' ';}/*** 设置音频流的声道数目* @param $_channels int 通道数目整数,大于等于1*/private function audioChannels( $_channels ){$_channels<1 ?$this->setErrMessage( 'Channels count must be biger than 0!!'):$this->InputFileOptionsString .= '-ac ' . $_channels . ' ';}/*** 设置终止时间点* @param $_endTimePoint String 终止时间点 hh:mm:ss*/private function endTime( $_endTimePoint ){$_endTimePoint = trim( $_endTimePoint );$_endTimePoint < 0 ?$this->setErrMessage( 'Time can not be less than 0!!'):$this->OutFileOptions .= '-to ' . $_endTimePoint . ' ';}/*** 设置时间长度* @param $_time String 时间长度 hh:mm:ss* @return $this Class 此类*/private function timeLength( $_timeLen ){$_timeLen = trim( $_timeLen );$_timeLen < 0 ?$this->setErrMessage( 'Time can not be less than 0!!'):$this->OutFileOptions .= '-t ' . $_timeLen . ' ';}处理音频/*** 修改音频的音量* @param $_volume int 你需要设置的音频音量* @return $this  Class 此类*/public function changeAudioVolume( $_volume ){( (int)$_volume < 10 )?$this->setErrMessage( 'Volume can not smaller than 10!!'):$this->OutFileOptions .= '-vol ' . $_volume . ' ';return $this;}/*** 合并多音轨* @return $this Class 此类*/public function audioComplex(  ){if( sizeof( $this->InputFilePath ) < 2 ){$this->setErrMessage( 'In this Complex function, The number of input files can not smaller than 2!!');}elseif( $this->OutFileTybe == 'amr' ){$this->setErrMessage( 'The outfile can not be amr type!!');}else{$this->OutFileOptions .= '-filter_complex join=inputs=2: ';}return $this;}/*** 多音轨合并(比如将BGM与人声结合) * @return $this*/public function audioAmix(){count($this->InputFilePath) < 2 ?$this->setErrMessage('File number is less than 2'):$this->OutFileOptions .= '-filter_complex amix=inputs=2:duration=first:dropout_transition=2 ';return $this;}/*** 拼接两个音频文件* @return $this Class 此类*/public function audioJoin(  ){( sizeof( $this->InputFilePath ) < 2 )?$this->setErrMessage( 'The number of input files can not smaller than 2!!' ):$this->OutFileOptions .= '-filter_complex acrossfade=d=10:c1=exp:c2=exp ';return $this;}/*** 改变音频的速率* @param $_speed int 你需要设置的速率 分数格式 7/10* @return $this Class 此类*/public function changeAudioSpeed( $_speed ){$_speed = trim( $_speed );( $_speed <= 0 && empty($_speed))?$this->ErrMessage[] = 'The slowdown speed can not smaller than 0 or =0!!':$this->OutFileOptions .= '-filter:a atempo=' . $_speed . ' ';return $this;}/*** 改变原音频的声调,改变声音* @param $_rateHz rateHz*/public function audioChangeVoice( $_rateHz ){$_rateHz = trim( $_rateHz );( $_rateHz < 100 )?$this->ErrMessage[] = 'The rate size cannot be lower than 100Hz!!':$this->OutFileOptions .= '-filter_complex asetrate=r=' . $_rateHz . ' ';return $this;}处理视频/*** 裁剪视频* @param $_Property Array 包括以下元素:'operation':操作,'width':要裁剪的宽,'height':要裁剪的高,'offestX':水平偏移,'offestY':垂直偏移* @return $this*/public function videoCrop( $_Property ){if(empty($_Property) && !is_array($_Property)){$this->setErrMessage('The parameter is incorrect');}else {switch ($_Property['operation']) {case 'normal'://普通操作,即要输入裁剪的宽高和开始裁剪的xy值$this->OutFileOptions .= '-filter_complex crop=w=' . $_Property['width'] . ':h=' . $_Property['height'] . ':x=' . $_Property['offestX'] . ':y=' . $_Property['offestY'] . ' ';break;case 'centerWH'://从中心开始裁剪多宽和多高,需要输入裁剪的宽高值$this->OutFileOptions .= '-filter_complex crop=' . $_Property['width'] . ':' . $_Property['height'] . ' ';break;case 'center'://从中心开始裁剪,裁剪的宽高值由程序控制$this->OutFileOptions .= '-filter_complex crop=out_w=in_h crop=in_h ';break;case 'boder'://据上下多少,左右多少进行裁剪,需输入裁剪的宽高值,此时宽高值为:距离边界多少像素值$this->OutFileOptions .= '-filter_complex crop="in_w-2 ' . $_Property['width'] . ':in_h-2 ' . $_Property['height'] . '" ';break;case 'shake':$this->OutFileOptions .= "-filter_complex crop='in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2+((in_h-out_h)/2)*sin(n/7)' ";break;}}return $this;}/*** 在视频上画网格* @param $_boxWidthCount  int  水平多少个格, 默认3* @param $_boxHeightCount int  垂直多少个格,默认3* @param $_thickness int 网格线的宽度,默认2* @param $_color String 网格颜色名称,默认yellow,详解:https://xdsnet.gitbooks.io/other-doc-cn-ffmpeg/content/ffmpeg-doc-cn-37.html* @param $_transparent 网格透明度,0~1 ,支持一位小数,默认1* @return $this Class 此类*/public function videoDrawGrid( $_boxWidthCount = "" , $_boxHeightCount ="" , $_thickness ="" , $_color ="" , $_transparent =""){if( empty( $_color ) ){$_color = 'yellow';}if( empty( $_transparent ) ){$_transparent = 1;}if( empty( $_thickness ) ){$_thickness = 2;}if( empty( $_boxWidthCount ) ){$_boxWidthCount = 3;}if( empty( $_boxHeightCount ) ){$_boxHeightCount = 3;}$this->OutFileOptions .= '-filter_complex drawgrid=width='.$_boxWidthCount . ':height=' . $_boxHeightCount . ':thickness=' . $_thickness . ':color=' . $_color . '@' . $_transparent . ' ';return $this;}/*** 水平翻转视频* @return $this*/public function videoHFlip(){$this->OutFileOptions .= '-vf "hflip" ';return $this;}/*** 垂直翻转视频* @return $this*/public function videoVFlip(){$this->OutFileOptions .= '-vf "vflip" ';return $this;}/*** 旋转视频* @param $_dir  int 角度(单位:90度)* @return $this Class 此类*/public function videoTranspose( $_dir ){if(empty($_dir)){$_dir = 90;}$this->OutFileOptions .= '-filter_complex transpose=dir=' . $_dir . ' ';return $this;}/*** 拼接多个视频* 需要php的ffmpeg扩展* @return $this Class 此类*/public function videoConcat(){if(empty(get_extension_funcs('ffmpeg'))){$this->setErrMessage('ffmpeg Extension does not exist');}else{if( empty( $this->InputFilePath ) ){$this->ErrMessage[] = 'Line 583 , The inputFiles count empty!!';}if( sizeof( $this->InputFilePath ) < 2 ){$this->ErrMessage[] = 'Line 586 , The inputFiles count must be bigger than 1!!';}$biggerWidth = 0;$biggerHeight = 0;for( $i = 0 ; $i < sizeof( $this->InputFilePath ) ; $i++  ){$ffmpeg = new \ffmpeg_movie( $this->InputFilePath[$i] );if( $ffmpeg->getFrameWidth() > $biggerWidth ){$biggerWidth = $ffmpeg->getFrameWidth();}if( $ffmpeg->getFrameHeight() > $biggerHeight ){$biggerWidth = $ffmpeg->getFrameHeight();}}for( $i = 0 ; $i < sizeof( $this->InputFilePath ) ; $i++  ){$ffmpeg = new \ffmpeg_movie( $this->InputFilePath[$i] );if( $ffmpeg->getFrameHeight() == $biggerHeight && $ffmpeg->getFrameWidth() == $biggerWidth ){continue;}else{$heightDifference = $ffmpeg->getFrameHeight() - $biggerHeight;$widthDifference = $ffmpeg->getFrameWidth() - $biggerWidth;if( $heightDifference !== 0 ){$heightDifference = $heightDifference/2;}if( $widthDifference !== 0 ){$widthDifference = $widthDifference/2;}$savePath = substr( $this->InputFilePath[$i] , 0 , strrpos( $this->InputFilePath[$i] , '.' , 0 )  ) . '1' . substr( $this->InputFilePath[$i] , strrpos( $this->InputFilePath[$i] , '.' , 0 ) + 1  );$ffmpegStr = 'ffmpeg -y -i ' . $this->InputFilePath[$i] . ' -vf pad=' . $biggerWidth . ':' . $biggerHeight . ':' . $widthDifference . ':' . $heightDifference . ':black ' . $savePath;$this->execute( $ffmpegStr );$this->InputFilePath[$i] = $savePath;}}$this->OutFileOptions .= "-filter_complex concat=n=" . sizeof( $this->InputFilePath ) . ' ';}return $this;}/*** 添加水印,水印图片为png图片,透明度用绘图软件调整* @param $_operation  string 操作类型,有normal(正常:需输入x,y偏移值),lefttop(左上角),righttop(右上角),leftbottom(左下角),rightbottom(右下角),center(中心)* @param $_offestX  (x偏移值)* @param $_offestY  (y偏移值)* @return $this  Class 此类*/public function videoOverlay( $_operation , $_offestX , $_offestY ){switch( $_operation ){case 'normal':$offestX = $_offestX;$offestY = $_offestY;break;case 'lefttop':$offestX = 0;$offestY = 0;break;case 'righttop':$offestX = 'main_w-overlay_w';$offestY = 0;break;case 'leftbottom':$offestX = 'main_w-overlay_w';$offestY = 'main_h-overlay_h';break;case 'rightbottom':$offestX = 0;$offestY = 'main_h-overlay_h';break;case 'center':$offestX = '(main_w-overlay_w)/2';$offestY = '(main_h-overlay_h)/2';break;default:$offestX = 0;$offestY = 0;break;}$this->OutFileOptions .= "-filter_complex overlay=" . $offestX . ':' . $offestY . ' ';return $this;}public function setAphaser(  ){$this->OutFileOptions .= "-filter_complex blend=all_mode=normal ";return $this;}/*** 修改视频速率(只修改视频,音频依旧是原速率)* @param $_speed   速率* @return $this  Class 此类*/public function videoSetpts($_speed){(empty($_speed))?$this->ErrMessage[] = 'videoSpeed is null':$this->OutFileOptions .= "-filter:v setpts=PTS*('.$_speed.')' ";return $this;}/*** 同时修改音频与视频速率*/public function changeVideoSpeed($_speed){$_speed = explode('/',$_speed);if(empty($_speed)){$this->ErrMessage[] = 'speed is null';}elseif(($_speed[0]/$_speed[1] > 2) || ($_speed[0]/$_speed[1] < 1/2)){$this->ErrMessage[] = 'The rate is only 2/1(2.0) to 1/2(0.5)';}else{$videoSpeed = '('.$_speed[0].'/'.$_speed[1].')';$audioSpeed = '('.$_speed[1].'/'.$_speed[0].')';$this->OutFileOptions .= "-filter_complex [0:v]setpts=".$videoSpeed."*PTS[v];[0:a]atempo=".$audioSpeed."[a] -map [v] -map [a] ";}return $this;}/*** 视频单独分离* @return $this  Class 此类*/public function separateVideo(){$this->OutFileOptions .= '-vcodec copy -an ';return $this;}/*** 音频单独分离* @return $this  Class 此类*/public function separateAudio(){$this->OutFileOptions .= '-acodec copy -vn ';return $this;}/*** 修改视频尺寸   参考 640x480* @param $Width    视频宽度* @param $Height   视频高度* @return $this*/public function changeAudioSize($Width,$Height){(empty($Width) || empty($Height))?$this->ErrMessage[] = 'width or height is null':$this->OutFileOptions .= '-s '.$Width.'x'.$Height.' ';return $this;}/** 转换黑白*/public function videoBlackWhite(){$this->OutFileOptions .= '-vf lutyuv="u=128:v=128" ';return $this;}/*** 生成gif* @return $this*/public function makeGif(){$this->OutFileOptions .='-pix_fmt rgb24 ';return $this;}错误处理,运行ffmpeg方法/*** 获取执行错误信息* @return array 错误信息,包括错误行数和错误内容*/public function setErrMessage($message){$this->ErrMessage[] = $message;}public function getErrorMessage(){return($this->ErrMessage);}/*** 执行ffmpeg命令* @return string 执行结果信息*/public function exec(  ){if(!empty($this->ErrMessage)){return false;}//amr文件输出方式跟其他文件不同,需要分开处理if( $this->OutFileTybe == 'amr' ){$acIndex = strrpos( $this->OutFileOptions , '-ac' , 0 );$arIndex = strrpos( $this->OutFileOptions , '-ar' , 0 );$this->OutFileOptions =  $acIndex === false ? $this->OutFileOptions . ' -ac 1 ' : $this->OutFileOptions;$this->OutFileOptions =  $arIndex === false ? $this->OutFileOptions . ' -ar 8000 ' : $this->OutFileOptions;}//输入文件内容$inputString = '';//将输入条件与对应文件进行匹配foreach ($this->InputFileOptions as $value) {$inputString .= $value;}//将执行语句拼接$this->ExecString .=  $this->GlobalOptions . $inputString . $this->OutFileOptions . $this->OutFilePath;//执行ffmpeg命令exec( $this->ExecString,$execInfo,$execCode);//执行后清空本次执行选项,防止干扰下次使用$this->ExecString = 'ffmpeg ';$this->GlobalOptions = '';$this->InputFileOptionsString = '';$this->InputFileOptions = array();$this->InputFilePath = array();$this->OutFileOptions = '';$this->OutFilePath = '';$this->OutFileTybe = '';//检查exec语句运行是否成功,如果不成功返回失败if(!is_array($execInfo) && $execCode!=0){$this->setErrMessage('exec error!!');return false;}else {return true;}}/*** 此方法用来解决无法用户无法通过浏览器执行exec命令(此方法只能在windos上使用)* @param $batPath bat文件路径* @return bool*/public function execute($batPath){if(!empty($this->ErrMessage)){return false;}if( $this->OutFileTybe == 'amr' ){$acIndex = strrpos( $this->OutFileOptions , '-ac' , 0 );$arIndex = strrpos( $this->OutFileOptions , '-ar' , 0 );$this->OutFileOptions =  $acIndex === false ? $this->OutFileOptions . ' -ac 1 ' : $this->OutFileOptions;$this->OutFileOptions =  $arIndex === false ? $this->OutFileOptions . ' -ar 8000 ' : $this->OutFileOptions;}//输入文件内容$inputString = '';//将输入条件与对应文件进行匹配foreach ($this->InputFileOptions as $value) {$inputString .= $value;}//将执行语句拼接$this->ExecString .=  $this->GlobalOptions . $inputString . $this->OutFileOptions . $this->OutFilePath;$bat = fopen($batPath,'w+');if(!$bat){$this->setErrMessage('batFile can not open');return false;}fwrite($bat, $this->ExecString);fclose($bat);exec($batPath,$execInfo,$execCode);$this->ExecString = 'ffmpeg ';$this->GlobalOptions = '';$this->InputFileOptionsString = '';$this->InputFileOptions = array();$this->InputFilePath = array();$this->OutFileOptions = '';$this->OutFilePath = '';$this->OutFileTybe = '';//检查exec语句运行是否成功,如果不成功返回失败if(!is_array($execInfo) && $execCode!=0){$this->setErrMessage('exec error!!');return false;}else {return true;}}
}

有些功能有冲突是不能同时使用的,比如音频分离跟修改速率是不能同时执行的
ffmpeg是一个功能十分强大的开源库,我这里只列举一部分功能,而且这个类还有许多可以优化的地方,这个类写出来主要是为了抛砖引玉 :D

下面附上ffmpeg参数说明
http://www.cnblogs.com/chen1987lei/archive/2010/12/03/1895242.html

参考:PHP的ffmpeg使用 - CSDN博客
https://blog.csdn.net/qq_20329253/article/details/51420661

转载于:https://www.cnblogs.com/Renyi-Fan/p/9595527.html

php如何截取出视频中的指定帧作为图片相关推荐

  1. 批量剪辑,截取视频中某一帧画面保存为图片

    平时刷视频的时候看到好看的画面就想截图保存,那么如何批量提取视频中的某一帧画面呢?不知道怎么操作的朋友走过路过不要错过,小编分享一个方法演示具体的操作步骤,一起来看看. 运行[媒体梦工厂]这款软件中有 ...

  2. 教你在多个视频中随机抽帧画面出来,置入到各个视频封面上

    通过抽帧在视频里随机抽取一幅画面图片出来,再次导入到各个视频上作为封面图片,这种的剪辑该如何操作呢?下面我们用一个媒体梦工厂剪辑的工具就可实现,一起看详细教程操作. 准备多个视频保存在同一文件夹中,可 ...

  3. Mac 截取一个视频中部分片段(命令行方法)

    苹果电脑中想要截取一个视频中的某一段视频,参考了百度经验 打开命令行,执行以下操作 mkdir bin cd bin touch capture.txt open capture.txt 输入一下内容 ...

  4. 动态水印跟踪去除_视频动态水印如何去除 视频中不定时出现的图片加文字广告如何尽量模糊处理...

    『狸窝是帮助用户解决问题 提供教程解决方案 在这个过程中有使用我们自己开发的软件 也有网上找的工具 只要帮助用户解决问题就好!』 离别真是个伤感的事情,每天都走人来来去去,每天也都有人走走停停,当离别 ...

  5. access找不到输入表或者dual_在Access窗体中显示指定路径的图片

    ↑↑↑点击上方图片,了解详情 在Access中,如果把图形对象以OLE格式的字段保存,那么在窗体中可以直接显示出图片来.但是这样做有以下不足: 一.需要将图片逐一插入到表中,工作量太大. 二.使数据库 ...

  6. mpeg4视频中,I帧、p帧、B帧的判定

    mpeg4视频中,I帧.p帧.B帧的判定 mpeg4的每一帧开头是固定的:00 00 01 b6,那么我们如何判断当前帧属于什么帧呢?在接下来的2bit,将会告诉我们答案.注意:是2bit,不是byt ...

  7. python OpenCV 按时间间隔截取视频中任意片段帧

    通过视频制作相应的数据集,截取视频中的任意片段帧. 使用python截取视频中的任意片段帧,直接上代码: import cv2 import os# 定义视频文件路径和保存图像文件路径 video_p ...

  8. 怎样在每个视频中随机抽帧一帧图片出来

    最近很多人都在问如何在视频里随机抽帧一帧画面为图片出来呢?下面教大家一次性剪辑多个视频,一起来试试吧. 下载一个"媒体梦工厂"进入主界面,用到"视频封面"功能 ...

  9. 在access窗体中加图片_如何在Access窗体中显示指定路径的图片

    在Access中,如果把图形对象以OLE格式的字段保存,那么在窗体中可以直接显示出图片来.但是这样做有以下不足:一.需要将图片逐一插入到表中,工作量太大.二.使数据库文件变得庞大.三.相同的图片文件, ...

最新文章

  1. 公众号留言-2020-4-3
  2. 怎么把文件放在python目录下-python – 如何将文件下载到特定目录?
  3. python获取计算机信息系统数据罪_工作心得:破坏计算机信息系统罪与非法获取计算机信息系统数据罪的区分...
  4. [Leetcode][第111题][JAVA][BFS][二叉树的最小深度][BFS][递归]
  5. ZGrapher 画函数曲线图的工具
  6. 人到中年生活不易,特别是工作压力很大
  7. Jmeter分布式测试-远程调用
  8. Webpack 简介
  9. 图像局部特征(十)--BRIEF描述子
  10. 110kv变电所无功补偿技术的研究
  11. cad安装日志文件发生错误_CAD安装错误怎么办?
  12. JAVA除数为0报错?
  13. 苹果文件管理器服务器,8最佳免费iPhone文件管理器,用于管理iOS设备上的文件...
  14. 画思维导图一定要用计算机来完成吗,一起来画思维导图
  15. 中职高二学生计算机学情分析,高二学生学习数学的学情分析.doc
  16. Python 中点法求积分
  17. 多核机器上多线程内存敏感程序的可伸缩性
  18. 批量安装系统工具cobbler配置
  19. MATLAB fprintf 函数输出希腊字母/特殊字符
  20. c语言编程培训ppt,C语言入门经典-C语言编程.ppt

热门文章

  1. 帝国cms7.2 linux伪静态,帝国CMS7.0IIS伪静态设置教程
  2. 喝酒神器微信小程序源码支持流量主解锁多人对战
  3. 异步爬取有道词典(入门js逆向)
  4. 微信用户头像不能高清问题
  5. 计算机显示另外一个用户登录,电脑两个用户怎么在欢迎界面只显示一个?
  6. 代码 马佳义_212电子信息学院(2018年度)
  7. 视频工作室必备利器——群晖NAS
  8. 【XJTU】数学建模
  9. 糗事百科李威: 如何基于数据构建推荐系统,助力精细化运营?
  10. 《GitHub详细教程》