Route-safe global audio manager and hook for React apps.
npm i react-global-audioPeer dependency:
npm i reactimport { useGlobalAudio } from 'react-global-audio';
export function Player() {
const { state, controls } = useGlobalAudio({
src: '/audio/track.mp3',
rememberProgress: true,
storage: 'localStorage',
});
return (
<div>
<button onClick={() => controls.play()}>Play</button>
<button onClick={controls.pause}>Pause</button>
<button onClick={controls.stop}>Stop</button>
<div>
{Math.floor(state.currentTime)} / {Math.floor(state.duration)}
</div>
<input
type='range'
min={0}
max={state.duration || 0}
value={state.currentTime}
onChange={(e) => controls.seek(Number(e.target.value))}
/>
</div>
);
}import { audioManager } from 'react-global-audio';
audioManager.configure({ rememberProgress: true, storage: 'localStorage' });
await audioManager.play('/audio/track.mp3');
audioManager.pause();
// 테스트/정리 시 전역 오디오 인스턴스를 해제
audioManager.dispose();Dispose the global audio instance (useful for tests or cleanup):
audioManager.dispose();Subscribe to state:
const unsubscribe = audioManager.subscribe((next) => {
console.log(next.currentTime);
});
unsubscribe();Subscribe to audio events:
const off = audioManager.subscribeEvents({
onPlay: () => console.log('play'),
onPause: () => console.log('pause'),
onEnded: () => console.log('ended'),
onTimeUpdate: (time) => console.log(time),
onError: (err) => console.error(err),
});
off();useGlobalAudio(options) and audioManager.configure(options) accept:
src?: string | nullautoPlay?: booleanrememberProgress?: boolean(default:true)storage?: 'localStorage' | 'sessionStorage' | false(default:'localStorage')throttleMs?: number(default:2000)keyBuilder?: (src: string) => string
Available from the hook (controls) and audioManager.getControls():
play(src?)pause()stop()seek(time)setVolume(volume)(0 to 1)setPlaybackRate(rate)(0.5 to 2)setSource(src)
- Progress is saved in whole seconds.
- A single shared
HTMLAudioElementinstance is used. - Set
storage: falseto disable persistence. - In SSR, audio actions are no-ops and the snapshot stays at the default state.