| | import { useEffect, useRef } from 'react'; |
| |
|
| | interface CustomAudioElement extends HTMLAudioElement { |
| | customStarted?: boolean; |
| | customEnded?: boolean; |
| | customPaused?: boolean; |
| | customProps?: { |
| | customStarted?: boolean; |
| | customEnded?: boolean; |
| | customPaused?: boolean; |
| | }; |
| | } |
| |
|
| | type TCustomAudioResult = { audioRef: React.MutableRefObject<CustomAudioElement | null> }; |
| |
|
| | export default function useCustomAudioRef({ |
| | setIsPlaying, |
| | }: { |
| | setIsPlaying: (isPlaying: boolean) => void; |
| | }): TCustomAudioResult { |
| | const audioRef = useRef<CustomAudioElement | null>(null); |
| | useEffect(() => { |
| | let lastTimeUpdate: number | null = null; |
| | let sameTimeUpdateCount = 0; |
| |
|
| | const handleEnded = () => { |
| | setIsPlaying(false); |
| | console.log('global audio ended'); |
| | if (audioRef.current) { |
| | audioRef.current.customEnded = true; |
| | URL.revokeObjectURL(audioRef.current.src); |
| | } |
| | }; |
| |
|
| | const handleStart = () => { |
| | setIsPlaying(true); |
| | console.log('global audio started'); |
| | if (audioRef.current) { |
| | audioRef.current.customStarted = true; |
| | } |
| | }; |
| |
|
| | const handlePause = () => { |
| | console.log('global audio paused'); |
| | if (audioRef.current) { |
| | audioRef.current.customPaused = true; |
| | } |
| | }; |
| |
|
| | const handleTimeUpdate = () => { |
| | if (audioRef.current) { |
| | const currentTime = audioRef.current.currentTime; |
| | |
| |
|
| | if (currentTime === lastTimeUpdate) { |
| | sameTimeUpdateCount += 1; |
| | } else { |
| | sameTimeUpdateCount = 0; |
| | } |
| |
|
| | lastTimeUpdate = currentTime; |
| |
|
| | if (sameTimeUpdateCount >= 1) { |
| | console.log('Detected end of audio based on time update'); |
| | audioRef.current.pause(); |
| | handleEnded(); |
| | } |
| | } |
| | }; |
| |
|
| | const audioElement = audioRef.current; |
| |
|
| | if (audioRef.current) { |
| | audioRef.current.addEventListener('ended', handleEnded); |
| | audioRef.current.addEventListener('play', handleStart); |
| | audioRef.current.addEventListener('pause', handlePause); |
| | audioRef.current.addEventListener('timeupdate', handleTimeUpdate); |
| |
|
| | audioRef.current.customProps = { |
| | customStarted: false, |
| | customEnded: false, |
| | customPaused: false, |
| | }; |
| | } |
| |
|
| | return () => { |
| | if (audioElement) { |
| | audioElement.removeEventListener('ended', handleEnded); |
| | audioElement.removeEventListener('play', handleStart); |
| | audioElement.removeEventListener('pause', handlePause); |
| | audioElement.removeEventListener('timeupdate', handleTimeUpdate); |
| | URL.revokeObjectURL(audioElement.src); |
| | } |
| | }; |
| | }, [setIsPlaying]); |
| |
|
| | return { audioRef }; |
| | } |
| |
|