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
相关产品推荐
相关产品推荐

