I'm unable to achieve this WhatsApp-like voice message recording, i want the user to be able to record and pause without limit as well as listen to what has been recorded, to finally send one whole audio.
im using react native "0.72.5" , "expo-av": "~13.4.1",
This is the Component:
import React, { useEffect, useState } from "react";
import { View, Text, TouchableOpacity } from "react-native";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { Audio } from "expo-av";
function AudioMessage({ ShowAudioModal }) {
const [recording, setRecording] = useState(null);
const [sound, setSound] = useState(null);
const [isRecording, setIsRecording] = useState(false);
const [isPlaying, setIsPlaying] = useState(false);
const [playbackPosition, setPlaybackPosition] = useState(0);
useEffect(() => {
startRecording();
}, []);
async function startRecording() {
try {
console.log("Requesting permissions..");
await Audio.requestPermissionsAsync();
await Audio.setAudioModeAsync({
allowsRecordingIOS: true,
playsInSilentModeIOS: true,
});
console.log("Starting recording..");
const { recording } = await Audio.Recording.createAsync(
Audio.RecordingOptionsPresets.HIGH_QUALITY
);
setRecording(recording);
setIsRecording(true);
console.log("Recording started");
} catch (err) {
console.error("Failed to start recording", err);
}
}
async function toggleRecording() {
try {
if (isRecording) {
// Pausing recording
await recording.pauseAsync();
} else {
// Resuming or starting recording
await recording.startAsync();
}
setIsRecording(!isRecording);
} catch (error) {
console.error("Failed to toggle recording", error);
}
}
async function stopRecording() {
try {
console.log("Stopping recording..");
setIsRecording(false);
await recording.stopAndUnloadAsync();
const uri = recording.getURI();
setSound(uri);
console.log("Recording stopped and stored at", uri);
} catch (error) {
console.error("Failed to stop recording", error);
}
}
async function playSound() {
try {
if (sound) {
console.log("Loading Sound");
const { sound: playbackObject, status } = await Audio.Sound.createAsync(
{ uri: sound },
{ shouldPlay: true, position: playbackPosition }
);
console.log("Playing Sound");
setIsPlaying(true);
playbackObject.setOnPlaybackStatusUpdate((status) => {
if (status.didJustFinish) {
setIsPlaying(false);
setPlaybackPosition(status.positionMillis);
}
});
}
} catch (error) {
console.error("Failed to play sound", error);
}
}
return (
<View
style={{
position: "absolute",
bottom: 0,
width: "100%",
height: 140,
backgroundColor: "red",
flexDirection: "column",
}}
>
<View style={{ width: "100%", height: "50%", backgroundColor: "yellow" }}>
{isRecording ? (
<View style={{ justifyContent: "center", alignItems: "center" }}>
<Text>0:00</Text>
<Text>RECORDING AUDIO</Text>
</View>
) : (
<View style={{ justifyContent: "center", alignItems: "center" }}>
<Text>PLAYING AUDIO</Text>
<TouchableOpacity onPress={playSound} disabled={isPlaying}>
<MaterialCommunityIcons
name="play-circle"
size={30}
color={isPlaying ? "gray" : "#FF5421"}
/>
</TouchableOpacity>
</View>
)}
</View>
<View
style={{
width: "100%",
height: "50%",
backgroundColor: "green",
flexDirection: "row",
justifyContent: "space-between",
paddingHorizontal: 15,
alignItems: "center",
}}
>
<TouchableOpacity onPress={""}>
<MaterialCommunityIcons name="delete" size={28} color="#cfd1d5" />
</TouchableOpacity>
<TouchableOpacity
onPress={isRecording ? stopRecording : toggleRecording}
>
{isRecording ? (
<MaterialCommunityIcons
name="pause-circle-outline"
size={34}
color="#FF2D21"
/>
) : (
<MaterialCommunityIcons
name="microphone"
size={34}
color="#FF2D21"
/>
)}
</TouchableOpacity>
<TouchableOpacity
style={{
width: 40,
height: 40,
display: "flex",
justifyContent: "center",
alignItems: "center",
borderRadius: 50,
borderColor: "white",
borderWidth: 2,
padding: 5,
backgroundColor: "#FFA121",
}}
>
<MaterialCommunityIcons size={25} name="send" color="white" />
</TouchableOpacity>
</View>
</View>
);
}
export default AudioMessage;
so far I have been able to just listen to the audio that was recorded before pausing when trying to resume it doesn't work anymore
Thank you in advance.