可能未处理的承诺拒绝:将不同的歌曲数据传递到 react-native-track-player 中的播放器屏幕

问题描述

我创建了流派(多首歌曲数据并将歌曲数据传递给我项目中的同一个 PlayerScreen.js,但我开始出现 TypeErrors 和警告:

可能的未处理的承诺拒绝(id:3): 类型错误:无法读取 null 的属性“scrollToOffset” 类型错误:无法读取 null 的属性“scrollToOffset”

例如,我现在有流行、乡村、摇滚、嘻哈等流派,我在所有流派中都有相同的歌曲数组,我用相同的代码创建了不同的播放器屏幕。但我相信我没有做正确的事情。请问我怎样才能有不同的歌曲数据(流派)并使用一个播放器屏幕来播放歌曲?

这是我的代码。 hiphopData.js:

const hiphopsongs = [
    {
      title: "death bed",artist: "Powfu",genre: "Pop",artwork: require("../../../assets/album-arts/death-bed.jpg"),url: "https://github.com/ShivamJoker/sample-songs/raw/master/death%20bed.mp3",id: "1",},{
      title: "bad liar",artist: "Imagine Dragons",artwork: require("../../../assets/album-arts/bad-liar.jpg"),url: "https://github.com/ShivamJoker/sample-songs/raw/master/Bad%20Liar.mp3",id: "2",{
      title: "faded",artist: "Alan Walker",artwork: require("../../../assets/album-arts/faded.jpg"),url: "https://github.com/ShivamJoker/sample-songs/raw/master/Faded.mp3",id: "3",{
      title: "hate me",artist: "Ellie Goulding",artwork: require("../../../assets/album-arts/hate-me.jpg"),url: "https://github.com/ShivamJoker/sample-songs/raw/master/Hate%20Me.mp3",id: "4",{
      title: "Solo",artist: "Clean Bandit",artwork: require("../../../assets/album-arts/solo.jpg"),url: "https://github.com/ShivamJoker/sample-songs/raw/master/Solo.mp3",id: "5",{
      title: "without me",artist: "Halsey",artwork: require("../../../assets/album-arts/without-me.jpg"),url: "https://github.com/ShivamJoker/sample-songs/raw/master/Without%20Me.mp3",id: "6",];
  
  export default hiphopsongs;
  

hiphopPlayerScreen.js:

import React,{useRef,useEffect,useState} from 'react';
import {
  View,SafeAreaView,Text,Image,FlatList,Dimensions,Animated,StyleSheet,TouchableOpacity,} from 'react-native';

import { useNavigation } from '@react-navigation/native';

import TrackPlayer,{
  Capability,useTrackPlayerEvents,usePlaybackState,TrackPlayerEvents,STATE_PLAYING,Event,} from 'react-native-track-player';

import songs from '../../components/TracksData/hipHopData';
import Controller from '../../components/Controller';
import SliderComp from '../../components/SliderComp';
import SimpleLineIcons from 'react-native-vector-icons/SimpleLineIcons';

const {width,height} = Dimensions.get('window');

// const events = [
//   TrackPlayerEvents.PLAYBACK_STATE,//   TrackPlayerEvents.PLAYBACK_ERROR
// ];

export default function PlayerScreen() {

  const navigation = useNavigation();

  const scrollX = useRef(new Animated.Value(0)).current;

  const slider = useRef(null);
  const isPlayerReady = useRef(false);
  const index = useRef(0);

  const [songIndex,setSongIndex] = useState(0);
  

  const isItFromUser = useRef(true);

  // for tranlating the album art
  const position = useRef(Animated.divide(scrollX,width)).current;
  const playbackState = usePlaybackState();

  useEffect(() => {
    // position.addListener(({ value }) => {
    //   console.log(value);
    // });

    scrollX.addListener(({value}) => {
      const val = Math.round(value / width);

      setSongIndex(val);
    });

    TrackPlayer.setupPlayer().then(async () => {
      // The player is ready to be used
      console.log('Player ready');
      // add the array of songs in the playlist
      await TrackPlayer.reset();
      await TrackPlayer.add(songs);
      TrackPlayer.play();
      isPlayerReady.current = true;

      await TrackPlayer.updateOptions({
        stopWithApp: false,alwaysPauSEOnInterruption: true,capabilities: [
          Capability.Play,Capability.Pause,Capability.SkipToNext,Capability.SkipToPrevIoUs,],});
      //add listener on track change
      TrackPlayer.addEventListener(Event.PlaybackTrackChanged,async (e) => {
        console.log('song ended',e);

        const trackId = (await TrackPlayer.getCurrentTrack()) - 1; //get the current id

        console.log('track id',trackId,'index',index.current);

        if (trackId !== index.current) {
          setSongIndex(trackId);
          isItFromUser.current = false;

          if (trackId > index.current) {
            goNext();
          } else {
            goPrv();
          }
          setTimeout(() => {
            isItFromUser.current = true;
          },200);
        }

        // isPlayerReady.current = true;
      });

      //monitor intterupt when other apps start playing music
      TrackPlayer.addEventListener(Event.RemoteDuck,(e) => {
        // console.log(e);
        if (e.paused) {
          // if pause true we need to pause the music
          TrackPlayer.pause();
        } else {
          TrackPlayer.play();
        }
      });
    });

    return () => {
      scrollX.removeAllListeners();
      TrackPlayer.destroy();

      // exitPlayer();
    };
  },[]);

  // change the song when index changes
  useEffect(() => {
    if (isPlayerReady.current && isItFromUser.current) {
      TrackPlayer.skip(songs[songIndex].id)
        .then((_) => {
          console.log('changed track');
        })
        .catch((e) => console.log('error in changing track ',e));
    }
    index.current = songIndex;
  },[songIndex]);

  const exitPlayer = async () => {
    try {
      await TrackPlayer.stop();
    } catch (error) {
      console.error('exitPlayer',error);
    }
  };

  const goNext = async () => {
    slider.current.scrollToOffset({
      offset: (index.current + 1) * width,});

    await TrackPlayer.play();
  };
  const goPrv = async () => {
    slider.current.scrollToOffset({
      offset: (index.current - 1) * width,});

    await TrackPlayer.play();
  };

  const renderItem = ({index,item}) => {
    return (
      <Animated.View
        style={{
          alignItems: 'center',width: width,transform: [
            {
              translateX: Animated.multiply(
                Animated.add(position,-index),-100,),}}>
        <Animated.Image
          source={item.artwork}
          style={{width: 320,height: 320,borderRadius: 5}}
        />
      </Animated.View>
    );
  };

  return (
    <SafeAreaView style={styles.container}>
      <SafeAreaView style={{height: 320}}>
        <Animated.FlatList
          ref={slider}
          horizontal
          pagingEnabled
          showsHorizontalScrollIndicator={false}
          scrollEventThrottle={16}
          data={songs}
          renderItem={renderItem}
          keyExtractor={(item) => item.id}
          onScroll={Animated.event(
            [{nativeEvent: {contentOffset: {x: scrollX}}}],{useNativeDriver: true},)}
        />
      </SafeAreaView>
      <TouchableOpacity 
        style={styles.genreContainer}
        onPress={() => navigation.navigate('Genre')}
      >
        <SimpleLineIcons name="playlist" size={20} color='#fff' />
        <Text style={styles.genre}> Genre</Text>
      </TouchableOpacity>
      <View>
        <Text style={styles.title}>{songs[songIndex].title}</Text>
        <Text style={styles.artist}>{songs[songIndex].artist}</Text>
      </View>

      <SliderComp />

      <Controller onNext={goNext} onPrv={goPrv} />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    justifyContent: 'space-evenly',alignItems: 'center',height: height,maxHeight: 600,backgroundColor: '#030303'
  },genreContainer: {
    flexDirection: 'row',genre: {
    fontSize: 18,textAlign: 'center',fontWeight: '600',textTransform: 'capitalize',color: '#ffffff',title: {
    fontSize: 28,artist: {
    fontSize: 18,});

我对自己创作的所有类型都这样做了,但我觉得这不是正确的做法。请帮助我将所有类型数据传递到一个播放器屏幕。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)