本文分享了在项目中实现视频截图并上传功能的安装与排错经验,重点介绍了FFmpeg和yasm的安装步骤、常见报错及解决方案,并提供了PHP代码示例。通过本文,读者可以快速掌握视频处理的核心技术,并解决实际开发中遇到的临界区问题。
—
文章标题:FFmpeg+PHP实现视频截图上传全攻略:安装排错与临界区处理经验分享
文章内容:
最近在公司项目中,我们需要实现用户上传视频并自动截取第一帧作为视频封面的功能。经过一番研究和尝试,我们最终选择了FFmpeg和yasm的组合方案。虽然最初遇到了不少安装问题,但最终成功实现了需求。下面我将详细分享这一过程,希望能帮助到有类似需求的开发者。
FFmpeg是一款强大的视频处理工具,但要成功运行它,需要先安装yasm库。以下是详细的安装步骤:
首先,从FFmpeg官网下载安装包:
http://ffmpeg.org/download.html
解压安装包:
tar -jxvf ffmpeg-x.x.tar.bz2
进入解压后的目录:
cd ffmpeg-x.x
编译安装FFmpeg:
./configure --enable-shared && make && make install
如果遇到报错:”nasm/yasm not found or too old. Use –disable-x86asm for a crippled build.”,说明需要先安装yasm。
下载yasm:
http://yasm.tortall.net/Download.html
上传到服务器的local目录,然后解压:
tar -zxvf yasm.tar.gz
进入解压目录进行安装:
cd yasm-1.3.0/
./configure
make
make install
安装完成后,返回FFmpeg目录继续编译安装,这个过程可能需要几分钟时间。
如果编译过程中出现报错,可以参考报错提示添加选项:
./configure --enable-shared --选项 && make && make install
2. 解决FFmpeg依赖问题
安装完成后,如果执行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
,如果出现版本信息,说明安装成功。
3. 配置PHP环境
由于PHP代码中会用到exec
或system
函数,需要修改php.ini
文件,解除这些函数的禁用。
修改php.ini
文件中的相关设置:
cd /usr/local/php/etc
vi php.ini
找到以下设置并取消注释:
disable_functions = exec,system,shell_exec,proc_open,proc_get_status
修改完成后保存退出,重启服务器:
service php-fpm restart
4. PHP代码实现视频截图
以下是使用ThinkPHP5框架实现的视频截图代码示例:
接收视频文件:
$video = request()->file('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截取视频第一帧
$str = "ffmpeg -i ".$video_filePath." -y -f mjpeg -ss 1 -t 0.001 -s 348470 ".$dir.$fileName;
exec($str,$out,$status);
$datas['video'] = $source;
$datas['picture'] = '/uploads/' . $fileName;
// 调用ThinkPHP图片处理类
$image = thinkImage::open('.'.$datas['picture']);
$width = $image->width();
$height = $image->height();
// 添加播放按钮水印
$water = $dir.'water.png';
$image->water($water,thinkImage::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 : '348470';
$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;
}
成功获取视频封面后,可以将相关数据存储到数据库中,至此整个流程完成。
在实现这一功能的过程中,我们遇到了不少挑战,特别是在处理临界区问题时。通过不断调试和优化,最终找到了最佳解决方案。希望这些经验能帮助大家更好地应用FFmpeg技术。
—
文章tag标签:
{1、FFmpeg, 2、PHP, 3、视频处理, 4、临界区, 5、安装教程, 6、排错经验, 7、视频截图, 8、服务器配置, 9、ThinkPHP5}
本文是基于《做项目时实现视频截图并上传功能的安装与排错经验分享》的AI重写版本
评论(0)