php 8.5尚未发布,实际应在php 8.2/8.3中调用已安装的ffmpeg命令行,利用drawtext滤镜实现动态文字;需转义参数防注入,并推荐用ass字幕实现复杂动效。

核心思路不是用 PHP 直接“画文字”,而是调用 FFmpeg 命令行,利用其 drawtext 滤镜实现动态文字(如滚动、淡入、位置移动、字体变化等),PHP 仅负责拼接命令并执行。
确保系统已安装并可用 FFmpeg
PHP 本身不内置视频处理能力。必须确认服务器(Linux/macOS/WSL)已安装 FFmpeg,且可被 PHP 进程调用:
- 终端运行
ffmpeg -version能正常输出版本信息 - PHP 中用
exec('which ffmpeg', $out, $code)检查路径,$code === 0表示可用 - 若用 Docker,需在镜像中预装 FFmpeg(如基于
php:8.3-cli+apt-get install ffmpeg)
用 drawtext 实现常见动态文字效果
FFmpeg 的 drawtext 支持表达式(如 t 表示当前时间秒),可驱动文字坐标、透明度、缩放等实时变化。PHP 中需正确转义字符串,避免 shell 注入:
-
从左向右滚动字幕:
-vf "drawtext=fontfile=/path/to/font.ttf:fontsize=48:fontcolor=white:x=t*100:y=h/2:text='Hello World'"
(x=t*100表示每秒向右移动 100 像素) -
淡入+居中+缩放入场:
-vf "drawtext=fontfile=/path/to/font.ttf:fontsize=48:fontcolor=white@{t/3}:x=(w-text_w)/2:y=(h-text_h)/2:scale=1.0+0.5*min(t,3):text='Welcome!'"
(@{t/3}控制透明度,scale控制缩放,3 秒内完成) - 逐字显示(打字机效果)需配合外部文本文件或复杂表达式,通常建议用 ASS 字幕或分帧合成,不推荐纯 drawtext 实现
PHP 安全执行 FFmpeg 命令
切勿直接拼接用户输入到命令中。正确做法:
- 使用
escapeshellarg()对所有路径、文字内容、字体路径做转义 - 限定输入字符集(如只允许中文、英文、数字、常用标点)
- 设置超时与资源限制:
proc_open()配合timeout和memory_limit监控 - 示例片段:
$videoIn = '/var/videos/input.mp4';
$text = '动态标题';
$fontPath = '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf';
$videoOut = '/var/videos/output.mp4';
$cmd = sprintf(
'ffmpeg -i %s -vf "drawtext=fontfile=%s:fontsize=60:fontcolor=yellow@0.8:x=(w-text_w)/2:y=h-100:text=%s" -c:a copy %s -y',
escapeshellarg($videoIn),
escapeshellarg($fontPath),
escapeshellarg($text),
escapeshellarg($videoOut)
);
exec($cmd . ' 2>&1', $output, $returnCode);
if ($returnCode !== 0) {
throw new RuntimeException('FFmpeg failed: ' . implode("\n", $output));
}
进阶建议:用 FFmpeg + 字幕文件更灵活
若需多段、定时、样式丰富的动态文字(如弹幕、多语言切换),推荐生成标准字幕文件(SRT 或 ASS),再用 FFmpeg 硬编码烧录:
- SRT 简单易写,适合静态时间轴字幕
- ASS 支持位置、颜色、动效、矢量字体,
-vf "subtitles=subtitle.ass"即可加载 - PHP 可动态生成 .ass 内容(含
{\move(x1,y1,x2,y2)}、{\fad(100,100)}等控制) - 比纯 drawtext 更易维护、调试和复用
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











