如何加速FFmpeg中复杂文本叠加的处理速度
嘿,我来帮你看看怎么优化这个FFmpeg文本叠加的速度问题~你的M1 Pro+32GB配置其实完全能应付这种任务,CPU使用率低大概率是因为滤镜没充分利用多核,或者命令里有可以优化的重复逻辑。给你几个针对性的优化方向,都是我处理类似问题时试过有效的方法:
给滤镜开启多线程支持
drawtext滤镜默认是单线程运行的,这就浪费了M1 Pro的多核优势。试试添加-filter_threads参数,设置成和你CPU性能核数量一致的数值(M1 Pro有8个性能核,所以设8就行),让滤镜并行处理帧:ffmpeg -i input.mp4 \ -filter_threads 8 \ -vf "drawtext=fontfile='/path/to/font.ttf':textfile='text1.txt':\ x=(w-text_w)/2:y=(h-text_h)/2:fontsize=65:fontcolor=white@0.8:\ bordercolor=black:borderw=9:shadowcolor=black:shadowx=5:shadowy=5:\ box=1:boxcolor=black@0.2:boxborderw=20:fix_bounds=1:line_spacing=10:\ enable='between(t,0,5)',\ drawtext=fontfile='/path/to/font.ttf':textfile='text2.txt':\ x=(w-text_w)/2:y=(h-text_h)/2:fontsize=65:fontcolor=white@0.8:\ bordercolor=black:borderw=9:shadowcolor=black:shadowx=5:shadowy=5:\ box=1:boxcolor=black@0.2:boxborderw=20:fix_bounds=1:line_spacing=10:\ enable='between(t,5,10)'" \ -b:v 5000k -c:v h264_videotoolbox -threads 8 -y output.mp4合并重复的
drawtext滤镜
你现在用了两个几乎完全一样的drawtext实例,只是文本和显示时间不同,重复的滤镜会让CPU做很多冗余计算。可以合并成一个滤镜,用动态表达式根据时间切换文本,这样只需要处理一套渲染逻辑:ffmpeg -i input.mp4 \ -filter_threads 8 \ -vf "drawtext=fontfile='/path/to/font.ttf':text='%{if(between(t,0,5),%{loadtext:text1.txt},%{loadtext:text2.txt})}':\ x=(w-text_w)/2:y=(h-text_h)/2:fontsize=65:fontcolor=white@0.8:\ bordercolor=black:borderw=9:shadowcolor=black:shadowx=5:shadowy=5:\ box=1:boxcolor=black@0.2:boxborderw=20:fix_bounds=1:line_spacing=10:\ eval=frame" \ -b:v 5000k -c:v h264_videotoolbox -threads 8 -y output.mp4这里的
eval=frame会让FFmpeg每一帧都重新计算文本内容,loadtext用来读取外部文本文件,if表达式则根据当前时间t来切换显示的文本内容。用硬件加速解码,把CPU留给滤镜
你已经用了h264_videotoolbox做硬件编码,但解码默认还是用CPU,会占用部分资源。加上硬件解码参数,让解码也交给苹果的videotoolbox,这样CPU就能专注处理文本渲染:ffmpeg -c:v h264_videotoolbox -i input.mp4 \ -filter_threads 8 \ -vf "drawtext=..." \ -b:v 5000k -c:v h264_videotoolbox -threads 8 -y output.mp4可选:移除
fix_bounds(如果文本不会越界)fix_bounds=1会让FFmpeg每次计算文本位置时额外检查是否超出视频边界,如果你确定居中后的文本不会超出画面范围,可以去掉这个参数,减少不必要的计算量。
这些优化组合起来,应该能让CPU使用率上去,同时完全不影响输出质量。你可以先试试合并滤镜+多线程的组合,这两个是提升最明显的~
备注:内容来源于stack exchange,提问作者mlika

