You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用MediaRecorder.AudioSource.REMOTE_SUBMIX创建对象触发AudioRecord未初始化崩溃

解决MediaRecorder.AudioSource.REMOTE_SUBMIX导致的AudioRecord未初始化崩溃

先抓崩溃的核心栈信息,一眼就能锁定问题根源:

java.lang.IllegalStateException: 对未初始化的AudioRecord调用了startRecording()。
at android.media.AudioRecord.startRecording(AudioRecord.java:649)
at net.yrom.screenrecorder.core.RESAudioClient.start(RESAudioClient.java:48)
at net.yrom.screenrecorder.ui.activity.ScreenRecordActivity.onActivityResult(ScreenRecordActivity.java:127)

这个问题几乎都是因为REMOTE_SUBMIX这个音频源的特殊性导致的,下面给你拆解原因和解决办法:

1. 你可能没搞懂REMOTE_SUBMIX的权限门槛

这个音频源是系统级别的,普通应用根本用不了,必须满足两个硬条件:

  • 你的应用必须用平台证书签名,成为系统应用
  • 必须声明两个权限:android.permission.RECORD_AUDIOandroid.permission.CAPTURE_AUDIO_OUTPUT(注意后者是系统权限,普通应用在Manifest里加了也没用,必须是系统应用才能获取)

如果你的应用不是系统应用,别折腾了,直接换成MediaRecorder.AudioSource.MIC这类普通应用能访问的音频源就行。

2. AudioRecord初始化后没做状态检查

看你代码里是直接调用startRecording(),但没判断AudioRecord是不是真的初始化成功了。赶紧在RESAudioClient里加个检查:

// 初始化AudioRecord的代码段
int minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.REMOTE_SUBMIX, sampleRate, channelConfig, audioFormat, minBufferSize);

// 加这行检查,初始化失败直接抛错或者处理,别硬启动
if (audioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
    throw new IllegalStateException("AudioRecord初始化失败,无法使用REMOTE_SUBMIX音频源");
    // 或者换成友好提示:比如Toast告知用户无法录制系统音频
}

3. 系统版本不兼容

REMOTE_SUBMIX是Android 5.0(API 21)才引入的,如果你在低于这个版本的设备上跑,肯定初始化失败。加个版本判断:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    Toast.makeText(context, "设备系统版本过低,无法录制系统音频", Toast.LENGTH_SHORT).show();
    return;
}

4. 音频参数配置不对

采样率、声道、格式如果不被设备支持,也会导致AudioRecord初始化失败。试试用通用兼容参数:

int sampleRate = 44100; // 大部分设备支持的采样率
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

或者直接拿系统输出的参数来用,兼容性更好:

AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
String sampleRateStr = audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
int sampleRate = Integer.parseInt(sampleRateStr);

最后提个醒

就算你满足了所有条件,有些定制ROM可能会砍掉REMOTE_SUBMIX的支持,所以一定要多测几款设备。另外,在onActivityResult里启动录制前,别着急调用start(),先把所有初始化检查做完再执行。

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

火山引擎 最新活动