Expo v50+环境下如何实现录音自动停止功能?
解决方案:Expo v50+ 实现语音自动停止录音
核心思路
通过监听录音过程中的实时音量数据,设置静音阈值和静音持续时长,当检测到用户停止说话(音量低于阈值且持续足够时间)时,自动触发录音停止逻辑,完全基于用户实际说话时长控制录音长度。
实现步骤
配置录音实例并开启音量监听
基于expo-av的Audio.Recording类,启动录音后通过addProgressListener实时获取音频分贝数据。设置静音判断逻辑
- 定义静音阈值(可根据场景调整,比如-20dB,值越小代表越安静)
- 记录静音开始时间,当音量持续低于阈值超过设定时长(比如1.5秒),执行停止录音操作。
完整代码示例
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
相关产品推荐
相关产品推荐

