How to make Audio stops when I change my component props.


#1

Hey everybody.

I am working on a audio player where I have prev and next buttons. Like this:

I’am usem redux, so when next is clicked, I get the next artwork from my store and updated the Audio Player props.

Every thing is working fine, except I can’t stop the audio when I click next or I exit the navigator scene.

I tried to use .stopAsync() with Lifecycle componenet methos like ComponentWillUpdate and CompunenetWillUnmount but did’t work it.

Any help?

AudioPlayer.js

  constructor(props) {
    super(props);
    this.state = {
        currentLocale: '',
        progressPercentageWidth: 0,
        muted: false,
        playbackInstancePosition: null,
        playbackInstanceDuration: null,
        shouldPlay: false,
        isPlaying: false,
        isBuffering: false,
        isLoading: true,
        volume: 1.0,
        rate: 1.0,
        player: null
    };
  }

  componentDidMount() {
    Audio.setAudioModeAsync({
      allowsRecordingIOS: false,
      interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
      playsInSilentModeIOS: true,
      shouldDuckAndroid: true,
      interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
      playThroughEarpieceAndroid: false,
    });
    this._loadNewSound();
  }

  async _loadNewSound() {
    const source = this.props.source;
    if (source !== '') {
      const { sound } = await Sound.create(
        { uri: source },
        {},
        this._onPlaybackStatusUpdate
      );
      this.setState({ player: sound });
    }
  }

  _onPlaybackStatusUpdate = status => {
    if (status.isLoaded) {
      this.setState({
        playbackInstancePosition: status.positionMillis,
        playbackInstanceDuration: status.durationMillis,
        shouldPlay: status.shouldPlay,
        isPlaying: status.isPlaying,
        isBuffering: status.isBuffering,
        rate: status.rate,
        muted: status.isMuted,
        volume: status.volume,
      });
    }
    if (status.error) {
      console.log(`FATAL PLAYER ERROR: ${status.error}`);
    }
  };

  togglePlayer() {
    if (this.state.isPlaying) {
      this.pause();
    } else {
      this.play();
    }
  }

  play() {
    if (this.state.playbackInstancePosition === this.state.playbackInstanceDuration) {
      this.state.player.setPositionAsync(0);
    }
    this.state.player.playAsync();
  }

  stop() {
    this.state.player.stopAsync();
  }

  _getMMSSFromMillis(millis) {
    const totalSeconds = millis / 1000;
    const seconds = Math.floor(totalSeconds % 60);
    const minutes = Math.floor(totalSeconds / 60);

    const padWithZero = number => {
      const string = number.toString();
      if (number < 10) {
        return '0' + string;
      }
      return string;
    };
    return padWithZero(minutes) + ':' + padWithZero(seconds);
  }

  pause() {
    this.state.player.pauseAsync();
  }

  measureProgressBar(evt) {
    progressBarWidth = evt.nativeEvent.layout.width;
  }


  goToTime(evt) {
    const progress = evt.nativeEvent.locationX / progressBarWidth;
    const time = this.state.playbackInstanceDuration * progress;
    this.state.player.setPositionAsync(time);
    // this.setState({ progressPercentageWidth: progress });
  }


#2

now is working :sweat_smile:

  constructor(props) {
    super(props);
    this.playbackInstance = null;
    this.state = {
        currentLocale: '',
        progressPercentageWidth: 0,
        muted: false,
        playbackInstancePosition: null,
        playbackInstanceDuration: null,
        shouldPlay: false,
        isPlaying: false,
        isBuffering: false,
        isLoading: true,
        volume: 1.0,
        rate: 1.0,
    };
  }

  componentDidMount() {
    Audio.setAudioModeAsync({
      allowsRecordingIOS: false,
      interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
      playsInSilentModeIOS: true,
      shouldDuckAndroid: true,
      interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
      playThroughEarpieceAndroid: false,
    });
    this._loadNewSound(this.props.source);
  }

  componentWillReceiveProps(newProps) {
    this._loadNewSound(newProps.source);
  };

  async _loadNewSound(source) {
    console.log('playbackInstance', !this.playbackInstance);
    if (this.playbackInstance != null) {
      await this.playbackInstance.unloadAsync();
      this.playbackInstance.setOnPlaybackStatusUpdate(null);
      this.playbackInstance = null;
    }
    // const source = this.props.source;
    if (source !== '') {
      const { sound } = await Sound.create(
        { uri: source },
        {},
        this._onPlaybackStatusUpdate
      );
      this.playbackInstance = sound;
    }
  }

#3

Glad you got it figured out @manebrasil123!

Cheers,

Adam


closed #4

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.