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

Expo v50+环境下如何实现录音自动停止功能?

解决方案:Expo v50+ 实现语音自动停止录音

核心思路

通过监听录音过程中的实时音量数据,设置静音阈值和静音持续时长,当检测到用户停止说话(音量低于阈值且持续足够时间)时,自动触发录音停止逻辑,完全基于用户实际说话时长控制录音长度。

实现步骤

  1. 配置录音实例并开启音量监听
    基于expo-av的Audio.Recording类,启动录音后通过addProgressListener实时获取音频分贝数据。

  2. 设置静音判断逻辑

    • 定义静音阈值(可根据场景调整,比如-20dB,值越小代表越安静)
    • 记录静音开始时间,当音量持续低于阈值超过设定时长(比如1.5秒),执行停止录音操作。
  3. 完整代码示例

import { Audio } from 'expo-av';
import { useState, useEffect } from 'react';

export default function AutoStopRecorder() {
  const [recording, setRecording] = useState(null);
  const [isRecording, setIsRecording] = useState(false);
  // 静音阈值(单位:dB)
  const SILENCE_THRESHOLD = -20;
  // 静音持续触发停止的时长(单位:ms)
  const SILENCE_TRIGGER_DURATION = 1500;
  let silenceStartTime = null;

  // 请求录音权限
  useEffect(() => {
    async function requestPermissions() {
      const { status } = await Audio.requestPermissionsAsync();
      if (status !== 'granted') {
        alert('需要授予录音权限才能使用此功能');
      }
    }
    requestPermissions();
    // 组件卸载时清理录音实例
    return () => {
      if (recording) {
        recording.stopAndUnloadAsync();
      }
    };
  }, []);

  const startRecording = async () => {
    try {
      await Audio.setAudioModeAsync({
        allowsRecordingIOS: true,
        playsInSilentModeIOS: true,
      });

      const newRecording = new Audio.Recording();
      await newRecording.prepareToRecordAsync(
        Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY
      );
      await newRecording.startAsync();

      setRecording(newRecording);
      setIsRecording(true);

      // 监听录音进度,获取音量数据
      newRecording.addProgressListener(({ status }) => {
        if (status.isRecording) {
          const currentDb = status.metering;
          if (currentDb < SILENCE_THRESHOLD) {
            if (!silenceStartTime) {
              silenceStartTime = Date.now();
            } else {
              const elapsed = Date.now() - silenceStartTime;
              if (elapsed >= SILENCE_TRIGGER_DURATION) {
                stopRecording();
              }
            }
          } else {
            // 检测到声音,重置静音计时
            silenceStartTime = null;
          }
        }
      });
    } catch (err) {
      console.error('开始录音失败:', err);
    }
  };

  const stopRecording = async () => {
    if (!recording) return;
    try {
      await recording.stopAndUnloadAsync();
      const uri = recording.getURI();
      setIsRecording(false);
      setRecording(null);
      silenceStartTime = null;
      console.log('录音已自动停止,文件路径:', uri);
      // 此处可添加录音文件的后续处理逻辑(播放、上传等)
    } catch (err) {
      console.error('停止录音失败:', err);
    }
  };

  return (
    <div>
      <button onPress={isRecording ? stopRecording : startRecording}>
        {isRecording ? '手动停止录音' : '开始录音'}
      </button>
    </div>
  );
}

注意事项

  • 阈值和触发时长需根据实际场景调整:嘈杂环境可提高阈值(如-15dB),安静环境可降低阈值;时长建议设置在1-2秒区间,避免短暂停顿误触发。
  • iOS和Android的音量计量存在细微差异,需在目标设备上测试并调整参数。
  • 确保组件卸载时清理录音实例,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:09:56