Search code examples
react-nativeaudioexpoexpo-avfilestack

How to Convert a Recording File to .mp3 or .m4a (or similar) Format Using Expo?


How can I record audio in a format other than .caf (iOS) or .3gp (Android)? I need to upload the file to a cloud storage service, but it doesn't support .caf or .3gp formats.

import * as React from "react";
import { Text, View, StyleSheet, Button } from "react-native";
import { Audio } from "expo-av";

export default function App() {
  const [recording, setRecording] = React.useState();

  async function startRecording() {
    try {
      console.log("Requesting permissions..");
      await Audio.requestPermissionsAsync();
      await Audio.setAudioModeAsync({
        allowsRecordingIOS: true,
        playsInSilentModeIOS: true,
        shouldDuckAndroid: true,
      });
      console.log("Starting recording..");
      const recording = new Audio.Recording({
        audioEncoder: Audio.RECORDING_OPTION_IOS_AUDIO_QUALITY_HIGH,
        extension: ".m4a",
      });
      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>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    backgroundColor: "#ecf0f1",
    padding: 10,
  },
});

I'm currently working on a test, but I'm facing an issue where the URI for my recording is not being saved with the '.m4a' file extension. Here's the console.log output for reference:

"Recording stopped and stored at file:///Users/XXXXXXXXXXXX/Library/Developer/CoreSimulator/Devices/B5A17703-6E71-4535-9700-CXXXXXXXXB/data/Containers/Data/Application/8C7XXXXXXXX4XE-909A-5842J34H598/Library/Caches/ExponentExperienceData/%2540gzXXXX%252Fforumaudio/AV/recording-J3J24U-6154-3U43-4IDB-9JDN39RND4.caf"

After that how can I upload to FileStack?

  async function uploadFileAndGetURL() {
    console.log("Starting upload...");
    console.log("Localfile:", recordingFileURI);
    try {
      if (recordingFileURI) {
        const response = await axios.post(
          `https://www.filestackapi.com/api/store/S3?key=${FILESTACKAPI}`,
          recordingFileURI,
          {
            headers: {
              "Content-Type": "audio/m4a",
            },
          }
        );
        if (response.status === 200) {
          console.log("Upload finished!");
          console.log("URL:", response.data.url);
          return response.data.url;
        }
      }
    } catch (error) {
      console.error("Erro durante o upload:", error);
      throw error;
    }
  }

Solution

  • You can define the output format, there is no need to add a convert step.

          const { recording } = await Audio.Recording.createAsync({
             ...Audio.RecordingOptionsPresets.HIGH_QUALITY,
            outputFormat: ".mp3"
          });