Expo-AV not playing audio after a while, and how to fix it

08/28/2024 08:36, 1 year ago

Recently, I was working on my game AI Against Humanity, where I encountered a bug in Expo-AV.
Namely, I was trying to play sounds.
And while it at first worked fine, after playing sounds for a few minutes, eventually I would run into this issue:

Unhandled Promise Rejection "Player doesn't exist" or sometimes "Player not found"

This was due to a memory leak in my application.
When you load sounds with await Audio.Sound.createAsync(source), it doesn't automatically unload it.

So I just wrote a custom hook, useSoundEffect, that you can use out of the box in your Expo app as well.
Here it is:

// useSoundEffect.ts import { Audio } from "expo-av" import { useEffect, useState } from "react" function useSoundEffect(source: any) { const [sound, setSound] = useState<Audio.Sound>(null) useEffect(() => { let _sound: Audio.SoundObject = null const loadSound = async () => { _sound = await Audio.Sound.createAsync(source) setSound(_sound.sound) } loadSound() return () => { _sound?.sound?.unloadAsync() } }, []) return sound } export default useSoundEffect

It's supposed to be used like this:

// First I add a Typescript definition to import .mp3 files // If you want to be fancy, you can always specify a type for any // I just went the quick way to get it working declare module "*.mp3" { const value: any; export default value; } // Then somewhere in the code, I can import the sound import SoundFanfare from '@page/against-humanity/sounds/fanfare.mp3' // And then, in any component, you can just use the hook like so const soundFanfare = useSoundEffect(SoundFanfare) // Then at any time, you can play the sound const playSound = () => { soundFanfare.playAsync() } // And you don't even have to worry about the unloading <3

That's about it for now, I'll see you soon
With love from wituz

0

0

Write a reply (0/3500)

Replies

No replies yet