linux系统,CentOS7.2安装ffmpeg扩展,PHP用FFmpeg截取视频第一帧作为视频封面,并给图片添加播放视频按钮

最近做公司的项目中,有用户上传视频,后台这边接收视频并上传,获取视频第一帧作为视频封面的功能,在网上查找了好多资料,并且安装 了ffmpeg-php的PHP扩展,由于版本问题,安装好几个版本都不成功,最后放弃安装扩展,后来运行代码发现不用安装那个扩展也能实现截图并上传的功能,所以要截取视屏第一帧,只需要安装FFmpeg和yasm即可,建议先安装yasm,再安装FFmpeg,我这边是一边安装一边排错的,所以我先安装的实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

linux系统,CentOS7.2安装ffmpeg扩展,PHP用FFmpeg截取视频第一帧作为视频封面,并给图片添加播放视频按钮_第1张图片

报错:

nasm/yasm not found or too old. Use --disable-x86asm for a crippled build.

If you think configure made a mistake, make sure you are using the latest
version from Git.  If the latest version fails, report the problem to the
[email protected] mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "ffbuild/config.log" produced by configure as this will help
solve the problem.

报这个错说明没有安装yasm,所以要先去安装yasm
http://yasm.tortall.net/Download.html 下载yasm,上传到服务器的local目录中

解压:
tar -zxvf yasm.tar.gz

进入解压目录安装: 

linux系统,CentOS7.2安装ffmpeg扩展,PHP用FFmpeg截取视频第一帧作为视频封面,并给图片添加播放视频按钮_第2张图片

cd yasm-1.3.0/
./configure
make
make install

安装成功以后进入FFmpeg目录进行安装,可能需要3,4分钟时间

linux系统,CentOS7.2安装ffmpeg扩展,PHP用FFmpeg截取视频第一帧作为视频封面,并给图片添加播放视频按钮_第3张图片

如果编译报错,请加选项(报错会提示选项内容)./configure --enable-shared  --选项 && make && make install

安装完成之后 执行 ffmpeg -version

如果出现ffmpeg: error while loading shared libraries: libavdevice.so.57: cannot open shared object file: No such file or directory

编辑/etc/ld.so.conf文件中的:include ld.so.conf.d/*.conf 这行下面加入如下内容
/usr/local/ffmpeg-4.0.2
保存退出后执行ldconfig命令  

检验安装成功与否,输入 ffmpeg检验,出现如下图内容,即安装成功

linux系统,CentOS7.2安装ffmpeg扩展,PHP用FFmpeg截取视频第一帧作为视频封面,并给图片添加播放视频按钮_第4张图片

2.修改php.ini中的禁止函数

因为PHP代码中会用到exec或者system,直接删除,还有shell_exc,proc_open,peoc_get_status

cd /usr/local/php/etc

vi php.ini

linux系统,CentOS7.2安装ffmpeg扩展,PHP用FFmpeg截取视频第一帧作为视频封面,并给图片添加播放视频按钮_第5张图片

 修改完成后保存退出重启服务器

service php-fpm restart

看到如下,说明重启成功
Gracefully shutting down php-fpm .. done
Starting php-fpm  done
 

3.PHP代码篇

我用的框架是tp5的框架,代码如下,因为视频和图片一样都是文件,所以接收方式和图片的接收方式一样,上传也是一样,直接调取框架自带的上传类:

$video = request()->file('video');//接收video文件
if(!empty($video)){
            $info = $video->move(ROOT_PATH . 'public' . DS . 'uploads');
            if($info) {
                $videoName = $info->getSaveName();
                $source = '/uploads/' .$videoName;//原视频名称

                $dir = ROOT_PATH . 'public' . DS . 'uploads/';//上传图片路径
                $fileName = str_replace('.mp4','.jpg',$videoName);//图片名称
                $video_filePath = $dir.$videoName;//视频路径
                //用ffmpeg截取视频第一帧,并上传保存在和视频一样的路径下
                //使用-ss参数,可以从指定的时间开始处理转换任务后面是1代表从第一秒开始
                //-s参数,后面是图片的宽高,这个可以不用写,因为有横屏的或者竖屏的视频,不能固定
                $str = "ffmpeg -i ".$video_filePath." -y -f mjpeg -ss 1 -t 0.001 -s 348*470 ".$dir.$fileName;
                exec($str,$out,$status);
                $datas['video'] = $source;
                $datas['picture'] = '/uploads/' . $fileName;

                $image = \think\Image::open('.'.$datas['picture']);
                //调用tp5的图片处理类,获取图片宽高,并给封面图片添加播放按钮
                $width = $image->width();
                // 返回图片的高度
                $height = $image->height();
                $datas['width'] = $width;
                $datas['height'] = $height;
                $water = $dir.'water.png';//播放按钮
                $image->water($water,\think\Image::WATER_NORTHWEST,50)->save('.'.$datas['picture']);
            }
        }
或者将截取视频第一帧的功能封装一个方法,可以调用
/**
 * 截取视频第一帧
 *
 * @param  $file   视频文件
 * @param  $time    第几帧
 * @param  $dir     临时目录
 * @param  $size    截图尺寸
 */
public function getVideoCover($file,$time,$dir,$size) {
    $time = $time ? $time : '1';      //默认截取第一秒第一帧
    $size = $size ? $size : '348*470';
    $fileName = getImgName();

    //临时视频路径,生成截图后删除
    $tempfiles = $dir.$fileName.'.mp4';
    $bool = move_uploaded_file($file, $tempfiles);
    $str = "ffmpeg -i ".$tempfiles." -y -f mjpeg -ss ".$time." -t 0.001 -s $size ".$dir.$fileName.'.jpg';
    exec($str,$out,$status);
    return $fileName;
}

成功以后进行数据库数据的存储,结束,就是这样喽

 

你可能感兴趣的:(PHP,FFmpeg)