如何在 React Native 中从数组中一个接一个地播放曲目?
How can I play tracks one after another from the array in React Native?
我使用了 react-native-sound 和 react-native-audio-recorder-player 等库来播放数组中的曲目。我尝试映射阵列,但它只播放第一首曲目。
有什么方法可以一个接一个地播放阵列中的所有曲目吗?
const[id, setId] = useState(1)
const sound = new Sound(('/data/user/0/com.hay/cache/' + id + '.mp3'), Sound.MAIN_BUNDLE)
const playA = () => {
sound.play(success=> setId(id+1))
}
return (
<View style={{flex: 1, backgroundColor: '#FFEDCB', justifyContent: 'center'}}>
<View style={{alignSelf: 'center'}} >
<Image source={globo} style={{width: 340, height: 484}} />
<View style={{ position: 'absolute', top: 403 }}>
<View style={{flexDirection: 'row',position: 'absolute', right: -120 }}>
<TouchableOpacity onPress={()=>playA() }
style={styles.iconHeart}><Icon name={ 'play-circle-outline'}
size={60} color='#F8C56A' /></TouchableOpacity>
</View></View></View></View>
);
};
我会给你我的钩子来播放一些实际上没有使用 react-native-sound
和 react-native-audio-recorder-player
的音频,但我想这会对你有所帮助。
基本上,当您播放声音时,您会得到 Promises。所以你要做的就是循环遍历音频数组并像这样一个接一个地解决Promises。
audios.reduce((p, audio) => p.then(() => audioPlay(audio)), Promise.resolve());
下面的代码是我的钩子的完整版本。
import { useState } from 'react';
import { Player } from '@react-native-community/audio-toolkit';
export const useAudioPlay = ({ audioDatas = [] }) => {
const [isPlaying, setIsPlayIng] = useState(false);
const [currentAudio, setCurrentAudio] = useState();
const audios = audioDatas.map((audioData) => new Player(audioData));
const audioPlay = async (audio) => {
setCurrentAudio(audio);
setIsPlayIng(true);
await new Promise((resolve) =>
audio.play().on('ended', () =>
setTimeout(() => {
if (audio === audios[audios.length - 1]) {
setIsPlayIng(false);
}
resolve();
}, 500)
)
);
};
const stopAudio = () => {
if (currentAudio) {
currentAudio.stop();
setIsPlayIng(false);
}
};
/*
* this meybe what you want.
*/
const playAudios = () => {
if (isPlaying) {
stopAudio();
return;
}
audios.reduce((p, audio) => p.then(() => audioPlay(audio)), Promise.resolve());
};
return { playAudios, stopAudio, isPlaying };
};
在 react-native-sound
中使用此回调
play(onEnd?: (success: boolean) => void): void
例子
Sound.play((success)=> success && nextSong(withID))
使用 useEffect
以便播放下一首歌曲。
useEffect(() => {
playA()
}, [id]
);
const LastSongID = 10 // Add Logic for LastSong
const playA = () => {
sound.play((success) => {
if (success && id !== LastSongID) setId(id + 1);
});
};
它应该是这样的:
useEffect( () => {
let sound = new Sound(('/data/user/0/com.hay/cache/' + id + '.mp3'), Sound.MAIN_BUNDLE, (error) => {
if (error) {
console.log('failed to load the sound', error);
} else {
sound.play((success) => setId(id+1));
}
});
}, [id] )
我使用了 react-native-sound 和 react-native-audio-recorder-player 等库来播放数组中的曲目。我尝试映射阵列,但它只播放第一首曲目。 有什么方法可以一个接一个地播放阵列中的所有曲目吗?
const[id, setId] = useState(1)
const sound = new Sound(('/data/user/0/com.hay/cache/' + id + '.mp3'), Sound.MAIN_BUNDLE)
const playA = () => {
sound.play(success=> setId(id+1))
}
return (
<View style={{flex: 1, backgroundColor: '#FFEDCB', justifyContent: 'center'}}>
<View style={{alignSelf: 'center'}} >
<Image source={globo} style={{width: 340, height: 484}} />
<View style={{ position: 'absolute', top: 403 }}>
<View style={{flexDirection: 'row',position: 'absolute', right: -120 }}>
<TouchableOpacity onPress={()=>playA() }
style={styles.iconHeart}><Icon name={ 'play-circle-outline'}
size={60} color='#F8C56A' /></TouchableOpacity>
</View></View></View></View>
);
};
我会给你我的钩子来播放一些实际上没有使用 react-native-sound
和 react-native-audio-recorder-player
的音频,但我想这会对你有所帮助。
基本上,当您播放声音时,您会得到 Promises。所以你要做的就是循环遍历音频数组并像这样一个接一个地解决Promises。
audios.reduce((p, audio) => p.then(() => audioPlay(audio)), Promise.resolve());
下面的代码是我的钩子的完整版本。
import { useState } from 'react';
import { Player } from '@react-native-community/audio-toolkit';
export const useAudioPlay = ({ audioDatas = [] }) => {
const [isPlaying, setIsPlayIng] = useState(false);
const [currentAudio, setCurrentAudio] = useState();
const audios = audioDatas.map((audioData) => new Player(audioData));
const audioPlay = async (audio) => {
setCurrentAudio(audio);
setIsPlayIng(true);
await new Promise((resolve) =>
audio.play().on('ended', () =>
setTimeout(() => {
if (audio === audios[audios.length - 1]) {
setIsPlayIng(false);
}
resolve();
}, 500)
)
);
};
const stopAudio = () => {
if (currentAudio) {
currentAudio.stop();
setIsPlayIng(false);
}
};
/*
* this meybe what you want.
*/
const playAudios = () => {
if (isPlaying) {
stopAudio();
return;
}
audios.reduce((p, audio) => p.then(() => audioPlay(audio)), Promise.resolve());
};
return { playAudios, stopAudio, isPlaying };
};
在 react-native-sound
play(onEnd?: (success: boolean) => void): void
例子
Sound.play((success)=> success && nextSong(withID))
使用 useEffect
以便播放下一首歌曲。
useEffect(() => {
playA()
}, [id]
);
const LastSongID = 10 // Add Logic for LastSong
const playA = () => {
sound.play((success) => {
if (success && id !== LastSongID) setId(id + 1);
});
};
它应该是这样的:
useEffect( () => {
let sound = new Sound(('/data/user/0/com.hay/cache/' + id + '.mp3'), Sound.MAIN_BUNDLE, (error) => {
if (error) {
console.log('failed to load the sound', error);
} else {
sound.play((success) => setId(id+1));
}
});
}, [id] )