php视频处理ci/cd必须显式安装ffmpeg、禁用proc_open限制、动态生成最小合法mp4测试文件,并验证upload_max_filesize、max_execution_time及进程回收机制,否则环境差异将导致静默失败。

PHP视频文件处理类项目做CI/CD,不能只跑phpunit就完事——视频编解码、FFmpeg调用、临时文件清理、大文件IO这些环节极易在CI环境里静默失败。核心判断是:必须把「视频处理逻辑」和「文件系统行为」一起进测试闭环,否则部署后第一段MP4上传就卡住。
为什么phpunit默认跑不通视频处理测试
本地能过、CI里报错是高频现象,根本原因是环境差异没被显式约束:
- CI runner 默认不装
ffmpeg或版本太旧(比如 Ubuntu 22.04 自带的 4.4 不支持libsvtav1) -
proc_open()被禁用(GitHub Actions 默认禁用,Jenkins 某些安全插件也会拦截) - 临时目录权限不对:
/tmp可写但磁盘空间不足,或容器内挂载路径未透传 - 测试用的 MP4 文件体积过大(>5MB),导致 Git LFS 未启用或 CI 缓存超时中断
解决办法不是“加个 try-catch”,而是把依赖和约束写死在 workflow 中。
GitHub Actions 里正确启动 FFmpeg 环境
别信 “ubuntu-latest” 自带新版 FFmpeg —— 它大概率是阉割版。必须显式安装:
steps:
- uses: actions/checkout@v4
- name: Install FFmpeg
run: |
sudo apt-get update
sudo apt-get install -y ffmpeg libavcodec-extra
ffmpeg -version
- name: Run PHP tests
run: vendor/bin/phpunit --group video
env:
FFPROBE_PATH: /usr/bin/ffprobe
FFMPEG_PATH: /usr/bin/ffmpeg
关键点:
- 用
libavcodec-extra补全编码器(H.265/AV1/VP9 都靠它) - 通过
env显式传入二进制路径,避免 PHP 代码里exec('ffmpeg')找不到命令 - 加
--group video把视频相关测试单独归类,失败时不拖垮整个 test job
如何让视频测试不依赖真实大文件
上传 100MB 样本视频进 Git?不行。用 file_put_contents() 生成假 MP4?也不行——FFmpeg 会校验头部签名。正确做法是:
- 用
ffmpeg -f lavfi -i testsrc=duration=1:size=320x240:rate=10 -c:v libx264 -pix_fmt yuv420p test.mp4在 CI 中动态生成最小合法 MP4(约 20KB) - 测试代码里用
is_readable($path) && get_headers('file://' . $path)[0] === 'HTTP/1.1 200 OK'替代file_exists(),防止因文件系统延迟误判 - 清理必须显式调用:
unlink($tempFile); rmdir($tempDir);,不能靠__destruct()—— PHP-FPM 的 worker 复用会让临时文件残留
漏掉最后一点,CI 跑十次后磁盘爆满是常态。
部署阶段要防住的三个硬伤
视频处理代码上线后崩得比测试还快,往往栽在这三处:
-
upload_max_filesize和post_max_size在 php.ini 里设了,但 Nginx 的client_max_body_size没同步改,直接 413 - PHP 进程被
max_execution_time=30截断,而转码 1080p 视频至少需 90 秒 —— 必须用set_time_limit(0)且确认 SAPI 允许(CLI 允许,FPM 默认禁止) - FFmpeg 进程变成孤儿进程:PHP 主进程退出但子进程还在跑,吃光 CPU —— 必须用
proc_terminate($proc)+proc_close($proc)双保险收尾
这些不是“优化项”,是上线前必须验证的存活底线。任何一项没覆盖,第一次用户上传就会触发告警。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











