我似乎无法让react-native-track-player 在我的广播流应用程序(shoutcast)中完全运行。我用来切换播放的 TouchableOpacity 似乎只能在第二次按下后才能工作。即使这样,切换似乎也不能可靠地工作。我想我的逻辑设置不正确..
我还意识到我应该通过react-native-track-player更新元数据,而不是我编写的自定义挂钩。
如果有人能指出我的错误,我将不胜感激!预先感谢 🙂
使用:
主屏逻辑:
...
const [playingState, setState] = useState(true)
const [song, setSong] = useState('');
const [musician, setMusician] = useState('');
useEffect(() => {
let repeat;
async function fetchData() {
try {
const res = await fetch(" * my API url ");
const json = await res.json();
setSong(json.data[0].track.title);
setMusician(json.data[0].track.artist);
repeat = setTimeout(fetchData, 26000);
} catch (error) {
console.error(error.message)
}
}
fetchData();
return () => {
if (repeat) {
clearTimeout(repeat);
}
}
}, []);
var songTitle = JSON.stringify(song)
var musicianName = JSON.stringify(musician)
const playbackState = usePlaybackState();
async function setup() {
await TrackPlayer.setupPlayer({});
await TrackPlayer.updateOptions({
stopWithApp: true,
capabilities: [
TrackPlayer.CAPABILITY_PLAY,
TrackPlayer.CAPABILITY_PAUSE,
TrackPlayer.CAPABILITY_STOP
],
compactCapabilities: [
TrackPlayer.CAPABILITY_PLAY,
TrackPlayer.CAPABILITY_PAUSE
]
});
}
useEffect(() => {
setup();
}, []);
async function togglePlayback() {
const currentTrack = await TrackPlayer.getCurrentTrack();
if (currentTrack == null) {
await TrackPlayer.reset();
await TrackPlayer.add({
id: 0,
title: songTitle,
url: " my audio stream URL ",
artist: musicianName,
album: null,
date: null,
genre: null}
);
await TrackPlayer.play();
} else {
if (playbackState === TrackPlayer.STATE_PAUSED) {
setState(!playingState)
await TrackPlayer.play();
} else {
await TrackPlayer.pause();
}
}
}
...
主屏前端:
...
<TouchableOpacity
onPress={() => togglePlayback()}
style={[
styles.playButtonContainer,
screenData.isLandscape && styles.playButtonContainerLandscape
]}>
{playingState ? (
<View style={{ alignContent: 'center', justifyContent: 'center' }}>
<Image
source={playButton}
style={styles.playPauseButton}
resizeMode='contain'
/>
</View>
) : (
<View style={{ alignContent: 'center', justifyContent: 'center' }}>
<Pulse color='white' numPulses={3} diameter={400} speed={20} duration={2000}
style={{ alignSelf: 'center', opacity: 50, zIndex: 0 }} />
<Image
source={pauseButton}
style={styles.playPauseButton}
resizeMode='contain'
/>
<LottieView
source={visualizer}
autoPlay
loop
style={{
zIndex: 1,
width: screenWidth,
height: 200,
position: 'absolute',
alignSelf: 'center'
}}
isPaused={false}
/>
</View>
)}
</TouchableOpacity>
{
playingState ? (
<Text
style={styles.trackTitle}>{''}</Text>
) : (
<Text
style={styles.trackTitle}>{song}</Text>
)
}
{
playingState ? (
<Text style={styles.tuneInTitle}>Tap the play button to tune in</Text>
) : (
<Text style={styles.artistName}>{musician}</Text>
)
}
...
我的实现在设置完成后使用单个
useEffect
。像这样的东西(在你的用例中)
useEffect(() => {
setup().then(function () {
let repeat;
async function fetchData() {
try {
const res = await fetch(" * my API URL ");
const json = await res.json();
setSong(json.data[0].track.title);
setMusician(json.data[0].track.artist);
repeat = setTimeout(fetchData, 26000);
} catch (error) {
console.error(error.message)
}
}
fetchData();
};
return () => {
if (repeat) {
clearTimeout(repeat);
}
};
}, []);
这使我的应用程序按预期工作。
对于更新元数据,我使用 ReactNativeTrackPlayer 方法
await TrackPlayer.updateMetadataForTrack(0, {
title: trackInfo.title,
artist: trackInfo.song,
artwork: trackInfo.cover,
album: config.album
})
而且,我使用的是
fetchData()
方法,而不是您的方法 updateScreen
,该方法从 currentTrackNumber
获取信息,即
const currentTrackNumber = await TrackPlayer.getActiveTrackIndex();
然后用
更新屏幕setTitle(tracks[currentTrackNumber].title);
setSong(tracks[currentTrackNumber].artist);
setCover(tracks[currentTrackNumber].artwork);
希望这对你有帮助(即使这个问题已经有3年历史了)