You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AI生成SRT字幕硬烧录视频失败:FFmpegKit字体缺失问题解决

解决FFmpeg硬编码字幕时找不到字体的问题

核心问题分析

从执行日志可明确错误根源:

[Parsed_drawtext_0 @ 0xb4000077140d5380] Cannot find a valid font for the family Sans

Android环境下的FFmpeg无法直接调用系统默认字体库,必须显式指定字体文件路径才能让drawtext滤镜正常工作。此外,原代码直接将interval的时间字符串传入between(t, ...)也存在格式问题——该函数需要秒数数值,而非0:00:00.000这类时间格式。

解决方案

1. 指定系统内置字体路径

Android系统通常自带Roboto字体,固定路径为/system/fonts/Roboto-Regular.ttf,可直接在drawtext参数中指定该路径。

2. 转换时间格式为秒数

将interval中的时间字符串(如0:00:00.000)转换为秒数格式,例如:

  • 0:00:00.000 → 0.0
  • 0:00:04.000 → 4.0

3. 修正后的Dart代码

Future<void> saveSubtitle() async {
  emit(ExportSubtitleLoading());
  String subtitleFilter = "";
  // Android系统Roboto字体固定路径
  const fontPath = "/system/fonts/Roboto-Regular.ttf";

  for (var subtitle in subtitles!.fotmatedSubtitle!) {
    // 转换时间字符串为秒数
    final startTimeSec = _convertTimeToSeconds(subtitle.interval![0]);
    final endTimeSec = _convertTimeToSeconds(subtitle.interval![1]);
    String text = subtitle.displayText!;
    // 转义文本中的单引号,避免FFmpeg命令解析错误
    text = text.replaceAll("'", "\\'");
    
    subtitleFilter +=
        "drawtext=text='$text':enable='between(t,$startTimeSec,$endTimeSec)':x=(w-text_w)/2:y=h-30:fontsize=24:fontcolor=white:fontfile='$fontPath',";
  }
  // 移除滤镜字符串末尾多余的逗号
  if (subtitleFilter.isNotEmpty) {
    subtitleFilter = subtitleFilter.substring(0, subtitleFilter.length - 1);
  }

  final dir = await getTemporaryDirectory();
  String outputPath = '${dir.path}/ex_vid.mp4';
  final arguments = [
    '-y', // 自动覆盖已存在的输出文件
    '-i',
    inputFile,
    '-vf',
    subtitleFilter,
    '-c:v',
    'libx264',
    '-c:a',
    'copy',
    outputPath
  ];

  await FFmpegKit.executeWithArguments(arguments).then((session) async {
    final returnCode = await session.getReturnCode();

    if (ReturnCode.isSuccess(returnCode)) {
      ('The Conversion is Success').logger;
      emit(ExportSubtitleSuccess());
    } else if (ReturnCode.isCancel(returnCode)) {
      ('The Conversion is Cancelled').logger;
    } else {
      emit(ExportSubtitleerror());
      ('The Conversion Have an Error').logger;
      // 打印详细日志辅助排查
      final logs = await session.getAllLogsAsString();
      logs.logger;
    }
  });
}

// 辅助函数:将时间字符串转换为秒数
double _convertTimeToSeconds(String timeStr) {
  final parts = timeStr.split(':');
  final hours = double.parse(parts[0]);
  final minutes = double.parse(parts[1]);
  final seconds = double.parse(parts[2]);
  return hours * 3600 + minutes * 60 + seconds;
}

额外说明

  • 若系统中无Roboto字体,可将自定义字体文件(如.ttf格式)打包到APP的assets目录,通过getApplicationDocumentsDirectory()获取字体路径后传入滤镜。
  • 使用executeWithArguments而非字符串拼接执行命令,可避免手动处理引号转义的风险,提升命令执行稳定性。

内容的提问来源于stack exchange,提问作者abdallah mostafa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 20:14:56