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

Android编程实现外置存储音频裁剪及FFmpeg执行失败问题求解

Android端音频裁剪实现分步指南

现有代码错误排查

你当前执行失败的核心原因如下:

  • FFmpeg命令参数冗余错误:你裁剪的是纯音频文件,不需要指定-vcodec mpeg4视频编码参数,添加后会导致FFmpeg识别不到视频流直接返回错误
  • 音频参数配置错误:你填写的-b:a 48000比特率数值不符合常规MP3编码标准,且和后续-ar 22050采样率参数逻辑冲突
  • 存储权限适配问题:Android 10及以上版本Environment.getExternalStorageDirectory()已被官方废弃,直接读写该路径会被系统权限拦截
  • 入参未校验:你代码中original_path = path的path变量没有做空值、文件存在性校验,路径无效时必然执行失败

完整实现步骤

1. 前置配置

  • 首先在模块级build.gradle引入FFmpeg依赖:
dependencies {
    implementation 'com.arthenica:mobile-ffmpeg-full:4.4.LTS'
}
  • 在AndroidManifest.xml配置权限,适配不同系统版本:
<!-- Android 12及以下存储权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Android 13及以上音频读取权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<application
    ...
    android:requestLegacyExternalStorage="true">
</application>

注意:所有危险权限需要在代码中动态申请,仅静态声明无效

2. 修正后的业务代码

private void trimMusic(long startMs, long endMs, String fileName) {
    // 使用应用专属音乐目录,无需额外存储权限即可读写
    File folder = new File(requireContext().getExternalFilesDir(Environment.DIRECTORY_MUSIC), "MusicEditor");
    if (!folder.exists()) {
        folder.mkdirs();
    }
    String fileExt = ".mp3";
    File destFile = new File(folder, fileName + fileExt);
    // 注意此处提前校验原始音频路径是否有效、文件是否存在
    String originalPath = path;
    if (TextUtils.isEmpty(originalPath) || !new File(originalPath).exists()) {
        Toast.makeText(getActivity(), "原始音频文件不存在", Toast.LENGTH_SHORT).show();
        return;
    }

    // 修正后的纯音频裁剪FFmpeg命令
    String[] command = new String[]{
        "-ss", String.valueOf(startMs / 1000),
        "-y",
        "-i", originalPath,
        "-t", String.valueOf((endMs - startMs) / 1000),
        "-acodec", "libmp3lame",
        "-b:a", "128k",
        "-ac", "2",
        "-ar", "44100",
        destFile.getAbsolutePath()
    };
    execffmpegBinary(command);
}

private void execffmpegBinary(final String[] command) {
    // 注册日志回调,失败时可直接查看Logcat定位错误原因
    Config.enableLogCallback(message -> Log.e("FFmpeg_LOG", message.getText()));
    Log.d("FFmpeg_CMD", "执行命令:ffmpeg " + Arrays.toString(command));

    FFmpeg.executeAsync(command, (executionId, returnCode) -> {
        if (returnCode == RETURN_CODE_SUCCESS) {
            dialog.dismiss();
            Toast.makeText(getActivity(), "音频裁剪成功", Toast.LENGTH_LONG).show();
        } else if (returnCode == RETURN_CODE_CANCEL) {
            Log.d("FFmpeg_STATUS", "裁剪任务已取消");
        } else {
            Toast.makeText(getActivity(), "音频裁剪失败,请查看日志排查原因", Toast.LENGTH_LONG).show();
        }
    });
}

3. 调用方式

裁剪歌曲第2分钟到第3分钟的片段,直接调用即可:

// 时间单位为毫秒,2分钟对应120000ms,3分钟对应180000ms
trimMusic(120000, 180000, "裁剪后的歌曲名称");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:48:01