Expo Audio createAsync返回Sound对象方法全为undefined问题排查
解决Expo在Mac Chrome中Sound.playAsync()报错“TypeError: sound.playAsync is not a function”
问题分析
你遇到的核心问题是:自定义创建的Sound实例虽有方法名称,但所有方法均为undefined。这是因为通过Object.assign(Sound.prototype, PlaybackMixin)挂载原型方法的方式,在Expo Web运行环境(Mac Chrome)中出现原型链绑定失效,方法未正确关联到实例上。
解决方案
1. 改用Expo官方的Sound实例创建方法
不要自行通过new Sound()实例化,直接使用Expo Audio模块提供的Audio.Sound.createAsync(),官方方法会自动处理原型方法的绑定逻辑,避免自定义实现的兼容性问题:
import { Audio } from 'expo-av'; // 正确创建并初始化Sound实例 const createSound = async () => { const { sound } = await Audio.Sound.createAsync( // 替换为你的音频资源路径 require('./assets/audio/your-sound.mp3'), { shouldPlay: false } ); return sound; }; // 在用户交互事件中调用(比如按钮点击) const handlePlay = async () => { const sound = await createSound(); await sound.playAsync(); };
2. 修复自定义createAsync的原型方法绑定
如果必须保留自定义的createAsync实现,不要直接用Object.assign批量覆盖原型,改为逐个遍历挂载方法,确保原型链正确关联:
class Sound { constructor() { // 你的实例初始化逻辑 } } // 遍历PlaybackMixin的方法,逐个挂载到Sound原型 Object.keys(PlaybackMixin).forEach(methodName => { Sound.prototype[methodName] = PlaybackMixin[methodName]; }); // 或者在实例创建后直接为实例挂载方法(绕过原型链问题) function createAsync() { const soundInstance = new Sound(); // 直接把方法挂载到实例上,而非原型 Object.assign(soundInstance, PlaybackMixin); return { sound: soundInstance }; }
3. 排查Web环境的自动播放限制
即使方法绑定正常,Mac Chrome也会限制非用户触发的音频播放。确保playAsync()是在用户交互事件(比如点击、触摸)中调用,而非页面加载时自动执行。
内容的提问来源于stack exchange,提问作者voxoid
相关产品推荐
相关产品推荐

