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

React Native中react-native-voice与expo-speech协同异常问题求助

问题:react-native-voice 与 expo-speech 音频冲突

我用 react-native-voice 实现语音转写功能,同时用 expo-speech 做文本转语音,但遇到了音频冲突问题:结束语音录制后调用 expo-speech 播放时完全没有声音,看起来 react-native-voice 在结束录音后把音频通道静音了——明明语音已经开始播放,却必须重新按下麦克风按钮激活语音识别才能听到声音。

我试过的临时方案是等文本转语音结束后再停止录音,但这种方式存在大量边缘情况,没法投入正式使用。所有常规停止录音的方法都解决不了这个问题,库文档里也找不到相关说明,求可行的解决方案。

附当前核心代码:

语音识别相关函数

const startRecognizing = async () => {
  setButtonColor('#38b000');
  // 启动对应语种的语音识别
  try {
    await Voice.start('en-EN');
  } catch (e) {
    console.error(e);
  }
};

const destroyRecognizer = async () => {
  // 销毁当前语音识别实例
  try {
    await Voice.destroy();
  } catch (e) {
    console.error(e);
  }
};

const stopRecognizing = async () => {
  setButtonColor('#344E41');
  setTimeout(() => {
    Speech.speak("I did not understand, can you repeat please ?", {
      language: 'en-EN',
      onDone: () => {
        setTimeout(
          async() => {
            await destroyRecognizer();
          }, 1000);
      },
    });
  }, 1000);
};

UI 部分代码

return (
  <View style={styles.microphoneButtonContainer}>
      <TouchableOpacity
      onPressIn={startRecognizing}
      onPressOut={stopRecognizing}>
      <Image
          style={styles.microphoneButton}
          source={require('../img/microphone-icon.png')}
          />
      </TouchableOpacity>
  </View>
);

可行解决方案

1. 按正确顺序释放音频资源

问题根源是 react-native-voice 占用音频输入设备后,未正确释放或切换音频会话模式,导致 expo-speech 的输出被阻塞。正确流程应该是:先停止识别,等待资源释放后再播放语音,最后销毁识别实例。

修改后的 stopRecognizing 函数:

const stopRecognizing = async () => {
  setButtonColor('#344E41');
  try {
    // 先停止识别,而非直接销毁实例
    await Voice.stop();
    // 短暂等待资源释放后启动播放
    setTimeout(() => {
      Speech.speak("I did not understand, can you repeat please ?", {
        language: 'en-EN',
        onDone: () => {
          // 播放完成后再销毁识别实例
          destroyRecognizer();
        },
      });
    }, 500);
  } catch (e) {
    console.error(e);
    // 出错时兜底播放语音
    Speech.speak("I did not understand, can you repeat please ?", {
      language: 'en-EN',
    });
  }
};

2. 手动切换音频会话模式(iOS 专属)

iOS 上音频会话模式切换需要手动干预,可以借助 expo-av 的 Audio 模块重置音频会话:

首先安装依赖:

npx expo install expo-av

然后修改停止识别逻辑:

import { Audio } from 'expo-av';

const stopRecognizing = async () => {
  setButtonColor('#344E41');
  try {
    await Voice.stop();
    // 重置音频会话为播放模式
    await Audio.setAudioModeAsync({
      allowsRecordingIOS: false,
      playsInSilentModeIOS: true,
      shouldDuckAndroid: true,
    });
    Speech.speak("I did not understand, can you repeat please ?", {
      language: 'en-EN',
      onDone: async () => {
        await destroyRecognizer();
        // 如果后续还要录音,记得切回录音模式
        await Audio.setAudioModeAsync({
          allowsRecordingIOS: true,
        });
      },
    });
  } catch (e) {
    console.error(e);
    Speech.speak("I did not understand, can you repeat please ?", {
      language: 'en-EN',
    });
  }
};

3. 优化麦克风触发逻辑

onPressOut 可能因手势触发时机问题导致资源释放不及时,建议改成用 onPress 配合状态控制录音启停:

import { Audio } from 'expo-av';

// 用状态控制录音状态
const [isRecording, setIsRecording] = useState(false);

const handleMicPress = async () => {
  if (isRecording) {
    // 停止录音逻辑
    setIsRecording(false);
    setButtonColor('#344E41');
    try {
      await Voice.stop();
      await Audio.setAudioModeAsync({ allowsRecordingIOS: false });
      Speech.speak("I did not understand, can you repeat please ?", {
        language: 'en-EN',
        onDone: async () => {
          await destroyRecognizer();
        },
      });
    } catch (e) {
      console.error(e);
    }
  } else {
    // 开始录音逻辑
    setIsRecording(true);
    setButtonColor('#38b000');
    try {
      await Audio.setAudioModeAsync({ allowsRecordingIOS: true });
      await Voice.start('en-EN');
    } catch (e) {
      console.error(e);
    }
  }
};

// UI 部分改成 onPress 触发
return (
  <View style={styles.microphoneButtonContainer}>
      <TouchableOpacity onPress={handleMicPress}>
      <Image
          style={styles.microphoneButton}
          source={require('../img/microphone-icon.png')}
          />
      </TouchableOpacity>
  </View>
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 13:40:47