2.9 KiB
useAudioFingerprint — React hook for the fingerprint pipeline
(no submodules)
Purpose
useAudioFingerprint(source, options?) drives a FingerprintBackend off a
React-managed AudioDocument and returns the live state, the resulting
fingerprint when done, a 0..1 progress fraction, and any error encountered.
The hook centralises the abort-on-unmount and progress wiring so component
authors do not have to repeat that work across uploaders, visualisers, and
match displays.
Features
sourcecan beundefined/nullto mean "do nothing" — useful while waiting for an upload to decode.statecycles through'idle'→'fingerprinting'→'done'(or'error'); a fresh source resets the cycle.- Abort-on-unmount and abort-on-source-change via internal
AbortController. - Backend swap via
options.backend; defaults toLocalBackend. - Wraps non-
ReactAudioFingerprintErrorrejections inFINGERPRINT_FAILED. - Suppresses
ABORTEDerrors — they settle back to'idle'.
Usage: Basic Example
import { useAudioFingerprint } from "@suaveplan/react-audio-fingerprint/hooks/use-audio-fingerprint";
function FingerprintPreview({ doc }: { doc: AudioDocument }) {
const { state, fingerprint, progress } = useAudioFingerprint(doc);
if (state === "fingerprinting") return <progress value={progress} />;
if (state === "done") return <span>{fingerprint?.length} pairs</span>;
return null;
}
Usage: Advanced Example
Inject a custom backend (e.g. the optional Python backend) and surface errors:
import { useAudioFingerprint } from "@suaveplan/react-audio-fingerprint/hooks/use-audio-fingerprint";
function Surface({ doc, backend }: { doc: AudioDocument; backend: FingerprintBackend }) {
const { state, error, fingerprint } = useAudioFingerprint(doc, { backend });
if (state === "error") return <Banner code={error?.code}>{error?.message}</Banner>;
if (state === "done") return <Result fp={fingerprint!} />;
return <Spinner />;
}
API Reference
useAudioFingerprint(source, options?): UseAudioFingerprintResult.source: AudioDocument | undefined | null.options?: { backend?: FingerprintBackend }.UseAudioFingerprintResult = { state, fingerprint, progress, error }.state: 'idle' | 'fingerprinting' | 'done' | 'error'.
Implementation Notes
The hook uses useMemo to stabilise the default LocalBackend so changing
unrelated props does not retrigger the effect. The alive flag guarding all
post-await setState calls is the canonical React pattern for protecting
against the lifecycle race between an async fetch completing and a fast
unmount. Aborts settle to 'idle' (not 'error') so user-driven cancels do
not produce a banner. Non-Suaveplan errors get wrapped so consumers can always
discriminate via error.code without an instanceof chain.