Giter Club home page Giter Club logo

Comments (1)

into-piece avatar into-piece commented on June 22, 2024
import {
    useCallback,
    useEffect,
    useRef,
    useState,
    MutableRefObject,
} from 'react';
import Sound from 'react-native-sound';
import { downLoadFile } from '@/utils/utils';

type Status = 'pause' | 'play' | 'pending';

export const statusMap: Record<'PAUSE' | 'PLAY' | 'PENDING', Status> = {
    PAUSE: 'pause',
    PLAY: 'play',
    PENDING: 'pending',
};

export type SoundMethods = {
    play: (callback: (error: Error) => void) => void;
    pause: () => void;
};

export type Info = {
    status: Status;
    currentTime: number;
    duration: number;
};

const useSound = (
    url: string
): [SoundMethods, Info, MutableRefObject<Sound | null>] => {
    const soundRef = useRef<Sound | null>(null);
    const timer = useRef<any>(null);
    const [status, setStatus] = useState(statusMap.PAUSE);
    const [currentTime, setCurrentTime] = useState(0);
    const [error, setError] = useState('');
    const [duration, setDuration] = useState(0);

    const play = useCallback(
        (callback) => {
            setStatus(statusMap.PLAY);
            soundRef.current?.play((success) => {
                if (success) {
                    clearInterval(timer.current);
                    setStatus(statusMap.PAUSE);
                    setCurrentTime(duration);
                }
            });
            callback(error);
        },
        [error, duration]
    );

    const pause = useCallback(() => {
        soundRef.current?.pause();
        setStatus(statusMap.PAUSE);
    }, []);

    useEffect(() => {
        if (status === statusMap.PLAY) {
            timer.current = setInterval(() => {
                soundRef.current?.getCurrentTime((second) => {
                    setCurrentTime(second);
                });
            }, 1000);
        }
        return () => {
            clearInterval(timer.current);
        };
    }, [status, soundRef]);

    useEffect(() => {
        if (!url) {
            return;
        }
        setStatus(statusMap.PENDING);
        const { savePath, rnfs } = downLoadFile(url);
        rnfs.promise
            .then((res) => {
                if (res.statusCode === 200) {
                    soundRef.current = new Sound(savePath, '', (err) => {
                        if (err) {
                            setError(err);
                            return;
                        }
                        setDuration(soundRef.current?.getDuration()!);
                    });
                    setStatus(statusMap.PAUSE);
                }
            })
            .catch((err) => {
                setError(err);
            });
        return () => {
            soundRef.current?.release();
        };
    }, [url]);

    return [
        { play, pause },
        {
            status,
            currentTime,
            duration,
        },
        soundRef,
    ];
};

export default useSound;

from step-by-step.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.