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

在Android Studio中如何修剪音乐文件?求可用库及实现方法

Android 音乐文件裁剪实现方案

方法一:使用Android原生API(MediaExtractor + MediaMuxer)

无需依赖第三方库,通过系统原生媒体API实现裁剪,适合不想引入额外依赖的场景。

核心逻辑

  1. 用MediaExtractor读取源音频,定位到音频轨道;
  2. 将裁剪时间转换为毫秒(比如30秒=30000ms、50秒=50000ms),定位到起始时间点;
  3. 用MediaMuxer创建输出文件,将截取的音频数据写入新文件,直到达到结束时间。

代码示例

import android.media.MediaExtractor
import android.media.MediaFormat
import android.media.MediaMuxer
import java.io.IOException

fun trimAudio(sourcePath: String, outputPath: String, startMs: Long, endMs: Long) {
    val extractor = MediaExtractor()
    var muxer: MediaMuxer? = null
    var trackIndex = -1
    var sampleTime: Long

    try {
        extractor.setDataSource(sourcePath)
        // 遍历找到音频轨道
        for (i in 0 until extractor.trackCount) {
            val format = extractor.getTrackFormat(i)
            val mime = format.getString(MediaFormat.KEY_MIME)
            if (mime?.startsWith("audio/") == true) {
                trackIndex = i
                extractor.selectTrack(i)
                // 初始化MediaMuxer准备写入
                muxer = MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
                val muxerTrackIndex = muxer.addTrack(format)
                muxer.start()
                break
            }
        }

        if (trackIndex == -1) throw IOException("源文件中未找到音频轨道")

        // 定位到裁剪起始时间点
        extractor.seekTo(startMs, MediaExtractor.SEEK_TO_CLOSEST_SYNC)

        val buffer = ByteArray(1024 * 1024)
        while (true) {
            sampleTime = extractor.sampleTime
            // 超过结束时间则停止
            if (sampleTime > endMs) break
            val sampleSize = extractor.readSampleData(buffer, 0)
            if (sampleSize < 0) break

            val bufferInfo = MediaMuxer.OutputBufferInfo().apply {
                offset = 0
                size = sampleSize
                presentationTimeUs = sampleTime
                flags = extractor.sampleFlags
            }

            muxer?.writeSampleData(0, buffer, bufferInfo)
            extractor.advance()
        }
    } catch (e: IOException) {
        e.printStackTrace()
    } finally {
        extractor.release()
        muxer?.stop()
        muxer?.release()
    }
}

// 调用示例:截取30秒到50秒的片段
trimAudio(
    sourcePath = "/sdcard/Music/source.mp3",
    outputPath = "/sdcard/Music/trimmed.mp3",
    startMs = 30 * 1000,
    endMs = 50 * 1000
)

方法二:使用FFmpeg第三方库

如果原生API对部分格式支持有限,FFmpeg是兼容性更强的选择,支持几乎所有音频格式。

步骤

  1. 引入FFmpeg的Android封装库;
  2. 执行裁剪命令,指定起始/结束时间和输出路径。

代码示例

首先在build.gradle中添加依赖:

dependencies {
    implementation 'com.arthenica:ffmpeg-kit-full:5.1.LTS'
}

执行裁剪逻辑:

import com.arthenica.ffmpegkit.FFmpegKit
import com.arthenica.ffmpegkit.FFmpegSession

fun trimAudioWithFFmpeg(sourcePath: String, outputPath: String, startSec: Int, endSec: Int) {
    // -ss 指定起始时间,-to 指定结束时间,-c copy 直接复制编码(快速无损失)
    val command = "-i $sourcePath -ss $startSec -to $endSec -c copy $outputPath"

    val session = FFmpegKit.execute(command)
    when (session.returnCode.value) {
        0 -> {
            // 裁剪成功
        }
        else -> {
            // 错误处理,可通过session.failStackTrace获取详情
        }
    }
}

// 调用示例
trimAudioWithFFmpeg(
    sourcePath = "/sdcard/Music/source.mp3",
    outputPath = "/sdcard/Music/trimmed_ffmpeg.mp3",
    startSec = 30,
    endSec = 50
)

注意事项

  • 权限申请:Android 13及以上需申请READ_MEDIA_AUDIO和WRITE_EXTERNAL_STORAGE(针对公共存储目录),并做好动态权限申请;
  • 格式适配:原生API对小众格式支持有限,FFmpeg兼容性更优;
  • 性能差异:原生API更轻量,FFmpeg功能全但会增加APK体积。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:36:32