Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to stop the sound from playing in a functional component #728

Open
3 of 4 tasks
efhan-the-unorthodox opened this issue Jun 11, 2021 · 2 comments
Open
3 of 4 tasks
Labels

Comments

@efhan-the-unorthodox
Copy link

efhan-the-unorthodox commented Jun 11, 2021

馃 Description

In my react native application, I am trying to make a "shrill alarm" feature where on the press of a button, an alarm can be played repeatedly. So far I have been able to play the audio file that I want. I tied the sound function to a useEffect hook in which I was hoping I would be able to start and stop the audio from playing. When I set the state which is tied to the useEffect hook to true, I am able to get the sound to play. But when I set the state to false, the sound will not stop

馃 What have you tried?

The solutions from the other issues don't seem to help me because they are all class components.

馃 Please post your code:

const [alarmStatus, setalarmStatus] = useState(false);

//The intention here is that when I change the alarmStatus to false, I expect the 
// Sound to stop playing. But it isn't in this case
useEffect(() => {
        Sound.setCategory('Alarm')
        let alarmtest = new Sound('smalarm.mp3', Sound.MAIN_BUNDLE, (error) => {
            if (error) {
                console.log('Failed to load sound', error)
            }
            else {
                if (alarmStatus) {
                    alarmtest.play((s) => {
                        if (s) {
                            console.log('Playback success')
                            alarmtest.release();
                        }
                        else {
                            console.log('Playback fail')
                        }
                    });
                }
                else{
                    alarmtest.stop();
                }
            }
        })
    }, [alarmStatus])

馃挕 Possible solution

  • iOS
  • Android

Are you using...

  • React Native CLI (e.g. react-native run-android)

Which versions are you using?

  • React Native Sound:
  • React Native:
  • iOS:
  • Android:

Does the problem occur on...

  • Device

If your problem is happening on a device, which device?

  • Device: iPhone X and any generic android
@Hannes1
Copy link

Hannes1 commented Jul 28, 2021

Well remember the alarmtest variable "resets" on every rerender, so when you change state to stop the alarmtest variable is a newly initiated Sound class and it can't be used to stop the old one.

You are going to have to use something like useref to initialize the Sound class, because useref doesn't reset on rerender

@alexanderhodes
Copy link

The idea of @Hannes1 worked for me. You just need to do the initialization of the Sound in a useRef. With that the sound variable stays the same as well during rerender

const soundRef = useRef<Sound>(
    new Sound(soundFile, soundPath, error => {
      if (error) {
        console.error("error", error);
      }
    })
  );

Later in your code you can access the sound like this:

useEffect(() => {
  // playing
  shuttleSoundRef.current.play();
  // stopping after 2 seconds
  setTimeout(() => {
    shuttleSoundRef.current.stop();
  }, 2000);
}, []);

You can use this for checking the state of alarmStatus in a useEffect

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants