Commit e72848e3 authored by Lorenzo Trujillo Rojas's avatar Lorenzo Trujillo Rojas
Browse files

Se creó un nuevo contexto para manejar la reproducción del audio

parent 761138cb
Loading
Loading
Loading
Loading
+88 −0
Original line number Diff line number Diff line
import { PropsWithChildren, createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
import { AVPlaybackSource, AVPlaybackStatus, Audio } from "expo-av";

type AudioContextType = {
    loadAudio: (source?: AVPlaybackSource) => Promise<void>;
    togglePlay: () => Promise<void>; 
    isPlaying: boolean; 
    duration: number; 
    position: number;
    onValueChange: (value: number) => void; 
    onUnmount: () => void;
}

const AudioContext = createContext(
    {
        loadAudio:  async  (source?: AVPlaybackSource) => {},
        togglePlay: async () => {}, 
        isPlaying: false, 
        duration: 0, 
        position: 0,
        onValueChange: (value: number) => {}, 
        onUnmount: () => {}
    } as AudioContextType
);

type AudioContextProviderProps = PropsWithChildren<{}>;

export const AudioContextProvider = ({children}: AudioContextProviderProps) => {
    const soundRef = useRef<Audio.Sound | null>(null);
    const [isPlaying, setIsPlaying] = useState(false);
    const [duration, setDuration] = useState(0);
    const [position, setPosition] = useState(0);

    const onPlaybackStatusUpdate = (status: AVPlaybackStatus) => {
        status.isLoaded && setPosition(status.positionMillis);
    }

    const onValueChange = (value: number) => {
        if (soundRef.current) {
            soundRef.current.setPositionAsync(value);
        }
    }

    const loadAudio = async (source?: AVPlaybackSource) => {
        if (!source) return;
        const { sound, status } = await Audio.Sound.createAsync(source, {
            shouldPlay: false
        });
        if (status.isLoaded) {
            sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
            setDuration(status.durationMillis || 0);
            soundRef.current = sound;
            setIsPlaying(status.isPlaying);
            console.log('audio loaded');
        }
    }

    const togglePlay = async () => {
        if (soundRef.current) {
            if (isPlaying) {
                await soundRef.current.pauseAsync();
            } else {
                await soundRef.current.playAsync();
            }
            setIsPlaying(!isPlaying);
        }
    }

    const onUnmount = () => {
        if (soundRef.current) {
            soundRef.current.unloadAsync();
        }
    }

    return (
        <AudioContext.Provider value={{ loadAudio, togglePlay, isPlaying, duration, position, onValueChange, onUnmount}}>
            {children}
        </AudioContext.Provider>
    );
}

export const useAudio = () => {
    const context = useContext(AudioContext);
    if (!context) {
        throw new Error("useAudio must be used within an AudioContextProvider");
    }
    return context;
}
 No newline at end of file