Files
party-mix-app/apps/web/src/hooks/usePlayer.ts

42 lines
1.4 KiB
TypeScript

'use client'
import { useRef, useCallback } from 'react'
export function useAudioEngine() {
const audioRef = useRef<HTMLAudioElement | null>(null)
const audioCtxRef = useRef<AudioContext | null>(null)
const analyserRef = useRef<AnalyserNode | null>(null)
const sourceRef = useRef<MediaElementAudioSourceNode | null>(null)
const initAudioViz = useCallback(() => {
const audio = audioRef.current
if (!audio || typeof window === 'undefined') return
try {
if (!audioCtxRef.current) {
const AudioCtx = window.AudioContext || (window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext
const ctx = new AudioCtx()
audioCtxRef.current = ctx
const analyser = ctx.createAnalyser()
analyser.fftSize = 64
analyser.smoothingTimeConstant = 0.8
analyserRef.current = analyser
}
// One MediaElementAudioSourceNode per audio element — never recreate
if (!sourceRef.current) {
const source = audioCtxRef.current.createMediaElementSource(audio)
sourceRef.current = source
source.connect(analyserRef.current!)
analyserRef.current!.connect(audioCtxRef.current.destination)
}
} catch {}
}, [])
const resumeContext = useCallback(() => {
if (audioCtxRef.current?.state === 'suspended') {
audioCtxRef.current.resume()
}
}, [])
return { audioRef, analyserRef, audioCtxRef, initAudioViz, resumeContext }
}