宝塔中php加水印失败主因是ffmpeg配置问题而非php版本;需确保ffmpeg路径正确、权限充足、避免中文路径/字体乱码,并在php中用绝对路径调用、显式指定二进制路径、调高执行时间和内存限制。

宝塔面板里 PHP 本身不处理水印,真正干活的是 ffmpeg;PHP 只负责拼命令、调用、等结果、检查返回码。配置失败的主因从来不是 PHP 版本,而是 ffmpeg 路径没写对、权限没放开、或中文路径/字体导致乱码。
确认 ffmpeg 是否真可用(不是“能执行”,而是“能正常跑通水印命令”)
别只信 ffmpeg -version 返回了版本号——那只能说明二进制文件存在,不代表它能读写文件、加载字体、处理透明 PNG。
- 在宝塔终端里手动运行一个最小水印命令(用绝对路径,避开中文目录):
ffmpeg -i /www/wwwroot/test/input.mp4 -i /www/wwwroot/test/logo.png -filter_complex "overlay=W-w-20:H-h-20" -c:a copy /www/wwwroot/test/output.mp4 - 如果报
Unable to find a suitable output format for 'overlay=...':说明引号被 shell 错误解析,改用单引号包裹滤镜参数 - 如果报
No such file or directory且路径明明存在:检查 nginx/php-fpm 运行用户(通常是www)是否对输入/输出目录有读写权限(chown -R www:www /www/wwwroot/test) - 如果输出视频无声:漏了
-c:a copy,音频流被默认重编码失败;加了但还无声,可能是源视频音频格式太偏门,换-c:a aac -b:a 128k
PHP 调用时必须绕开的三个坑
宝塔默认用 php-fpm 池跑 PHP,它和你终端里用 root 执行命令的环境完全不同:PATH 不一致、HOME 不一致、当前工作目录不可控。
- 永远用
exec()的完整路径调用,不要依赖PATH:/www/server/ffmpeg/bin/ffmpeg(Linux 宝塔)或D:\ffmpeg\bin\ffmpeg.exe(Windows 宝塔) - 所有文件路径必须是绝对路径,
__DIR__或$_SERVER['DOCUMENT_ROOT']开头,别用相对路径 - 中文文字水印必出乱码?不是 PHP 编码问题,是
drawtext在 Linux 下默认用 UTF-8,但字体文件路径含中文或字体本身不支持中文时崩溃;解决方案:
• 字体路径用英文(如/www/fonts/simhei.ttf)
• 字体文件提前用fc-list :lang=zh确认系统已缓存
• text 参数用 URL 编码或 base64(text='base64:5byg5aW9')
php-ffmpeg 扩展在宝塔里容易卡死的原因
很多教程推荐 composer require php-ffmpeg/php-ffmpeg,但它在宝塔里常因超时或内存限制静默失败,且默认会尝试自动探测 ffmpeg 路径(探测逻辑在宝塔环境下大概率失败)。
- 安装后必须显式指定二进制路径,不能靠自动发现:
$ffmpeg = FFMpegFFMpeg::create([ 'ffmpeg.binaries' => '/www/server/ffmpeg/bin/ffmpeg', 'ffprobe.binaries' => '/www/server/ffmpeg/bin/ffprobe' ]) - 宝塔 PHP 设置里要调高:
• 最大执行时间(max_execution_time)至少 300 秒
• 内存限制(memory_limit)建议 512M 或 -1(不限制)
• 关闭disable_functions中的exec,shell_exec,passthru,system - 扩展本身不处理并发;10 个用户同时上传视频加水印,会串行排队执行——这不是 bug,是设计如此;真要并发得自己套队列(如 Redis + Worker)
最易被忽略的一点:宝塔的“计划任务”里执行 ffmpeg 命令,和网站 PHP 执行,用的是不同用户(root vs www),所以定时任务里能跑通的命令,在网页里可能因权限失败;反过来也一样。调试前先确认当前上下文是谁在跑。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











