FFmpeg使用drawtext的between滤镜定时添加文本失效问题求助
我来帮你分析下FFmpeg命令出问题的原因,以及对应的修复方案:
核心问题分析
你的命令出现两个异常:between(t,0,1)对应的文本持续显示,between(t,1,2)的文本不显示,大概率是引号解析错误或者区间逻辑的误解导致的:
引号解析问题(常见于Windows环境)
如果你是在Windows命令提示符(cmd)里执行这个命令,单引号'不会被系统当作引号解析,导致enable='between(t,0,1)'被FFmpeg理解为enable=between(t,0,1)——FFmpeg会把这个整个字符串视为非空值,直接判定为真,所以对应的文本会一直显示。而第一个drawtext的enable表达式同样被错误解析,但可能因为你的视频在1-2秒区间的帧没有被正确触发(或者被第二个drawtext覆盖),导致完全不显示。between函数的区间逻辑误解
FFmpeg的between(t, a, b)是闭区间判断(即t >= a 且 t <= b),这意味着between(t,0,1)会在t=1秒的瞬间仍然显示文本,而between(t,1,2)会在t=2秒时还在显示。这和你“仅显示1秒”的预期(左闭右开区间:0<=t<1和1<=t<2)有差异。
修复后的命令
方案1:修正多drawtext的区间与引号
根据你的需求,我调整了区间逻辑,并适配不同操作系统的引号规则:
Linux/macOS Shell环境:
ffmpeg -y -i public/media/vid1.mp4 -vf "drawtext=text='1':x=w-tw-50:y=50:fontcolor=black:fontsize=380:enable='gte(t,1)*lt(t,2)',drawtext=text='2':x=w-tw-50:y=50:fontcolor=black:fontsize=380:enable='lt(t,1)'" -codec:a copy public/media/vid1-1.mp4这里用
gte(t,1)*lt(t,2)表示t>=1 且 t<2,lt(t,1)表示t<1,更精准匹配你的时间区间需求,同时用单引号正确包裹enable表达式。Windows CMD环境:
ffmpeg -y -i public/media/vid1.mp4 -vf "drawtext=text='1':x=w-tw-50:y=50:fontcolor=black:fontsize=380:enable=\"gte(t,1)*lt(t,2)\",drawtext=text='2':x=w-tw-50:y=50:fontcolor=black:fontsize=380:enable=\"lt(t,1)\"" -codec:a copy public/media/vid1-1.mp4Windows cmd不支持单引号包裹表达式,所以用转义双引号
\"来包裹enable的逻辑表达式。
方案2:更简洁的动态文本生成
如果你只是想每秒显示对应的递增数字(比如0-1秒显示1,1-2秒显示2,以此类推),完全不需要多个drawtext,用一个drawtext结合表达式动态生成文本即可:
# Linux/macOS版本 ffmpeg -y -i public/media/vid1.mp4 -vf "drawtext=text='%{eif:t:floor+1}':x=w-tw-50:y=50:fontcolor=black:fontsize=380" -codec:a copy public/media/vid1-1.mp4 # Windows CMD版本 ffmpeg -y -i public/media/vid1.mp4 -vf "drawtext=text='%{eif:t:floor+1}':x=w-tw-50:y=50:fontcolor=black:fontsize=380" -codec:a copy public/media/vid1-1.mp4
这里%{eif:t:floor+1}的意思是:取当前时间t的整数部分(floor(t))再加1,自动匹配每秒的数字,比多个drawtext高效得多。
内容的提问来源于stack exchange,提问作者HUNG

