寻求基于Expo CLI的React Native录音可视化实现方案
Expo CLI 实现 React Native 录音可视化方案
核心依赖选择
无需 eject,直接基于 Expo 官方生态实现:
expo-av:Expo 官方音频录制/播放库,支持实时获取音频振幅、频谱数据react-native-svg:用来绘制波形、频谱类可视化图形(Expo 已内置基础支持,安装即可用)
步骤1:安装依赖
expo install expo-av react-native-svg
步骤2:基础波形可视化实现
利用 Audio.Recording 的进度监听获取实时振幅,再通过 SVG 绘制动态波形:
import { Audio } from 'expo-av'; import { useState, useEffect } from 'react'; import { View, Button } from 'react-native'; import Svg, { Rect } from 'react-native-svg'; export default function AudioWaveVisualizer() { const [recording, setRecording] = useState(null); const [amplitude, setAmplitude] = useState(0); // 申请录音权限 useEffect(() => { async function requestAudioPermission() { const { status } = await Audio.requestPermissionsAsync(); if (status !== 'granted') { alert('需授予录音权限才能使用该功能'); } } requestAudioPermission(); }, []); // 启动录音并监听振幅 async function startRecording() { 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(); // 实时获取音频振幅(范围0-1) newRecording.addProgressListener((data) => { setAmplitude(data.metering.average); }); setRecording(newRecording); } catch (err) { console.error('录音启动失败:', err); } } // 停止录音 async function stopRecording() { if (!recording) return; try { await recording.stopAndUnloadAsync(); setRecording(null); setAmplitude(0); } catch (err) { console.error('录音停止失败:', err); } } // 绘制动态柱状波形 const renderWaveBar = () => { // 将0-1的振幅映射为0-200的柱子高度 const barHeight = Math.max(10, amplitude * 200); return ( <Svg width="320" height="220" viewBox="0 0 320 220"> <Rect x="60" y={220 - barHeight} width="200" height={barHeight} fill="#2196F3" rx="8" /> </Svg> ); }; return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', gap: 24 }}> {renderWaveBar()} <Button title={recording ? '停止录音' : '开始录音'} onPress={recording ? stopRecording : startRecording} /> </View> ); }
进阶:频谱可视化
如果需要更精细的频谱图,可使用 Audio.Analyser 获取多频段能量数据:
// 在startRecording函数中添加分析器 const analyser = new Audio.Analyser({ recording: newRecording, fftSize: 256, // FFT尺寸越大,频谱数据点越多(可选值:32/64/128/256等) }); // 定时获取频谱数据(每50ms更新一次) const spectrumInterval = setInterval(() => { const frequencyData = analyser.getByteFrequencyData(); // frequencyData为Uint8Array,每个元素对应一个频段的能量值(0-255) setSpectrumData([...frequencyData]); }, 50); // 停止录音时清除定时器 async function stopRecording() { if (!recording) return; clearInterval(spectrumInterval); // ...其余停止录音逻辑 }
注意事项
- 振幅值默认范围为0-1,需根据需求映射为可视化元素的尺寸
- iOS/Android 权限逻辑略有差异,必须先申请权限再启动录音
- 避免过于频繁的状态更新,可调整监听/定时器的时间间隔以优化性能
内容的提问来源于stack exchange,提问作者Doğa
相关产品推荐
相关产品推荐

