本文目录导读:

- 方案一:使用 FFmpeg(最通用、最强大)
- 方案二:使用 PHP 专用扩展(如 FFMpeg-PHP)
- 方案三:云服务/第三方API(推荐用于生产环境)
- 方案四:使用 PHP 的
imagick或gd库(仅处理封面/GIF) - 总结与建议
在 PHP 项目中实现短视频处理,通常有几种不同的路径,具体取决于你的需求(是简单的转码、添加水印,还是复杂的剪辑、特效)。
由于 PHP 本身不是为视频处理设计的底层语言,主流的实现方式是结合系统命令或专用的扩展/服务。
以下是几种主流且可行的方案,从简单到复杂依次介绍:
使用 FFmpeg(最通用、最强大)
这是处理短视频最标准、最灵活的方式,FFmpeg 是一个强大的命令行音视频处理工具。
实现方式: 在 PHP 中通过 exec()、shell_exec()、proc_open() 等函数调用操作系统中的 FFmpeg 命令。
安装 FFmpeg
- Linux (Ubuntu/Debian):
sudo apt install ffmpeg - macOS:
brew install ffmpeg - Windows: 下载二进制文件并添加到系统 PATH。
PHP 代码示例
<?php
// 假设你的视频文件路径
$inputFile = '/path/to/upload/short_video.mp4';
$outputFile = '/path/to/output/processed.mp4';
// 1. 最简单的转码 (压缩体积,修改尺寸)
$cmd = "ffmpeg -i " . escapeshellarg($inputFile) .
" -vf \"scale=720:-2\" " . // 缩放宽度到720px,高度自动保持比例且为偶数
" -c:v libx264 -preset fast -crf 28 " . // 使用H.264编码,适当压缩
" -c:a aac -b:a 128k " . // 音频编码为AAC
escapeshellarg($outputFile) . " 2>&1"; // 2>&1 用于捕获错误信息
echo "执行命令:$cmd\n";
$output = shell_exec($cmd);
echo "输出:$output\n";
// 2. 添加文字水印
$text = "我的水印";
$watermarkCmd = "ffmpeg -i " . escapeshellarg($inputFile) .
" -vf \"drawtext=text='$text':fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf:x=10:y=10:fontsize=24:fontcolor=white:shadowy=2\"" .
" " . escapeshellarg($outputFile) . " 2>&1";
// 3. 截取视频片段 (从第5秒开始,持续10秒)
$clipCmd = "ffmpeg -i " . escapeshellarg($inputFile) .
" -ss 00:00:05 -t 10 " .
" -c copy " . // 不重新编码,速度快
escapeshellarg($outputFile) . " 2>&1";
// 4. 获取视频文件信息 (时长、尺寸、码率)
$infoCmd = "ffprobe -v error -show_entries format=duration,size,bit_rate -of default=noprint_wrappers=1:nokey=1 " .
escapeshellarg($inputFile);
$info = shell_exec($infoCmd);
echo "视频信息: $info\n";
?>
优点:
- 功能极其强大,几乎可以处理任何视频格式。
- 社区活跃,资料丰富。
缺点:
- 需要服务器安装 FFmpeg,并开放
exec等函数(有安全风险,需谨慎处理用户输入)。 - 处理大视频时可能阻塞 PHP 进程(建议使用消息队列异步处理)。
- 关键安全提醒: 永远不要直接将用户输入的文件名或参数传递给
exec,务必使用escapeshellarg()转义。
使用 PHP 专用扩展(如 FFMpeg-PHP)
这是一个基于 PHP 的面向对象封装库,底层依然调用 FFmpeg。
实现方式: 通过 Composer 安装 php-ffmpeg/php-ffmpeg。
安装
composer require php-ffmpeg/php-ffmpeg
代码示例
<?php
require 'vendor/autoload.php';
$ffmpeg = FFMpeg\FFMpeg::create([
'ffmpeg.binaries' => '/usr/bin/ffmpeg', // 路径
'ffprobe.binaries' => '/usr/bin/ffprobe',
'timeout' => 3600, // 超时时间
]);
$video = $ffmpeg->open('/path/to/input.mp4');
// 转码和缩放
$video
->filters()
->resize(new \FFMpeg\Coordinate\Dimension(720, 720))
->synchronize();
$format = new \FFMpeg\Format\Video\X264('libmp3lame', 'libx264');
$format->setKiloBitrate(1000); // 码率
$video->save($format, '/path/to/output.mp4');
// 截取帧 (生成封面图)
$frame = $video->frame(\FFMpeg\Coordinate\TimeCode::fromSeconds(10));
$frame->save('/path/to/cover.jpg');
// 获取视频时长 (秒)
$duration = $ffmpeg->getFFProbe()->streams('/path/to/input.mp4')
->videos()->first()->get('duration');
?>
优点:
- 代码更优雅,面向对象,易于维护。
- 自动处理了 FFmpeg 的命令行参数。
缺点:
- 仍然依赖 FFmpeg 二进制文件。
- 对非常复杂的滤镜(filter graph)支持不如直接写命令灵活。
云服务/第三方API(推荐用于生产环境)
如果不想自己管理服务器资源和 FFmpeg 版本,使用专业的云视频处理服务是最省心、最安全的方式。
常见服务:
- 七牛云 / 阿里云 OSS + 媒体处理:上传视频后,调用 API 触发转码、水印、截图等,支持异步通知(Webhook)。
- 腾讯云 VOD(视频点播):功能全面,有专门的 PHP SDK。
- AWS Elemental MediaConvert:全球知名,PHP SDK 完善。
- Shotstack / Cloudinary:提供更简单的 API,适合前端集成。
实现方式(以阿里云为例):
// 1. 安装 SDK: composer require alibabacloud/sdk
// 2. 初始化和调用 API (伪代码)
$client = new DefaultAcsClient(profile);
$request = new MtsRequest\SubmitJobsRequest();
$request->setInput(json_encode(['Location'=>'oss-cn-hangzhou', 'Bucket'=>'my-bucket', 'Object'=>'video/abc.mp4']));
$request->setOutputBucket('my-output-bucket');
$request->setOutputLocation('oss-cn-hangzhou');
// 定义转码模板 (水印、尺寸)
$outputs = [
'OutputFile' => ['Object' => 'processed/abc.mp4'],
'TemplateId' => 'S00000001-200030', // 预先定义的转码模板
'WaterMarks' => [...]
];
$request->setOutputs(json_encode($outputs));
$response = $client->getAcsResponse($request);
优点:
- 无需服务器资源,处理速度快,支持高并发。
- 安全,不暴露服务器命令执行。
- 通常提供 CDN 分发,直接输出可播放的 URL。
缺点:
- 需要付费(按量或包月)。
- 依赖网络,离线场景不可用。
使用 PHP 的 imagick 或 gd 库(仅处理封面/GIF)
如果只需要生成视频封面图或处理 GIF,可以用 Imagick 配合 FFmpeg 的视频帧。
// 先生成一张帧图片 (用ffmpeg)
exec("ffmpeg -i input.mp4 -ss 00:00:03 -vframes 1 frame.png");
// 再用 Imagick 加水印、裁剪
$image = new Imagick('frame.png');
$watermark = new Imagick('logo.png');
$image->compositeImage($watermark, Imagick::COMPOSITE_OVER, 10, 10);
$image->writeImage('cover_with_watermark.jpg');
总结与建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 学习/小项目/内网 | FFmpeg + PHP exec | 免费、灵活、可完全控制。 |
| 中小型商业项目 | php-ffmpeg 扩展 | 代码更规范,便于团队维护。 |
| 大型/高并发/安全要求高 | 云服务 (阿里云/七牛/腾讯云) | 不用担心服务器负载和命令注入,有完整回调机制。 |
| 只需要封面图 | FFmpeg + Gd/Imagick | 简单快速,内存占用低。 |
重要安全建议:
- 永远不要直接在 PHP 中处理用户上传的短视频(如直播流或上传到临时目录)。
- 始终使用
move_uploaded_file()将上传文件移动到受保护的、非 web 可访问的目录。 - 如果使用
exec,必须对文件名和路径使用escapeshellarg()。 - 建议使用消息队列(如 Redis + 队列)来异步处理视频,避免阻塞 PHP-FPM 进程。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播