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

Android端如何同时实现实时语音转文本与本地音频录制保存?

Android 同时实现语音转文本与本地音频保存的解决方案

核心问题在于Android的音频输入资源是独占的,AudioRecord和SpeechRecognizer会争抢同一麦克风输入,所以无法同时运行。下面给出两种低成本、无需依赖付费云服务的可行方案:

方案一:复用AudioRecord的音频数据,同时做录制和离线识别

用AudioRecord捕获原始PCM音频数据,一边将数据写入本地文件(可封装为WAV格式),一边把实时数据喂给离线语音识别引擎(比如开源的CMU Sphinx),这样只占用一次音频输入资源。

关键步骤:

  1. 初始化AudioRecord,配置统一的音频参数(建议用16kHz单声道16bit PCM,适配多数离线引擎)。
  2. 在录制循环中,读取PCM数据:
    • 将数据写入本地文件(如果要保存为WAV,需要先写入WAV文件头,再追加PCM数据)。
    • 将数据传入离线识别引擎的输入流,实时解析识别结果。

代码片段示例:

// 初始化AudioRecord
int sampleRate = 16000;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, channelConfig, audioFormat, bufferSize);

// 初始化离线识别引擎(以CMU Sphinx为例)
SpeechRecognizer recognizer = SpeechRecognizerSetup.defaultSetup()
        .setAcousticModel("resource:/edu/cmu/sphinx/models/en-us/en-us")
        .setDictionary("resource:/edu/cmu/sphinx/models/en-us/cmudict-en-us.dict")
        .getRecognizer();
recognizer.addListener(new RecognitionListener() {
    @Override
    public void onResult(Result result) {
        // 处理识别结果
        String text = result.getHypothesis();
    }
});

// 开始录制和识别
audioRecord.startRecording();
recognizer.startListening();

byte[] buffer = new byte[bufferSize];
FileOutputStream fos = new FileOutputStream(new File(getExternalFilesDir(null), "recording.pcm"));

while (isRecording) {
    int read = audioRecord.read(buffer, 0, bufferSize);
    if (read > 0) {
        // 写入本地文件
        fos.write(buffer, 0, read);
        // 将音频数据喂给识别引擎
        recognizer.processRaw(buffer, 0, read, false, false);
    }
}

// 停止录制和识别
audioRecord.stop();
audioRecord.release();
recognizer.stopListening();
fos.close();

方案二:通过SpeechRecognizer回调获取音频数据并保存

部分Android设备的SpeechRecognizer支持通过额外参数获取识别过程中的原始音频数据,这样可以省去单独用AudioRecord录制的步骤,直接在识别回调中保存音频。

关键步骤:

  1. 启动识别时,添加EXTRA_GET_AUDIO_FORMAT和EXTRA_GET_AUDIO_DATA参数。
  2. 在onResults或onPartialResults回调中,获取音频数据并写入本地文件。

代码片段示例:

Intent recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
// 添加获取音频数据的参数
recognizerIntent.putExtra(RecognizerIntent.EXTRA_GET_AUDIO_FORMAT, "audio/amr");
recognizerIntent.putExtra(RecognizerIntent.EXTRA_GET_AUDIO_DATA, true);

SpeechRecognizer speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context);
speechRecognizer.setRecognitionListener(new RecognitionListener() {
    @Override
    public void onResults(Bundle results) {
        // 获取识别结果
        ArrayList<String> matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        // 获取音频数据并保存
        byte[] audioData = results.getByteArray(SpeechRecognizer.EXTRA_AUDIO_DATA);
        if (audioData != null) {
            try {
                FileOutputStream fos = new FileOutputStream(new File(getExternalFilesDir(null), "recording.amr"));
                fos.write(audioData);
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 实现其他回调方法...
});

speechRecognizer.startListening(recognizerIntent);

注意事项:

  • 该方案的兼容性有限,部分设备或系统版本可能不支持EXTRA_GET_AUDIO_DATA参数,需要提前做兼容性判断。
  • 保存的音频格式由EXTRA_GET_AUDIO_FORMAT指定,通常支持audio/amr或audio/wav。

额外提示

  • 权限:确保已申请RECORD_AUDIO权限,以及Android 13及以上版本的WRITE_MEDIA_AUDIO/READ_MEDIA_AUDIO权限,Android 12及以下的WRITE_EXTERNAL_STORAGE权限。
  • 离线引擎选择:CMU Sphinx完全开源免费,支持多语言,但识别精度可能略低于云服务;也可以尝试设备厂商自带的离线语音识别能力(如小米、华为的内置ASR),需参考各自厂商的开发文档。
  • 音频格式一致性:无论是录制还是识别,务必保持采样率、声道数、位深等参数一致,否则会导致识别失败或音频文件损坏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 12:52:46