在php中裁剪视频画面通常使用ffmpeg的`-vf crop`滤镜,通过指定宽、高及起始坐标来实现。核心做法是调用`exec()`或`shell_exec()`执行包含`ffmpeg -i input.mp4 -vf "crop=w:h:x:y" output.mp4`命令的脚本,其中`w`和`h`为目标宽高,`x`和`y`为左上角偏移量。若需保持中心裁剪,可先计算原尺寸与目标尺寸的差值并除以2得到偏移量。该操作会生成一个新的视频文件,原始文件保持不变。

如何计算中心裁剪的坐标参数
中心裁剪需要动态计算`x`和`y`偏移量,公式为`(原宽-目标宽)/2`和`(原高-目标高)/2`。在PHP中,可通过FFprobe获取源视频的元数据,然后构建完整的FFmpeg命令字符串。关键在于确保计算结果为整数,避免浮点数导致FFmpeg报错。此方法适用于已知目标分辨率且希望自动适配的场景。

<?php
$src = 'input.mp4';
$out = 'output.mp4';
$targetW = 640;
$targetH = 360;
// 获取源视频信息
$cmd = "ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of default=noprint_wrappers=1:nokey=1 $src";
exec($cmd, $output);
$srcW = (int)$output[0];
$srcH = (int)$output[1];
// 计算中心裁剪坐标
$x = ($srcW - $targetW) / 2;
$y = ($srcH - $targetH) / 2;
// 执行裁剪
$ffmpegCmd = "ffmpeg -i $src -vf \"crop=$targetW:$targetH:$x:$y\" -c:a copy $out";
exec($ffmpegCmd, $result, $returnVar);
if ($returnVar === 0) {
echo "裁剪成功";
} else {
echo "裁剪失败";
}
?>
上述代码首先利用`ffprobe`提取源视频的宽和高,接着计算中心偏移量,最后拼接FFmpeg命令执行裁剪。输出文件`output.mp4`即为裁剪后的结果,音频流直接复制以保证同步。
立即学习“PHP免费学习笔记(深入)”;
如何处理非标准比例导致的黑边问题
当目标宽高比与原视频不一致时,直接裁剪可能导致画面变形或留黑边。解决思路是先使用`scale`滤镜调整分辨率至目标比例,再配合`crop`进行精确截取,或者使用`pad`填充背景。更常见的做法是结合`scale`和`crop`实现“缩放+裁剪”以填满屏幕。例如,先将视频等比缩放至覆盖目标区域,再裁去多余部分。这能确保输出视频无黑边且充满画面。

<?php
$src = 'input.mp4';
$out = 'output_no_black.mp4';
$targetW = 640;
$targetH = 360;
$cmd = "ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of default=noprint_wrappers=1:nokey=1 $src";
exec($cmd, $output);
$srcW = (int)$output[0];
$srcH = (int)$output[1];
// 计算缩放比例,确保覆盖目标区域
$ratioW = $targetW / $srcW;
$ratioH = $targetH / $srcH;
$scaledW = (int)($srcW * max($ratioW, $ratioH));
$scaledH = (int)($srcH * max($ratioW, $ratioH));
// 计算缩放后裁剪的偏移量
$x = ($scaledW - $targetW) / 2;
$y = ($scaledH - $targetH) / 2;
// 组合滤镜:先缩放,再裁剪
$filter = "scale=$scaledW:$scaledH,crop=$targetW:$targetH:$x:$y";
$ffmpegCmd = "ffmpeg -i $src -vf \"$filter\" -c:a copy $out";
exec($ffmpegCmd, $result, $returnVar);
if ($returnVar === 0) {
echo "无黑边裁剪成功";
} else {
echo "处理失败";
}
?>
该段代码通过比较宽高比选择较大的缩放因子,使视频在缩放后完全覆盖目标分辨率,再通过`crop`切除边缘多余部分。最终输出的`output_no_black.mp4`将充满640x360的画面,无任何黑边或拉伸变形。
基于输入视频宽高比的具体裁剪结果差异
当输入视频为16:9(如1920x1080)而目标为1:1(如500x500)时,直接中心裁剪会保留完整宽度但上下被截断;若先缩放再裁剪,则画面内容会被放大并居中截取。具体而言,16:9视频直接裁剪500x500时,`x`为710,`y`为290,保留中间正方形区域;若采用缩放策略,视频先放大至1080x1080(假设按高度缩放),再裁剪500x500,此时画面细节更清晰但视野更窄。开发者应根据业务需求选择是否牺牲视野以换取填充效果。



















