首页 > 解决方案 > 如何从 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-nativereact-native-sound

解决方案


我会给你我的钩子来播放一些实际上没有使用react-native-soundnor的音频react-native-audio-recorder-player,但我想这会对你有所帮助。

基本上,当你播放声音时,你会得到 Promises。因此,您要做的就是像这样循环遍历音频数组并一个接一个地解决 Promise。

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 };
};

推荐阅读