kojow7
kojow7

Reputation: 11394

React-Native sound clip stops working after a certain amount of clicks

I am using the react-native-sound library. I have a button that invokes a function to play a short sound file. After playing the sound file 15 times, the sound no longer plays, even though the function loads.

The following is my function code:

  playSound() {
    var s = new Sound('soundfile.mp3', Sound.MAIN_BUNDLE, (e) => {
      if (e) {
        console.log('error', e);
      } else {
        console.log('duration', s.getDuration());
        s.play()
      }
    });

  }

What is happening and how can I solve this problem?

Upvotes: 3

Views: 2028

Answers (2)

HienMacVan
HienMacVan

Reputation: 1

i'm a new one to react native and try many times to fix this. When i add s.release() like sire kojow7's answered it's great but it stoped after less than 50 times. But finally i fixed this, here is my code :

const [countTimesSoundPlay, setCountTimesSoundPlay] = useState(0);
  const [soundTrue, setsoundTrue] = useState(null)

  useEffect(() => {
    var soundTrue = new Sound('sound_good.mp3', Sound.MAIN_BUNDLE, (error) => {
      if (error) {
        console.log('failed to load the sound', error);
        return;
      }
      // loaded successfully
      console.log('duration in seconds: ' + soundTrue.getDuration() + 'number of channels: ' + soundTrue.getNumberOfChannels());
    });

    setsoundTrue(soundTrue)
  }, [countTimesSoundPlay])

  const timerRef2 = useRef(null);

  const playTrue = async () => {
    soundTrue.play((sucess) => {
      if (sucess) {
        console.log('successfully finished playing');
        soundTrue.release()
        timerRef2.current = setTimeout(() => {
          setCountTimesSoundPlay(countTimesSoundPlay + 1)
        }, 1200);
      } else {
        console.log('playback failed due to audio decoding errors');
      }
      return () => {
        if (timerRef2.current) {
          clearTimeout(timerRef2.current);
        }
      };
    });
  }



////i tested with 200 times :)
  // useEffect (()=> {
  //   if (soundTrue) {
  //      playTrue()
  //     console.log('countTimesSoundPlay', countTimesSoundPlay)
  //   }
  // },[countTimesSoundPlay])

hope it helps!

Upvotes: 0

kojow7
kojow7

Reputation: 11394

The reason is because all the resources are being used up. You should release your audio resources when you are done with them.

 playSound() {
    var s = new Sound('soundfile.mp3', Sound.MAIN_BUNDLE, (e) => {
      if (e) {
        console.log('error', e);
      } else {
        console.log('duration', s.getDuration());
        s.play(()=>{
                s.release()
        })
      }
    });

  }

Also, you can reuse a Sound instance rather than recreating a new resource each time.

Upvotes: 7

Related Questions