如何避免FFmpeg添加的长文本超出视频边界?
解决FFmpeg drawtext长文本自动换行且保留原坐标的问题
核心方案
利用FFmpeg drawtext滤镜的width参数限制文本宽度,配合align、valign参数控制对齐逻辑,实现长文本自动换行的同时,完全保留原x/y坐标的锚点位置,无需手动添加换行符。
具体修改步骤
- 限制文本宽度:根据原x偏移量计算文本允许的最大显示宽度,确保文本不会超出视频左边界。
- 固定对齐方式:用
align=2(右对齐)维持文本右边缘的原位置,valign=1(垂直居中)保证文本块的中心落在原y坐标上。 - 处理特殊字符:转义用户输入文本中的单引号,避免FFmpeg命令解析出错。
修改后的代码
var filterComplex = "" for (index, textData) in textDataArray.enumerated() { print("x: \(textData.xPosition), y: \(textData.yPosition)") let x = (textData.xPosition * 1080) / videoViewWidth let y = (textData.yPosition * 1920) / videoViewHeight let fontSizeForWidth = (20 * 1080) / videoViewWidth let fontSizeForHeight = (20 * 1920) / videoViewHeight print("fontSizeForWidth: \(fontSizeForWidth)") print("fontSizeForHeight: \(fontSizeForHeight)") // 转义文本中的单引号,防止FFmpeg命令解析失败 let escapedText = textData.text.replacingOccurrences(of: "'", with: "\\'") let textFilterBase = "[video\(index)]drawtext=text='\(escapedText)':fontfile=\(fontPath):fontsize=\(fontSizeForHeight):fontcolor=white:x=(main_w-\(x)):y=\(y):width=(main_w-\(x)):align=2:valign=1:line_spacing=4" if index == textDataArray.count - 1 { filterComplex += textFilterBase } else { filterComplex += "\(textFilterBase)[video\(index + 1)];" } }
参数说明
width=(main_w-\(x)):设置文本的最大可显示宽度,值为视频总宽度减去原x偏移,文本超出该宽度时自动换行,且不会越出视频左边界。align=2:将文本设置为右对齐,确保换行后的文本块右边缘仍与原坐标位置一致。valign=1:让整个文本块垂直居中于原y坐标,即使文本换行,整体的中心锚点也不会偏移。line_spacing=4:可选参数,调整多行文本的行间距,提升可读性,可根据需求修改数值。
内容的提问来源于stack exchange,提问作者Dhruvisha Joshi
相关产品推荐
相关产品推荐

