I can't use the Audio.Sound from Expo instance correctly. I can't pause or update the playback status

Viewed 3650

When I try to pause or update the status of the sound Object created by Audio.Sound(), an error indicates that the sound is not loaded.

Error : Cannot complete operation because sound is not loaded.

I don't understand because I called the method from the same object where I loaded the file and played it.

Here is my code :

    import React, { useState, useEffect } from "react";
    import { Feather } from "@expo/vector-icons";
    import {
      StyleSheet,
      Text,
      View,
      Button,
      FlatList,
      TouchableOpacity,
      Image
    } from "react-native";
    import { Audio } from "expo-av";

    const imageLocation = "./../assets/bibliotheque";
    const soundLocation = "./../sounds/bibliotheque";

    export default BibliothequeScreen = ({ navigation }) => {
      const [playing, setPlaying] = useState(false);
      const [soundPlaying, setSoundPlaying] = useState(false);

      const soundObject = new Audio.Sound();

      const playAudio = async (key, sound) => {
        console.log(key, playing, soundPlaying);
        try {
          if (playing) {
            await soundObject.pauseAsync();
            setPlaying(false);
          } else {
            setPlaying(true);
            await soundObject.loadAsync(
              require(soundLocation + "/Presentationpiano.mp3")
            );
            await soundObject.playAsync();
          }
        } catch (error) {
          console.log(error);
        }
      };

      return (
        <View style={styles.container}>
          <FlatList
            data={sound}
            renderItem={({ item }) => (
              <View style={styles.itemContainer}>
                <TouchableOpacity
                  onPress={
                    () => playAudio(item.key, item.soundPath)
                    // item.key == playing ? setPlaying(false) : setPlaying(item.key)
                  }
                  style={styles.item}
                >
                  <View style={{ flex: 1, flexDirection: "row" }}>
                    <View style={styles.imageContainer}>
                      <Image source={item.path} style={styles.image}></Image>
                    </View>
                    <Text style={styles.text}>{item.name}</Text>
                  </View>
                  <Feather
                    name={playing && item.key === soundPlaying ? "pause" : "play"}
                    size={35}
                    color='#3D425C'
                  ></Feather>
                </TouchableOpacity>
              </View>
            )}
          />
        </View>
      );
    };

Thank you for your help !

1 Answers

Try moving const soundObject = new Audio.Sound(); out of the BibliothequeScreen function, like this:

  import React, { useState, useEffect } from "react";
import { Feather } from "@expo/vector-icons";
import {
  StyleSheet,
  Text,
  View,
  Button,
  FlatList,
  TouchableOpacity,
  Image
} from "react-native";
import { Audio } from "expo-av";

const imageLocation = "./../assets/bibliotheque";
const soundLocation = "./../sounds/bibliotheque";

const soundObject = new Audio.Sound();

export default BibliothequeScreen = ({ navigation }) => {
  const [playing, setPlaying] = useState(false);
  const [soundPlaying, setSoundPlaying] = useState(false);

  const playAudio = async (key, sound) => {
    console.log(key, playing, soundPlaying);
    try {
      if (playing) {
        await soundObject.pauseAsync();
        setPlaying(false);
      } else {
        setPlaying(true);
        await soundObject.loadAsync(
          require(soundLocation + "/Presentationpiano.mp3")
        );
        await soundObject.playAsync();
      }
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <View style={styles.container}>
      <FlatList
        data={sound}
        renderItem={({ item }) => (
          <View style={styles.itemContainer}>
            <TouchableOpacity
              onPress={
                () => playAudio(item.key, item.soundPath)
                // item.key == playing ? setPlaying(false) : setPlaying(item.key)
              }
              style={styles.item}
            >
              <View style={{ flex: 1, flexDirection: "row" }}>
                <View style={styles.imageContainer}>
                  <Image source={item.path} style={styles.image}></Image>
                </View>
                <Text style={styles.text}>{item.name}</Text>
              </View>
              <Feather
                name={playing && item.key === soundPlaying ? "pause" : "play"}
                size={35}
                color='#3D425C'
              ></Feather>
            </TouchableOpacity>
          </View>
        )}
      />
    </View>
  );
};
Related