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

如何在React Native中实现点击按钮录音频,静音20秒后停止并保存为WAV文件?

Implementing Audio Recording with Auto-Stop on 20s Silence & WAV Save in React Native

Absolutely! This is totally achievable in React Native. We'll use a reliable audio library combined with volume level monitoring to detect silence, then auto-stop recording and save the file as WAV. Here's how to make it happen:

Step 1: Install Dependencies

We'll use react-native-audio-recorder-player for recording/playing audio and accessing volume levels, plus react-native-permissions to handle necessary device permissions (microphone, storage).

Install them via npm/yarn:

# Using npm
npm install react-native-audio-recorder-player react-native-permissions

# Using yarn
yarn add react-native-audio-recorder-player react-native-permissions

For iOS, don't forget to run pod install after installing dependencies:

cd ios && pod install && cd ..

Step 2: Configure Permissions

iOS

Add these lines to your Info.plist (inside the <dict> tag) to request microphone and storage access:

<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access to record audio</string>
<key>NSDocumentsFolderUsageDescription</key>
<string>Need access to documents folder to save recorded audio</string>

Android

Add these permissions to your AndroidManifest.xml:

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

Step 3: Core Implementation Code

Here's a complete functional component example with all the logic you need:

import React, { useState, useEffect, useRef } from 'react';
import { View, Button, Text, Alert } from 'react-native';
import AudioRecorderPlayer from 'react-native-audio-recorder-player';
import { check, request, PERMISSIONS, RESULTS } from 'react-native-permissions';

const AudioRecorderComponent = () => {
  const [isRecording, setIsRecording] = useState(false);
  const [silenceDuration, setSilenceDuration] = useState(0);
  const silenceThreshold = -40; // Adjust based on your environment (lower = quieter)
  const maxSilenceTime = 20; // Target 20 seconds of silence
  const audioRecorderPlayer = useRef(new AudioRecorderPlayer()).current;
  const silenceTimerRef = useRef(null);
  const volumeCheckIntervalRef = useRef(null);

  // Check permissions when component mounts
  useEffect(() => {
    const checkPermissions = async () => {
      const micPermission = await check(PERMISSIONS.IOS.MICROPHONE ?? PERMISSIONS.ANDROID.RECORD_AUDIO);
      const storagePermission = await check(PERMISSIONS.IOS.DOCUMENTS_FOLDER ?? PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE);

      if (micPermission !== RESULTS.GRANTED || storagePermission !== RESULTS.GRANTED) {
        const micRequest = await request(PERMISSIONS.IOS.MICROPHONE ?? PERMISSIONS.ANDROID.RECORD_AUDIO);
        const storageRequest = await request(PERMISSIONS.IOS.DOCUMENTS_FOLDER ?? PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE);

        if (micRequest !== RESULTS.GRANTED || storageRequest !== RESULTS.GRANTED) {
          Alert.alert("Permissions Required", "Please grant microphone and storage permissions to use this feature.");
        }
      }
    };

    checkPermissions();

    // Cleanup timers and recording on component unmount
    return () => {
      if (silenceTimerRef.current) clearTimeout(silenceTimerRef.current);
      if (volumeCheckIntervalRef.current) clearInterval(volumeCheckIntervalRef.current);
      audioRecorderPlayer.stopRecorder();
    };
  }, []);

  const startRecording = async () => {
    try {
      // Configure recording to save as WAV format
      const audioPath = `${AudioRecorderPlayer.WORKING_DIR}/test.wav`;
      const recordingOptions = {
        audioQuality: "high",
        sampleRate: 44100,
        numberOfChannels: 1,
        audioEncoding: "wav",
        format: "wav",
      };

      await audioRecorderPlayer.startRecorder(audioPath, recordingOptions);
      setIsRecording(true);
      setSilenceDuration(0);

      // Monitor volume levels every 1 second
      volumeCheckIntervalRef.current = setInterval(async () => {
        const volume = await audioRecorderPlayer.getVolume();
        const decibel = parseInt(volume);

        if (decibel <= silenceThreshold) {
          // Increment silence counter if below threshold
          setSilenceDuration(prev => prev + 1);
        } else {
          // Reset counter if sound is detected
          setSilenceDuration(0);
          if (silenceTimerRef.current) clearTimeout(silenceTimerRef.current);
        }
      }, 1000);

      // Check if silence duration hits the 20-second mark
      const checkSilenceTimeout = () => {
        if (silenceDuration >= maxSilenceTime && isRecording) {
          stopRecording();
          Alert.alert("Recording Stopped", "Silence detected for 20 seconds.");
        } else {
          silenceTimerRef.current = setTimeout(checkSilenceTimeout, 1000);
        }
      };
      silenceTimerRef.current = setTimeout(checkSilenceTimeout, 1000);

    } catch (error) {
      console.error("Error starting recording:", error);
      Alert.alert("Error", "Failed to start recording.");
    }
  };

  const stopRecording = async () => {
    try {
      await audioRecorderPlayer.stopRecorder();
      setIsRecording(false);

      // Clean up timers
      if (silenceTimerRef.current) clearTimeout(silenceTimerRef.current);
      if (volumeCheckIntervalRef.current) clearInterval(volumeCheckIntervalRef.current);

      Alert.alert("Recording Saved", "Your audio has been saved as test.wav");
    } catch (error) {
      console.error("Error stopping recording:", error);
      Alert.alert("Error", "Failed to stop recording.");
    }
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 }}>
      <Button
        title={isRecording ? "Stop Recording" : "Start Recording"}
        onPress={isRecording ? stopRecording : startRecording}
        color={isRecording ? "#ff3b30" : "#34c759"}
      />
      {isRecording && (
        <Text style={{ marginTop: 20, fontSize: 16 }}>
          Silence detected for: {silenceDuration}s / {maxSilenceTime}s
        </Text>
      )}
    </View>
  );
};

export default AudioRecorderComponent;

Key Adjustments & Tips

  • Silence Threshold: The -40 dB threshold might need tweaking based on your environment. Test with different values to find what works best for your use case.
  • File Location: The audio saves to the app's working directory by default. You can adjust the audioPath to save to external storage on Android if needed.
  • Performance: Checking volume every 1 second balances accuracy and performance—you can adjust the interval, but 1s is usually sufficient.
  • Error Handling: The example includes basic error handling, but you might want to expand it for edge cases like low storage or recording interruptions.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:50:30