is there a way to keep recording after pausing expo-audio?

59 views Asked by At

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.

0

There are 0 answers