Fluent-ffmpeg随机丢失添加文本问题排查求助
可能的原因
字体依赖不确定性
代码中注释了fontfile参数,ffmpeg会自动使用系统默认字体,但不同运行环境的默认字体可能不同,甚至同一环境下字体加载也可能出现随机异常。这会导致text_w/text_h的计算偏差,要么文本位置超出视频可视区域(看起来像丢失),要么滤镜参数解析失败触发无效输入错误。文本内容未转义
如果thoughts中的字符串包含特殊字符(比如单引号、双引号、反斜杠),会直接破坏ffmpeg drawtext滤镜的参数语法,导致部分滤镜解析失败,出现随机丢文本或错误。滤镜表达式运算优先级问题
x坐标的表达式(main_w${left ? "*0.3" : "*0.7"}-text_w/2)没有明确的运算优先级包裹,ffmpeg可能会错误解析运算顺序,导致文本位置偏移或参数计算错误。异步流程中的潜在竞态
虽然测试数组正常,但动态生成的thoughts如果在异步处理中存在变量状态异常(比如index/left变量在循环中被意外修改),也可能导致滤镜参数错误。
解决办法
1. 强制指定字体文件
取消fontfile的注释,使用绝对路径指定字体文件,确保ffmpeg每次使用一致的字体,避免系统字体带来的不确定性:
options: { fontfile: '/absolute/path/to/font.ttf', // 替换为实际绝对路径 text: title, // 其他参数不变 }
2. 转义文本中的特殊字符
对要渲染的文本内容进行转义,避免破坏ffmpeg的参数语法,比如封装一个转义函数:
function escapeFFmpegText(text) { return text.replace(/'/g, "\\'").replace(/"/g, '\\"'); }
然后在设置text参数时使用:
text: escapeFFmpegText(string),
3. 修正滤镜表达式的运算优先级
给x坐标的表达式加上明确的括号,确保运算顺序正确:
x: `((main_w * ${left ? 0.3 : 0.7}) - text_w/2)`,
4. 增加错误捕获与调试
为fluent-ffmpeg添加错误监听,捕获具体的ffmpeg错误信息,方便定位问题:
video.on('error', (err) => { console.error('FFmpeg执行错误:', err.message); console.error('当前滤镜链:', JSON.stringify(filters, null, 2)); });
5. 限制文本位置不超出视频范围
如果yoffset超过视频高度,文本会被渲染到可视区域外,看起来像丢失。可以先通过ffprobe获取视频高度,再动态计算y的最大值:
// 先获取视频信息 ffmpeg.ffprobe('path/to/video.mp4', (err, metadata) => { if (err) throw err; const videoHeight = metadata.streams[0].height; // 后续生成filters时,限制yoffset let yoffset = 130 + (130*(index+1)) + (line*20); yoffset = Math.min(yoffset, videoHeight - 20); // 留20px边距 yoffset = Math.max(yoffset, 0); });
内容的提问来源于stack exchange,提问作者ToborWinner

