You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native音效板开发中expo-av调用Audio.sound.createAsync报错无法播放音频

报错核心原因

你遇到的未处理Promise拒绝和state赋值时机无关,触发报错的根源有两点:

  • API拼写错误导致属性访问失败
    你代码中调用的Audio.sound.createAsync在expo-av的导出对象中不存在,正确的静态方法挂载在Audio.Sound.createAsync(注意Sound为大写S)。JS在执行时找不到Audio对象上的sound属性,直接抛出undefined类型的访问错误,这就是报错信息中提示evaluating '_expoAv.Audio.sound.createAsync'的直接原因——代码根本没有走到赋值、播放音频的步骤,在属性访问阶段就已经中断了。
  • 未完成音频模块初始化
    缺少对expo-av的播放模式配置,部分iOS/Android真机环境下就算修正拼写错误,也会因为没有获取音频播放权限抛出异步错误。
分步修复方案
  • 修正API调用的大小写错误:将Audio.sound.createAsync替换为Audio.Sound.createAsync
  • 补充组件挂载时的音频初始化逻辑,适配移动端的播放权限规则
  • 将sound状态的初始值从空字符串改为null,避免空字符串被判定为truthy导致卸载逻辑误执行
  • 给所有异步音频操作补全try/catch块,捕获权限不足、资源加载失败等异常,避免未处理Promise打断应用运行
  • 优化按钮绑定逻辑,给不同触控按钮传入对应的音效资源路径,实现不同按钮播放不同音效的效果
核心修复代码片段
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";

export default function App() {
  // 初始值改为null,替代原有的空字符串
  const [sound, setSound] = useState(null);

  // 组件挂载时初始化音频播放模式
  useEffect(() => {
    const setupAudio = async () => {
      await Audio.setAudioModeAsync({
        playsInSilentModeIOS: true, // 支持静音模式下播放
        staysActiveInBackground: false,
        shouldDuckAndroid: false,
      });
    };
    setupAudio();
  }, []);

  // 给函数传入需要播放的音频资源路径,支持多按钮绑定不同音效
  const playSound = async (audioResource) => {
    try {
      console.log("Loading Sound");
      // 修正大写的Sound,替代原有的小写sound调用
      const { sound: audioInstance } = await Audio.Sound.createAsync(
        audioResource,
        { shouldPlay: true }
      );
      // 卸载上一个正在播放的音频实例,避免多音频叠加
      if (sound) {
        await sound.unloadAsync();
      }
      setSound(audioInstance);
      console.log("playing sound");
    } catch (error) {
      console.log("音频播放异常:", error);
    }
  };

  // 组件卸载时清理音频资源
  useEffect(() => {
    return sound
      ? () => {
          console.log("unloading the sound");
          sound.unloadAsync();
        }
      : undefined;
  }, [sound]);

  return (
    <View style={styles.container}>
      <Text>SoundGround</Text>
      <View style={{ flexDirection: "row" }}>
        <TouchableOpacity 
          onPress={() => playSound(require("./assets/Ayo.mp3"))}
        >
          <Feather name="arrow-left" style={styles.iconStyle} />
        </TouchableOpacity>
        {/* 右按钮可以绑定对应路径的其他音效资源 */}
        <TouchableOpacity 
          onPress={() => playSound(require("./assets/你的另一个音效.mp3"))}
        >
          <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,
  },
});

内容的提问来源于stack exchange,提问作者skumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 20:36:02