import { formatTime } from '@/utils/index'; import { PauseCircleFilled, PlayCircleFilled } from '@ant-design/icons'; import { Button, Slider } from 'antd'; import React, { forwardRef, useCallback, useEffect, useImperativeHandle } from 'react'; import IconFont from '../icon-font'; import './index.less'; interface AudioPlayerProps { autoplay?: boolean; url: string; speed?: number; ref?: any; name: string; height?: number; width?: number; duration?: number; } const AudioPlayer: React.FC = forwardRef((props, ref) => { const { autoplay = false, speed: defaultSpeed = 1 } = props; const audioRef = React.useRef(null); const [audioState, setAudioState] = React.useState<{ currentTime: number; duration: number; }>({ currentTime: 0, duration: 0 }); const [playOn, setPlayOn] = React.useState(false); const [speakerOn, setSpeakerOn] = React.useState(false); const [volume, setVolume] = React.useState(0.5); const [speed, setSpeed] = React.useState(defaultSpeed); const timer = React.useRef(null); useImperativeHandle(ref, () => ({ play: () => { audioRef.current?.play(); }, pause: () => { audioRef.current?.pause(); } })); const handleAudioOnPlay = useCallback(() => { timer.current = setInterval(() => { setAudioState((prestate) => { return { currentTime: Math.ceil(audioRef.current?.currentTime || 0), duration: prestate.duration || Math.ceil(audioRef.current?.duration || 0) }; }); if (audioRef.current?.paused || audioRef.current?.ended) { clearInterval(timer.current); setPlayOn(false); setAudioState((prestate: any) => { return { currentTime: 0, duration: prestate.duration }; }); } }, 500); }, []); const handlePlay = useCallback(() => { if (playOn) { audioRef.current?.pause(); } else { audioRef.current?.play(); } setPlayOn(!playOn); }, [playOn]); const initPlayerConfig = useCallback(() => { // set volume audioRef.current!.volume = volume; // set playback rate audioRef.current!.playbackRate = speed; }, []); const handleLoadedMetadata = useCallback( (data: any) => { const duration = Math.ceil(audioRef.current?.duration || 0); setAudioState({ currentTime: 0, duration: duration && duration !== Infinity ? duration : props.duration || 0 }); setPlayOn(autoplay); }, [autoplay, props.duration] ); const handleCurrentChange = useCallback((val: number) => { audioRef.current!.currentTime = val; setAudioState((prestate) => { return { currentTime: val, duration: prestate.duration }; }); }, []); useEffect(() => { if (audioRef.current) { initPlayerConfig(); } }, [audioRef.current]); useEffect(() => { return () => { clearInterval(timer.current); }; }, []); return (
{' '} {formatTime(audioState.currentTime)}
{props.name}
{props.speed ? `${props.speed}x` : '1x'}
{formatTime(audioState.duration)}
); }); export default React.memo(AudioPlayer);