Files
skills/docs/ui/react/react-audio-fingerprint/src/hooks/use-audio-fingerprint/use-audio-fingerprint.md
2026-05-29 08:20:56 +01:00

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

  • source can be undefined/null to mean "do nothing" — useful while waiting for an upload to decode.
  • state cycles 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 to LocalBackend.
  • Wraps non-ReactAudioFingerprintError rejections in FINGERPRINT_FAILED.
  • Suppresses ABORTED errors — 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.