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

Android MediaRecorder生成无音频.m4a文件问题排查与修复

问题描述

在Android Studio中通过MediaRecorder在前台服务录制音频,成功生成.m4a文件,但播放时无音频内容。相关代码如下:

fun recAudio(context: Context) {
    if (!activeAudioRec || recordingStarted) return

    if (!hasPermission(Manifest.permission.RECORD_AUDIO)) return

    val folder = File(gFolderPath)
    if (!folder.exists()) folder.mkdirs()

    val fileName = "aud_${SimpleDateFormat("yyMMddHHmmss", Locale.getDefault()).format(Date())}.m4a"
    val file = File(folder, fileName)

    recorder = MediaRecorder().apply {
        setAudioSource(MediaRecorder.AudioSource.MIC)
        setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
        setAudioSamplingRate(44100)
        setAudioEncodingBitRate(256000)
        setOutputFile(file.absolutePath)
        prepare()
        start()
    }

    coroutineScope.launch {
        delay(saveAudiorecLength * 1000L)
        stopAudioRecording()
    }
}

已尝试操作:

  • 确认RECORD_AUDIO权限已授予
  • 确保存储文件夹存在
  • 验证saveAudiorecLength大于0
  • 尝试切换MIC、DEFAULT等不同AudioSource值

现象:生成的.m4a文件时长正常(30秒)但无音频,start()执行无异常,仅在部分Android 12+设备上出现该问题。设备为Android 12+系统,使用前台服务+MediaRecorder API。

原因分析与修复方案

1. Android 12+前台服务的麦克风权限限制

Android 12(API 31)起,前台服务访问麦克风仅靠RECORD_AUDIO权限不够,必须显式指定服务类型为FOREGROUND_SERVICE_TYPE_MICROPHONE。

修复方法:

  • 启动前台服务时,在startForeground中传入服务类型:
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
    .setContentTitle("正在录制音频")
    .setSmallIcon(R.drawable.ic_recording)
    .build()

startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE)
  • 在AndroidManifest.xml的服务声明中添加类型:
<service
    android:name=".YourRecordingService"
    android:foregroundServiceType="microphone" />

2. MediaRecorder参数兼容性问题

部分Android 12+设备对AAC编码的参数组合要求更严格,未设置声道数或比特率过高可能导致无音频。

修复方法:
在MediaRecorder配置中补充声道数,并调整比特率为通用值:

recorder = MediaRecorder().apply {
    setAudioSource(MediaRecorder.AudioSource.MIC)
    setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
    setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
    setAudioSamplingRate(44100)
    setAudioEncodingBitRate(128000) // 改用更兼容的比特率
    setAudioChannels(1) // 显式设置单声道,适配多数设备
    setOutputFile(file.absolutePath)
    prepare()
    start()
}

3. 录制停止逻辑不规范

如果stopAudioRecording()未正确调用stop()、release(),会导致文件头部写入不完整,出现有声长无音频的情况。

修复方法:
规范停止录制的逻辑:

fun stopAudioRecording() {
    try {
        recorder?.run {
            stop()
            release()
        }
        recordingStarted = false
    } catch (e: Exception) {
        e.printStackTrace()
    } finally {
        recorder = null
    }
}

同时确保停止操作在IO线程执行,避免线程安全问题:

coroutineScope.launch(Dispatchers.IO) {
    delay(saveAudiorecLength * 1000L)
    stopAudioRecording()
}

4. Android 13+存储权限缺失

Android 13(API 33)起,写入音频文件需要额外的READ_MEDIA_AUDIO权限,否则可能导致文件写入不完整。

修复方法:
在AndroidManifest.xml中添加权限:

<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<!-- 兼容Android 12及以下 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

动态申请权限时,同时检查这些权限是否已授予。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 05:39:53