react-native - 在 React Native Expo 中录制后如何播放声音?
问题描述
我正在用 Expo 构建一个录音应用程序。这是我开始录音的功能,它工作正常。
const [recording, setRecording] = React.useState();
async function startRecording() {
try {
console.log('Requesting permissions..');
await Audio.requestPermissionsAsync();
await Audio.setAudioModeAsync({
allowsRecordingIOS: true,
playsInSilentModeIOS: true,
});
console.log('Starting recording..');
const recording = new Audio.Recording();
await recording.prepareToRecordAsync(Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY);
await recording.startAsync();
setRecording(recording);
console.log('Recording started');
} catch (err) {
console.error('Failed to start recording', err);
}
}
这是我的“停止”功能,录制停止并存储...
async function stopRecording() {
console.log('Stopping recording..');
setRecording(undefined);
await recording.stopAndUnloadAsync();
const uri = recording.getURI();
console.log('Recording stopped and stored at', uri);
}
现在我想用播放按钮播放这个保存的声音。我怎样才能得到这个保存的声音?
return (
<View style={styles.container}>
<Button
title={recording ? 'Stop Recording' : 'Start Recording'}
onPress={recording ? stopRecording : startRecording}
/>
</View>
);
我想将此存储的 uri 作为文件位置传递。有可能以这种方式吗?
async function playSound() {
console.log('Loading Sound');
const { sound } = await Audio.Sound.createAsync(
require(RecordedURI)
);
setSound(sound);
console.log('Playing Sound');
await sound.playAsync();
}
解决方案
首先,您undefined
在获得录音后分配您的状态。
我建议你做这样的事情
Recording
为和Playing
音频创建两个参考。
const AudioRecorder = useRef(new Audio.Recording());
const AudioPlayer = useRef(new Audio.Sound());
和一些状态recordingStatus
等permission
。
const [RecordedURI, SetRecordedURI] = useState<string>("");
const [AudioPermission, SetAudioPermission] = useState<boolean>(false);
const [IsRecording, SetIsRecording] = useState<boolean>(false);
const [IsPLaying, SetIsPLaying] = useState<boolean>(false);
录制实现的小吃在这里
这是一个具有实现的GitHub 存储库。
结果截图
我在实现的其余部分下方添加了
import React, { useState, useRef, useEffect } from "react";
import { View, StyleSheet, Button, Text } from "react-native";
import { Audio } from "expo-av";
export default function App() {
// Refs for the audio
const AudioRecorder = useRef(new Audio.Recording());
const AudioPlayer = useRef(new Audio.Sound());
// States for UI
const [RecordedURI, SetRecordedURI] = useState<string>("");
const [AudioPermission, SetAudioPermission] = useState<boolean>(false);
const [IsRecording, SetIsRecording] = useState<boolean>(false);
const [IsPLaying, SetIsPLaying] = useState<boolean>(false);
// Initial Load to get the audio permission
useEffect(() => {
GetPermission();
}, []);
// Function to get the audio permission
const GetPermission = async () => {
const getAudioPerm = await Audio.requestPermissionsAsync();
SetAudioPermission(getAudioPerm.granted);
};
// Function to start recording
const StartRecording = async () => {
try {
// Check if user has given the permission to record
if (AudioPermission === true) {
try {
// Prepare the Audio Recorder
await AudioRecorder.current.prepareToRecordAsync(
Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY
);
// Start recording
await AudioRecorder.current.startAsync();
SetIsRecording(true);
} catch (error) {
console.log(error);
}
} else {
// If user has not given the permission to record, then ask for permission
GetPermission();
}
} catch (error) {}
};
// Function to stop recording
const StopRecording = async () => {
try {
// Stop recording
await AudioRecorder.current.stopAndUnloadAsync();
// Get the recorded URI here
const result = AudioRecorder.current.getURI();
if (result) SetRecordedURI(result);
// Reset the Audio Recorder
AudioRecorder.current = new Audio.Recording();
SetIsRecording(false);
} catch (error) {}
};
// Function to play the recorded audio
const PlayRecordedAudio = async () => {
try {
// Load the Recorded URI
await AudioPlayer.current.loadAsync({ uri: RecordedURI }, {}, true);
// Get Player Status
const playerStatus = await AudioPlayer.current.getStatusAsync();
// Play if song is loaded successfully
if (playerStatus.isLoaded) {
if (playerStatus.isPlaying === false) {
AudioPlayer.current.playAsync();
SetIsPLaying(true);
}
}
} catch (error) {}
};
// Function to stop the playing audio
const StopPlaying = async () => {
try {
//Get Player Status
const playerStatus = await AudioPlayer.current.getStatusAsync();
// If song is playing then stop it
if (playerStatus.isLoaded === true)
await AudioPlayer.current.unloadAsync();
SetIsPLaying(false);
} catch (error) {}
};
return (
<View style={styles.container}>
<Button
title={IsRecording ? "Stop Recording" : "Start Recording"}
color={IsRecording ? "red" : "green"}
onPress={IsRecording ? StopRecording : StartRecording}
/>
<Button
title={IsPLaying ? "Stop Sound" : "Play Sound"}
color={IsPLaying ? "red" : "orange"}
onPress={IsPLaying ? StopPlaying : PlayRecordedAudio}
/>
<Text>{RecordedURI}</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
backgroundColor: "#ecf0f1",
padding: 8,
},
});
推荐阅读
- r - dplyr 中的条件求和(例如“引用另一行中刚刚更新的值” - 就像在 Excel 中一样)
- python - sklearn.utils 模块未找到
- c# - 在 JsonDeserializer 中正确跳过父级
- python - 在 'r+' 中截断文件使整个文件变成矩形
- google-drive-api - 未经授权的 WebHook 回调通道 Google 推送通知
- python - 从 OSMNX Geoseries 获取坐标列表(纬度、经度)
- pandas - Pandas Groupby:函数定义中的条件语句
- ios - 如何使用带有可选 UIImage 的绑定?
- c# - 等待后 EF Core 异步方法挂起/死锁
- eclipse - 无法打包插件