react-native-sound
react-native-sound copied to clipboard
Playing the next track in the done callback of the play() function doesn't work
:beetle: Description
I have an app where I have a series of tracks, they're specified by state variable index, at the callback of the play(cb) function I call setIndex(index + 1)... that in turn triggers a useEffect hook which loads the next sound and calls play() again.
It doesn't play the next sound, it just errors on "sound playback failed". I have a button on the screen that calls play() as well, and that does work, even after the error.
I tried putting the call to play() function from the useEffect hook in a setTimeout to avoid potential scheduling issues, but it still fails.
It seems that play function doesn't work if it's not triggered by a user-initiated event.
:beetle: What is the observed behavior? I see
Sound playback failed
in the console.
:beetle: What is the expected behavior? Next track should play.
:beetle: Please post your code:
import {Button, Text, View} from 'react-native';
import {useContext, useEffect, useState} from 'react';
import {useDownloadBookSection} from '../hooks/page_info';
import {BookContext} from './book_player';
import Sound from 'react-native-sound';
export const PlayerControls = ({
playing,
setPlaying,
index,
setIndex,
}: {
playing: boolean;
index: number;
setIndex: (n: number) => void;
setPlaying: (p: boolean) => void;
}) => {
const [sound, setSound] = useState<Sound>(null!);
const {bookName, pageNum} = useContext(BookContext);
const {filePath, status, error} = useDownloadBookSection(
bookName,
pageNum,
index,
);
useEffect(() => {
console.log('filepath', filePath, 'status', status);
if (status != 'completed') {
return;
}
const sound = new Sound(filePath, '', error => {
if (error) {
console.log('Failed to load sound', error);
return;
}
console.log('successfully loaded sound', sound);
setSound(sound);
if (playing) {
play();
}
});
return () => {
if (sound) {
sound.release();
}
};
}, [filePath, status]);
const noSound = () => {
if (!sound) {
console.warn('no sound!');
return true;
}
return false;
};
const play = () => {
if (noSound()) {
return;
}
if (!playing) {
setPlaying(true);
}
sound.play(success => {
if (success) {
console.log('Sound played successfully');
setIndex(index + 1);
} else {
console.log('Sound playback failed');
}
});
};
const pause = () => {
if (noSound()) {
return;
}
setPlaying(false);
sound.pause();
};
return (
<View>
<Text>
status: {status}: {error}
</Text>
<Button
title={playing ? 'Pause' : 'Play'}
onPress={() => (playing ? pause() : play())}
/>
</View>
);
};
:bulb: Does the problem have a test case?
No
:bulb: Possible solution No
:bulb: Is there a workaround? No
:bulb: If the bug is confirmed, would you be willing to create a pull request? Yes
Is your issue with...
- [x] iOS
- [ ] Android
- [ ] Windows
Are you using...
- [x] React Native CLI (e.g.
react-native run-android) - [ ] Expo
- [ ] Other: (please specify)
Which versions are you using?
- React Native Sound: ^0.11.2
- React Native: 0.71.8
- iOS: 16.4.1
- Android:
- Windows:
Does the problem occur on...
- [ ] Simulator
- [x] Device
If your problem is happening on a device, which device?
- Device: iPhone 14 Pro
ah I noticed #825 's similar to this.