PHP调用FFmpeg,通过-vfcrop和scale命令实现视频裁剪与缩放,需先获取原始分辨率以保持宽高比。移动端上传的视频需处理旋转元数据,并注意超时与磁盘空间限制。
PHP视频处理画面裁剪与分辨率缩放移动端适配
作者:技术拾光
时间:2026-06-18
浏览:336
文章目录
PHP无法直接处理视频像素,这项任务必须交由FFmpeg完成。不要尝试使用imagecopyresampled处理视频——两者属于完全不同的技术路线。PHP的角色更像一个调度员:负责传递参数、校验路径、处理错误,所有像素级的操作均由FFmpeg执行。

PHP 调用 FFmpeg 实现画面裁剪(crop)
先拆解具体步骤。FFmpeg 的 -vf crop 是当前唯一可靠的画面裁剪方式。但需注意:必须先获取源视频的分辨率,否则可能误切关键内容。
- 使用以下命令获取原始宽高:
ffprobe -v quiet -show_entries stream=width,height -of csv=p=0 input.mp4 - 裁剪命令示例:
ffmpeg -i input.mp4 -vf "crop=350:250:100:80" -c:a copy output.mp4,其中350:250为目标区域宽高,100:80为左上角起始坐标(x:y) - 切勿省略
-c:a copy,否则音频会重编码,不仅拖慢处理速度,还可能引发音画不同步 - 在 PHP 中执行命令时,务必用
escapeshellarg()包裹所有路径和参数——文件名中的空格或特殊字符会导致严重错误
缩放到指定分辨率(scale)并保持宽高比
直接设置 -s 320x240 会强行拉伸变形,这在移动端适配中是大忌。关键在于“等比缩放 + 填黑边或裁边”,而 FFmpeg 默认行为是拉伸,必须显式控制。
- 推荐做法:
-vf "scale=320:-2:force_original_aspect_ratio=decrease,pad=320:240:(ow-iw)/2:(oh-ih)/2"。此命令先等比缩小至宽度 ≤320,再居中填黑边到 320×240 - 若需裁边而非填黑边,将
pad替换为crop,例如:-vf "scale=320:240:force_original_aspect_ratio=increase,crop=320:240" -2非常实用,表示高度自动按比例计算,省去手动计算步骤;force_original_aspect_ratio=decrease则确保不会放大画面- 执行时建议添加超时限制:
exec($cmd . ' 2>&1', $output, $return_code);,然后检查$return_code !== 0判断是否失败
移动端上传后自动触发裁剪缩放的坑点
用户从手机上传的视频常携带旋转元数据——例如iPhone拍摄的竖屏视频,宽高值实际是颠倒的。直接裁剪会导致画面歪斜。FFmpeg 默认不自动旋转,必须先处理 orientation。
- 可添加
-vf "transpose=1"或"transpose=2"手动旋转(需先用ffprobe查看tags:rotate值) - 更稳妥的做法是使用
-vf "transpose=2,setsar=1"配合-noautorotate关闭 FFmpeg 的自动旋转(某些版本默认开启自动旋转,反而会干扰操作) - 大视频文件(如4K)执行时间较长。PHP 默认的
max_execution_time=30必须提前调大,否则进程会被终止,留下临时文件残骸 - 内存并非瓶颈,真正的挑战是磁盘 I/O。确保
/tmp有足够空间,FFmpeg 的临时帧缓存可能占用数个 GB
归根结底,真正困难的并非写出FFmpeg命令,而是判断该用 pad 还是 crop、是否保留元数据、以及如何追踪失败的任务。这些逻辑一旦固化在PHP代码中,后续修改将比重装FFmpeg更加复杂。
实用工具推荐
电子包浆
使用 ›绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
图片压缩
使用 ›选择画质和输出格式,预览压缩前后的大小。