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

Flutter使用ffmpeg_kit_flutter裁剪音频失败,返回returnCode 1

音频裁剪功能异常排查与修复

问题概述

音频裁剪功能无法正常工作,执行后返回returnCode 1,输出路径下无目标文件,后续操作抛出文件未找到异常。

环境信息

  • Flutter版本:3.0.2
  • Dart版本:2.17.3
  • 使用依赖包:ffmpeg_kit_flutter: ^4.5.1

输入输出路径

  • 输入文件路径:"/data/user/0/com.goonetech.v1.gofinal/cache/file_picker/sample-15s.mp3"
  • 输出文件路径:"/data/user/0/com.goonetech.v1.gofinal/app_flutter/output.mp3"

原实现代码

double start=2, 
double end=5;

String path="/data/user/0/com.goonetech.v1.gofinal/cache/file_picker/sample-15s.mp3"


static Future<String> cutAudio(String path, double start, double end) async {
  final Directory dir = await getApplicationDocumentsDirectory();
  final outPath = "${dir.path}/output.mp3";
  double start = 1;
  double end = 5;

  try {
    await File(outPath).delete();
  } catch (e) {
    print("Delete Error");
  }

  var cmd =
      "-y -i \"$path\" -vn -ss $start -to $end -ar 16k -ac 2 -b:a 96k -acodec libmp3lame $outPath";

  FFmpegKit.executeAsync(cmd, (session) async {
    final returnCode = await session.getReturnCode();
    print("returnCode $returnCode");
  });

  return outPath;
}

问题分析

  1. 参数被覆盖:函数参数start和end被内部重新赋值为1和5,导致外部传入的裁剪时间完全无效。
  2. 异步任务未等待:FFmpegKit.executeAsync是异步执行逻辑,函数直接返回outPath时,FFmpeg的裁剪任务可能还未完成,此时输出文件尚未生成,后续读取必然触发文件未找到异常。
  3. 路径引号问题:输入路径被双引号包裹,部分环境下会导致FFmpeg无法正确解析路径,找不到输入文件。
  4. 错误信息缺失:仅打印返回码,未获取FFmpeg的详细错误输出,无法精准定位问题根源。

修复方案

1. 移除参数覆盖

删除函数内部的double start = 1; double end = 5;,保留外部传入的参数值。

2. 等待FFmpeg任务完成

改用FFmpegKit.execute同步执行,确保裁剪任务完成后再返回输出路径;或者通过Completer监听异步任务状态,完成后再返回。推荐同步方式简化逻辑。

3. 修正命令行路径格式

移除输入路径的双引号,直接使用原始路径字符串。

4. 捕获详细错误日志

通过session.getErrorOutput()获取FFmpeg的执行错误信息,便于快速定位问题。

修正后的代码

double start = 2;
double end = 5;

String path = "/data/user/0/com.goonetech.v1.gofinal/cache/file_picker/sample-15s.mp3";

static Future<String> cutAudio(String path, double start, double end) async {
  final Directory dir = await getApplicationDocumentsDirectory();
  final outPath = "${dir.path}/output.mp3";

  // 尝试删除旧输出文件,忽略删除失败
  try {
    await File(outPath).delete();
  } catch (_) {}

  // 修正FFmpeg命令:移除路径引号,使用传入的裁剪参数
  var cmd = "-y -i $path -vn -ss $start -to $end -ar 16k -ac 2 -b:a 96k -acodec libmp3lame $outPath";

  // 同步执行FFmpeg任务,等待完成
  final session = await FFmpegKit.execute(cmd);
  final returnCode = await session.getReturnCode();

  if (ReturnCode.isSuccess(returnCode)) {
    print("音频裁剪成功");
    return outPath;
  } else {
    // 获取详细错误信息
    final errorLog = await session.getErrorOutput();
    print("裁剪失败,错误日志:$errorLog");
    // 抛出异常供上层处理
    throw Exception("音频裁剪失败,错误码:$returnCode,详情:$errorLog");
  }
}

额外注意事项

  • 确保应用拥有存储读写权限:Android 13+需申请READ_MEDIA_AUDIO或WRITE_EXTERNAL_STORAGE权限,iOS需在Info.plist中配置文档目录访问权限。
  • 提前验证输入文件:调用裁剪函数前,通过await File(path).exists()检查输入文件是否存在,避免因文件不存在导致的FFmpeg执行失败。
  • 裁剪精度与速度权衡:若需要高精度裁剪,可将-ss参数移至-i之后(即-i $path -ss $start -to $end),但会降低裁剪速度;反之-ss放在-i前速度更快,但精度稍低。

内容的提问来源于stack exchange,提问作者Sharath Appesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:11:25