使用react-native-track-player正确切换播放状态以进行实时音频流React Native应用程序(shoutcast)

问题描述 投票:0回答:1

我似乎无法让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>
        )
}

...

javascript react-native react-hooks shoutcast react-native-track-player
1个回答
0
投票

我的实现在设置完成后使用单个

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年历史了)

© www.soinside.com 2019 - 2024. All rights reserved.