0

我正在尝试使用 react native 和 expo av 创建一个音频播放器。我可以很好地播放在线远程文件(通过 uri),而且我的代码运行良好。但是,每当我尝试播放本地文件时,它都会抛出错误:[Unhandled promise rejection: Error: Cannot load an AV asset from a null playback source]. 我现在用于音频处理的大部分代码都是通过 处理的handleAudioPlayPause,它在按下按钮时被调用。我怎样才能让这个程序毫无问题地播放本地文件?谢谢

const audio = {
  filename: 'Audio file 1',
  uri:
  require('../assets/sounds/hello.mp3'), //this does not work
    // 'https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3', // this works
};

...

const [isPlaying, setIsPlaying] = useState(false);
const [playbackObject, setPlaybackObject] = useState<any | null>(null);
const [playbackStatus, setPlaybackStatus] = useState<any | null>(null);
useEffect(() => {
    if (playbackObject === null) {
      setPlaybackObject(new Audio.Sound());
    }
  }, []);
   const handleAudioPlayPause = async () => {
    if (playbackObject !== null && playbackStatus === null) {
      const status = await playbackObject.loadAsync(
        { uri: audio.uri },
        { shouldPlay: true }
      );
      setIsPlaying(true);
      return setPlaybackStatus(status);
    }

    // It will pause our audio
    if (playbackStatus.isPlaying) {
      const status = await playbackObject.pauseAsync();
      setIsPlaying(false);
      return setPlaybackStatus(status);
    }

    // It will resume our audio
    if (!playbackStatus.isPlaying) {
      const status = await playbackObject.playAsync();
      console.log(status);
      setIsPlaying(true);
      return setPlaybackStatus(status);
    }
  };
  
4

3 回答 3

1

查看加载音频文件的不同方法

  1. 对于远程文件,像你一样使用它
const status = await playbackObject.loadAsync(
  { uri: audio.uri }, // For remote files we have to place uri like this
  { shouldPlay: true }
);
  1. 但是对于本地文件,你必须像这样使用它,
const status = await playbackObject.loadAsync(
  audio.uri, // For local files we have to use it like this
  { shouldPlay: true }
);

这里的工作示例

于 2021-07-01T06:16:12.230 回答
0

我认为 useState应该使用而不是你useRef,因为 useState 会导致重新渲染,但 useRef 不会。useState如果我们想在 UI 上反映变化,我们通常会使用。

  const soundRef = useRef(null);

useEffect(() => {
       #you could have multiple sound files to load
        const soundObject = new Audio.Sound();
  
        const loadSounds = async () => {
            await soundObject.loadAsync("Your config");
            soundRef.current = soundObject;

        };
        loadSounds();
        // ALways clean up running files
        return () => {
            soundObject && soundObject.unloadAsync();
            
        };
    }, []);
于 2021-08-02T21:56:16.317 回答
0

只是为了改进 Kartikey 答案,对于本地文件,以下内容对我有用。

 const { sound } = await Audio.Sound.createAsync(
  { uri: recording.getURI() },
  {
    shouldPlay: true,
  }
);
于 2021-08-21T20:21:10.960 回答