react-native-sound
react-native-sound copied to clipboard
Sounds won't stop - Android
In Android Marshmallow (6.0) whenever I play sound and then stop it, not only it won't stop but also it would loop itself and overlap with the next sound. The weird thing is that in Lollipop it doesn't happen. I'm using the same code. "react-native": "^0.46.1", "react-native-sound": "^0.10.3", Thank you!
find anything here @javoescan ?
Can you post your code?
Same issue 👍 (Android v6.0.1)
My code is
_playLocal(audioUri){ console.log('playing... ' + audioUri); var sound = new Sound(audioUri.replace('file://', ''), '', (error) => { console.log(sound.isLoaded()); if (sound.isLoaded()) { sound.setVolume(1); //sound.setNumberOfLoops(1); } if (error) { console.log('failed to load the sound', error); return; } // loaded successfully console.log('loops: ' + sound.getNumberOfLoops()); console.log('duration in seconds: ' + sound.getDuration() + 'number of channels: ' + sound.getNumberOfChannels()); this.setState({ status: 'PLAYING', localSound: sound }, () => { // Play the sound with an onEnd callback this.state.localSound.play((success) => { if (success) { this.setState({ status: 'FINISHED', localSound: null, }, () => { //this._next(); }); console.log('successfully finished playing'); } else { console.log('playback failed due to audio decoding errors'); // reset the player to its uninitialized state (android only) // this is the only option to recover after an error occured and use the player again //sound.reset(); } console.log('...'); sound.release(); }); }); }); }
Hi apparently the problem is while playing ogg files.
See: https://stackoverflow.com/questions/12834727/android-loop-true-how-to-avoid-mediaplayer-looping-audios-with-this-metadat
I know it's a bit late but I had the same problem and solved it by changing player.pause(); to player.stop(); on react-native-sound/android/src/main/java/com/zmxv/RNSound/RNSoundModule.java stop method.
I changed this: @ReactMethod public void stop(final Integer key, final Callback callback) { MediaPlayer player = this.playerPool.get(key); if (player != null && player.isPlaying()) { player.pause(); player.seekTo(0); } callback.invoke(); }
to this:
@ReactMethod public void stop(final Integer key, final Callback callback) { MediaPlayer player = this.playerPool.get(key); if (player != null && player.isPlaying()) { player.stop(); player.seekTo(0); } callback.invoke(); }
and now everything works fine!! Hope it helps someone.
@zmxv maybe you can check this out. I'd be glad to submit a PR if you want.
I'm using mp3's and have this problem on Android 7.1.1. I tried the above and it didn't fix it for me unfortunately
Hi guys, I have the same problem. I solved it by @gisellezeitoune 's way but the sound stop and cannot be played again, I am using Android Virtual Device of Android Studio, Nexus 4 API 23.
Later on, I solved it by a strange way. Whenever I stop the sound, I seek it to 1 minute because all of my sounds only last for a few seconds. This is my code change in RNSoundModule.java
@ReactMethod
public void stop(final Double key, final Callback callback) {
MediaPlayer player = this.playerPool.get(key);
if (player != null && player.isPlaying()) {
// player.pause();
player.seekTo(60000);
}
// Release audio focus in Android system
if (!this.mixWithOthers && key == this.focusedPlayerKey) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audioManager.abandonAudioFocus(this);
}
callback.invoke();
}
I know this is not the best solution but hope it can help
I don't think there's a stopAll() function. You need to keep track of the instances you create. I use a single global variable. With some logic I can make sure that only one sound is being played at a time.
When you create a new sound object, assign it to a global variable. Before you create a new sound object, stop the sound on global instance Add a null check on the global variable for the first click
var whoosh = new Sound(/storage/sdcard0/Android/data/com.myapp/files/Download/${name}.mp3, '', (error) => { if (error) { alert('failed to load the sound', error); return; } if (global.sound) global.sound.stop(); global.sound = whoosh; whoosh.play( success => { console.log('Playing') } ); } People think global variables bad in JS. If you misuse yes. But this case it really is a global object and there's nothing wrong using it. It's not a misuse.
https://stackoverflow.com/questions/49620303/react-native-sound-stop-all-sounds
I use "react-native-sound": "^0.11.2" and i fixed this problem as below
useEffect(() => {
const sound = new Sound('tick.mp3', Sound.MAIN_BUNDLE, error => {
if (error) {
console.error('Failed to load sound', error);
} else {
setMetronomeSound(sound);
}
});
return () => {
// Release the sound when the component unmounts
if (metronomeSound) {
metronomeSound.release();
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
just call
if (metronomeSound) { metronomeSound.play(); }
and for stop
const stopPlayMetronome = () => { if (metronomeSound) { metronomeSound.stop(); } };