Flutter合并两段视频并播放:Android下FFmpeg返回码1问题解决
解决Flutter中FFmpeg合并视频Android返回码1的问题
先查FFmpeg日志(最关键)
返回码1是FFmpeg的通用错误标识,必须先获取详细日志才能精准定位问题。修改代码添加日志监听:
// 初始化阶段添加日志回调 ffmpeg.enableLogCallback((log) { print("FFmpeg Log: ${log.message}"); }); ffmpeg.enableStatisticsCallback((stats) { print("FFmpeg Stats: ${stats.toString()}"); }); // 执行命令部分保留原有逻辑,补充错误打印 await ffmpeg.execute(commandToExecute).then((rc) { if (rc == 0) { latest = output; } else { print("FFmpeg执行失败,返回码: $rc"); } });
从日志中可以直接看到具体错误原因,比如视频参数不匹配、文件找不到、滤镜组件缺失等。
常见问题及对应解决方法
1. 两段视频参数不匹配
concat滤镜要求两段视频的分辨率、帧率、编码格式、像素格式完全一致,参数不符会直接导致合并失败。
- 解决方法:
方案一:先统一两段视频参数再合并。先通过ffprobe获取第一段视频的参数,再将第二段视频转码为相同参数:
方案二:改用// 示例:将第二段视频转码为和第一段一致的1080p、30fps、H.264编码 String transcodeCmd = '-i $compress -c:v libx264 -crf 23 -s 1920x1080 -r 30 -pix_fmt yuv420p temp_compress.mp4'; await ffmpeg.execute(transcodeCmd); // 后续用temp_compress.mp4参与合并concat demuxer(无需参数完全一致,仅需格式兼容):// 先创建文本文件存储视频列表 String listPath = "${rootPath}_video_list.txt"; await File(listPath).writeAsString("file '$latest'\nfile '$compress'"); // 执行合并命令 String mergeCmd = '-f concat -safe 0 -i $listPath -c copy $output'; await ffmpeg.execute(mergeCmd);-safe 0用于允许使用绝对路径,避免路径权限校验失败。
2. 命令引号转义问题
Android Shell对单引号的解析逻辑和其他平台不同,原命令中的单引号可能导致滤镜参数被错误解析。
- 解决方法:去掉单引号直接编写滤镜,或给带空格的路径包裹双引号:
// 调整命令写法,处理路径空格和转义问题 String commandToExecute = '-i "$latest" -i "$compress" -filter_complex [0:0][1:0]concat=n=2:v=1:a=0[out] -map [out] "$output"';
3. Flutter FFmpeg包组件缺失
如果使用的是基础版flutter_ffmpeg,可能缺少concat滤镜依赖的组件。
- 解决方法:改用全功能版依赖,修改
pubspec.yaml:
执行dependencies: flutter_ffmpeg: ^0.4.0 flutter_ffmpeg_kit_full: ^4.5.1-LTSflutter pub get重新安装依赖。
4. Android文件权限问题
若视频路径位于外部存储,需确保已申请读写权限,Android 10+还要注意Scoped Storage限制。
- 解决方法:
- 在
AndroidManifest.xml中添加权限声明:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>- 用
permission_handler包动态申请权限,确保执行FFmpeg前权限已通过。
- 在
5. 输出路径无写入权限
若输出路径是外部存储根目录或系统受限目录,会导致写入失败。
- 解决方法:改用应用专属存储路径:
import 'package:path_provider/path_provider.dart'; final appDir = await getApplicationDocumentsDirectory(); var output = "${appDir.path}/merged_${DateTime.now().microsecondsSinceEpoch}_M3.mp4";
内容的提问来源于stack exchange,提问作者rt_elf
相关产品推荐
相关产品推荐

