React Native:为什么 Expo-AV 不播放音频?

React Native: Why is Expo-AV not playing audio?

我正在尝试构建一个充当音板的应用程序,当按下不同的按钮时可以播放不同的声音。我希望音频可以播放,但我收到一条错误消息:

Possible Unhandled Promise Rejection (id: 1): TypeError: undefined is not an object (evaluating '_expoAv.Audio.sound.createAsync')
playSound$

这是我的代码:

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

// project made in yarn
// yarn start
// yarn add

export default function App() {
  const [sound, setSound] = useState("");

  const playSound = async () => {
    console.log("Loading Sound");
    const { sound } = await Audio.sound.createAsync(
      require("./assets/Ayo.mp3")
    );
    setSound(sound);

    console.log("playing sound");
    await sound.playAsync();
  };

  useEffect(() => {
    return sound
      ? () => {
          console.log("unloading the sound");
          sound.unloadAsync();
        }
      : undefined;
  }, [sound]);
  // run useEffect whenever sound state changes

  return (
    <View style={styles.container}>
      <Text>SoundGround</Text>

      <View style={{ flexDirection: "row" }}>
        <TouchableOpacity onPress={playSound}>
          <Feather name="arrow-left" style={styles.iconStyle} />
        </TouchableOpacity>

        <TouchableOpacity onPress={playSound}>
          <Feather name="arrow-right" style={styles.iconStyle} />
        </TouchableOpacity>
      </View>

      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  iconStyle: {
    fontSize: 100,
  },
});

到目前为止,我尝试使用不同的音频格式添加 try/catch 块。我认为该错误与在用于播放某些内容之前未分配状态有关 - 但我不确定。

您可以实施 useRef 而不是 useState 来停止重新渲染!

这对我很有效。

import { StatusBar } from "expo-status-bar";
import React, { useEffect } from "react";
import { StyleSheet, Text, View, TouchableOpacity } from "react-native";
import { Feather } from "@expo/vector-icons";
import { Audio } from "expo-av";

// project made in yarn
// yarn start
// yarn add

export default function App() {
  const sound = useRef(new Audio.Sound());

  useEffect(() => {
    return () => sound.current.unloadAsync();
  }, []);

  const playSound = async () => {
    console.log("Loading Sound");

    await sound.current.createAsync(require("./assets/Ayo.mp3"));

    console.log("playing sound");

    const checkLoaded = await sound.current.getStatusAsync();
    if (checkLoaded.isLoaded === true) {
      console.log("Error in Loading mp3");
    } else {
      await sound.current.playAsync();
    }
  };

  return (
    <View style={styles.container}>
      <Text>SoundGround</Text>

      <View style={{ flexDirection: "row" }}>
        <TouchableOpacity onPress={() => playSound()}>
          <Feather name="arrow-left" style={styles.iconStyle} />
        </TouchableOpacity>

        <TouchableOpacity onPress={() => playSound()}>
          <Feather name="arrow-right" style={styles.iconStyle} />
        </TouchableOpacity>
      </View>

      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  iconStyle: {
    fontSize: 100,
  },
});