useAudio
Controls an audio element while exposing playback, loading, timing, volume, rate, loop, and error state.
About
useAudio connects a callback ref to an <audio> element and mirrors its media events into React state. Use it when an application needs custom audio controls or media-event callbacks in addition to the element's native controls.
Example
import { useAudio } from "rooks";
export default function AudioPlayer() {
const [audioRef, audio, controls] = useAudio(
{ preload: "metadata" },
{ onError: (message) => console.error(message) }
);
return (
<section>
<audio ref={audioRef} src="/example-audio.mp3" controls />
<p aria-live="polite">
{audio.hasError
? audio.error
: `${audio.isPlaying ? "Playing" : "Paused"} at ${Math.round(audio.currentTime)} seconds`}
</p>
<button type="button" onClick={controls.togglePlay}>
{audio.isPlaying ? "Pause" : "Play"}
</button>
<button type="button" onClick={controls.toggleMute}>
{audio.isMuted ? "Unmute" : "Mute"}
</button>
<label>
Volume
<input
type="range"
min="0"
max="1"
step="0.1"
value={audio.volume}
onChange={(event) =>
controls.setVolume(event.currentTarget.valueAsNumber)
}
/>
</label>
</section>
);
}The /example-audio.mp3 path represents an audio asset supplied by the application.
Parameters
Both arguments are optional objects.
| Option | Type | Default | Behavior |
|---|---|---|---|
autoPlay | boolean | false | Sets the element's autoplay property after the ref attaches. |
isMuted | boolean | false | Initial muted state and element property. |
volume | number | 1 | Initial element volume; supply 0..1 because this assignment is not clamped. Later controls clamp to that range. |
playbackRate | number | 1 | Initial browser playback rate; this assignment is not clamped. Later controls clamp to 0.25..4. |
loop | boolean | false | Initial loop state. |
preload | "none" | "metadata" | "auto" | "metadata" | Sets the element's preload hint. |
The callbacks object accepts onPlay, onPause, onEnded, onMute, onUnmute, onLoadedMetadata, onLoadStart, onCanPlay, and onWaiting. It also accepts onTimeUpdate(currentTime), onDurationChange(duration), onVolumeChange(volume), onRateChange(rate), and onError(message). Callback identities stay fresh without requiring media listeners to be recreated.
Return value
The hook returns [audioRef, state, controls].
audioRefis a callback ref for anHTMLAudioElement.statecontainsisPlaying,isMuted,volume,currentTime,duration,playbackRate,isLoading,isBuffering,loop,hasError, and optionalerror.controlscontainsplay,pause,togglePlay,mute,unmute,toggleMute,setVolume,setCurrentTime,setPlaybackRate,seek,fastForward,rewind, andsetLoop.
All controls return void. fastForward() and rewind() default to ten seconds. Seeking is clamped between zero and the known duration, so seeking before metadata supplies a duration remains at zero.
Behavior and lifecycle
After the ref attaches, the hook applies the initial element properties and subscribes to the relevant media events. It removes every listener when the element changes or the component unmounts. Native media events are the source of truth for playing, timing, buffering, volume, rate, and error state.
Controls do nothing until an element has attached. play() handles a rejected HTMLMediaElement.play() promise by setting hasError, clearing isPlaying, and calling onError. Media-element error events use the browser error code and message. Other control assignments rely on normal platform behavior; they do not throw errors through the hook.
Compatibility and accessibility
The initial render is server-safe because DOM work begins only after the ref attaches. Autoplay and scripted playback may still be rejected by browser user-activation policies. The hook does not load an audio source or request media permissions.
Keep native controls when possible, give custom controls accessible names, expose failures with an appropriate live region, and provide a transcript for spoken content. See SSR and browser APIs.
Related
- useVideo provides the smaller video-specific state and control tuple.
- useMediaRecorder records a supplied media stream.