React Native Expo Audio | Play live stream from latest position

Viewed 1194

I'm writing an audio player, using Expo Audio, for an app I'm making for an online radio. The audio comes from an online live stream and, I've successfully added the player and all the things related to it; however, the one issue I'm having is that if I pause the audio when I resume playing it the audio continues from when I paused it rather than from the current position and I need to pause it and play it again to get it to update to what's currently being played. I play it with playAsync() and I've tried pausing with pauseAsync(), stopAsync(), setStatusAsync({ shouldPlay: false, positionMillis: 0 });

Any tips on how I can get it to work the way it should?

Here's the code I have for the audio player, it's a class from which then I create an instance of to be able to manage it from different places in the app:

class audioPlayer {
  static instance = null;
  static createInstance() {
    var object = new audioPlayer();
    return object;
  }

  _radioStream;

  /**
   * @returns {audioPlayer}
   */
  static getInstance() {
    if (audioPlayer.instance == null) {
      audioPlayer.instance = audioPlayer.createInstance();
    }

    return audioPlayer.instance;
  }

  // Call this first to create a new audio element
  createAudio() {
    this._radioStream = new Audio.Sound();
  };

  async loadAudioAsync() {
    try {
      await this._radioStream.loadAsync(
        { uri: "radio straem"},
      );
      store.dispatch(setLiveState(true));

      this.toggleAudio(); // Autoplay at start

      return true;
    } catch (error) {
      if (error.code === "E_LOAD_ERROR") {
        // In the case of an error we try to load again
        setTimeout(this.loadAudioAsync, 10000);

        throw new Error(error.code);
      } else {
        throw new Error(error);
      };
    };
  };

  async unloadAudioAsync() {
    await this._radioStream.unloadAsync();
  };

  async getStatusAsync() {
    return await this._radioStream.getStatusAsync();
  };

  async toggleAudio() {
    // We're gonna play or pause depending on the status
    let { isLoaded, isPlaying } = await this._radioStream.getStatusAsync();

    // If the user presses the audio and the stream connection has been lost or something
    // we try to load it again
    if (!isLoaded) {
      let res = await this.loadAudioAsync(); // Try to loadAudio again
      if (res) this.toggleAudio(); // Retrigger the toggle to start playing
    }

    if (isLoaded && !isPlaying) {
      store.dispatch(setPlayingStatus(true));
      await this._radioStream.playAsync();
    } else if (isLoaded && isPlaying) {
      store.dispatch(setPlayingStatus(false));
      await this._radioStream.setStatusAsync({ shouldPlay: false, positionMillis: 0 });
    };
  };
};
1 Answers

I just had the same exact problem (for my internet radio https://notylus.fr). It's seems that I found a solution : instead of using

playbackInstance.pauseAsync()

I now use

playbackInstance.stopAsync()

AND for the play part, I add

await playbackInstance.playAsync() //play stream playbackInstance.setPositionAsync(0) //ensure that you're at position 0

Last

Regards,

Related