React Native Expo AV audio player - react redux state management

Viewed 354

How to manage state for realtime updates How to update state for songs in react native expo av audio.

import { PLAY_MUSIC } from "../Types/Types";
import { Audio } from 'expo-av';

var initialState = {
    music: null,
    isPlaying: false,
    playbackObj: null,
    soundObj: null,
    duration: 0,
    position: 0,
    sliderPosition: 0,
};

const MusicReducer = (state = initialState, action) => {
    switch(action.type) {

        case PLAY_MUSIC:
            //console.log(state);
            audioPlay(action.payload);
            return initialState;

        default: return state;
    }
};

const audioPlay = async(payload) => {
    //play song
    if(initialState.soundObj === null) {
        const audio = new Audio.Sound();
        Audio.setAudioModeAsync({
            staysActiveInBackground: true,
            playsInSilentModeIOS: true,
            playThroughEarpieceAndroid: false,
            interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
            interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
        });
        const status = await audio.loadAsync(
            { uri: payload.url },
            { shouldPlay: true }
        );
        audio.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
        audio.setProgressUpdateIntervalAsync(1000);
        const data = {playbackObj:audio, soundObj:status, music:payload, isPlaying:true};
        initialState = {...initialState, ...data};
        return;
    }

    //pause song
    if(initialState.soundObj.isLoaded && initialState.soundObj.isPlaying && initialState.music._id===payload._id) {
        const status = await initialState.playbackObj.setStatusAsync({shouldPlay: false});
        return {soundObj:status, sliderPosition:status.positionMillis, isPlaying:false};

    }

    //resume song
    if(initialState.soundObj.isLoaded && !initialState.soundObj.isPlaying && initialState.music._id===payload._id) {
        const status = await initialState.playbackObj.playAsync();
        return {soundObj:status, isPlaying:true};
    }

    //select another song
    if(initialState.soundObj.isLoaded && initialState.music._id !== payload._id) {
        const status = await initialState.playbackObj.playAsync();
        return {soundObj:status};
    }

    return;
};

const onPlaybackStatusUpdate = async(status) => {
    if(status.isLoaded && status.isPlaying) {
        const data =  {duration:status.durationMillis, position:status.positionMillis, sliderPosition:status.positionMillis};
        initialState = {...initialState, ...data};
        return;
    }

    //play next automatically
    if(status.didJustFinish) {
        //pass index of next music
        const status = await playNext(val);
        return {soundObj:status, music:val};
    }
};

const playNext = async(val) => {
    await initialState.playbackObj.stopAsync();
    await initialState.playbackObj.unloadAsync();
    await initialState.playbackObj.stopAsync();
    audioPlay(val);
};

export default MusicReducer;

How to manage state for realtime updates How to update state for songs in react native expo av audio.

How to manage state for realtime updates How to update state for songs in react native expo av audio.

How to manage state for realtime updates How to update state for songs in react native expo av audio.

How to manage state for realtime updates How to update state for songs in react native expo av audio.

0 Answers
Related