Flutter中使用FFmpeg给视频添加文本报错(返回码1)求助
解决Flutter中FFmpeg添加文本返回错误码1的问题
错误码1通常意味着FFmpeg命令解析失败或执行时遇到基础错误,结合你的代码,主要问题集中在命令字符串语法、权限和FFmpeg组件完整性上,以下是具体修复步骤:
1. 修复命令字符串的引号嵌套问题
你的命令中text='MY_TEXT'的单引号和外层双引号冲突,导致FFmpeg无法正确解析参数。需要转义内部引号或调整引号使用方式:
String command = '-y -i "$videoPath" -filter_complex "[0]scale=540:-1[s];[s]drawtext=fontfile=/storage/emulated/0/Download/SuperDessert.ttf:text=\\"MY_TEXT\\":fontsize=24:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2" "${output.path}"';
或者使用Dart原始字符串(前缀r)避免转义:
String command = r'-y -i "$videoPath" -filter_complex "[0]scale=540:-1[s];[s]drawtext=fontfile=/storage/emulated/0/Download/SuperDessert.ttf:text=\"MY_TEXT\":fontsize=24:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2" "${output.path}"';
同时给输入输出路径加上双引号,避免路径含空格时解析失败。
2. 解决字体文件的权限问题
Android 10及以上版本直接访问外部Download目录需要额外权限:
- 在
AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
- 在代码中动态申请权限(可使用
permission_handler包),确保应用获得权限后再执行FFmpeg命令。
更稳妥的方式是将字体文件放到应用内部存储目录,避免权限问题:
// 假设字体文件已复制到应用的files目录 final fontPath = '${(await getApplicationDocumentsDirectory()).path}/SuperDessert.ttf'; // 替换命令中的fontfile路径 String command = '-y -i "$videoPath" -filter_complex "[0]scale=540:-1[s];[s]drawtext=fontfile=$fontPath:text=\\"MY_TEXT\\":fontsize=24:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2" "${output.path}"';
3. 确保FFmpeg Kit包含drawtext滤镜
ffmpeg_kit_flutter的minimal版本不包含drawtext滤镜,需要在pubspec.yaml中使用full版本:
dependencies: ffmpeg_kit_flutter_full: ^5.1.0
修正后的完整代码示例
import 'dart:io'; import 'package:ffmpeg_kit_flutter_full/ffmpeg_kit.dart'; import 'package:ffmpeg_kit_flutter_full/return_code.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'dart:developer' as dev; // 先申请权限 Future<void> requestPermissions() async { if (await Permission.storage.isDenied) { await Permission.storage.request(); } if (await Permission.manageExternalStorage.isDenied && Platform.isAndroid) { await Permission.manageExternalStorage.request(); } } Future<void> addTextToVideo() async { await requestPermissions(); final videoPath = _controller.file.path; final outputName = videoPath.hashCode.toString(); final output = File('${(await getTemporaryDirectory()).path}/$outputName.mp4'); // 使用内部存储的字体文件,或确保外部存储权限已获取 final fontPath = '/storage/emulated/0/Download/SuperDessert.ttf'; String command = '-y -i "$videoPath" -filter_complex "[0]scale=540:-1[s];[s]drawtext=fontfile=$fontPath:text=\\"MY_TEXT\\":fontsize=24:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2" "${output.path}"'; final session = await FFmpegKit.execute(command); final returnCode = await session.getReturnCode(); if (ReturnCode.isSuccess(returnCode)) { dev.log("Success full text added"); } else { dev.log("Error adding text: ${await session.getFailStackTrace()}"); // 打印FFmpeg输出辅助排查 dev.log("FFmpeg output: ${await session.getOutput()}"); } }
内容的提问来源于stack exchange,提问作者Aiman
相关产品推荐
相关产品推荐

