fix(player): WaveformPlayer click did nothing — media element never got a src (#379)

With an external `media`, wavesurfer's `url` option only fetches for peak
decoding and never assigns the element's src — so the waveform drew but
play() had nothing to play. Set src on the in-DOM <audio> via JSX (same
pattern as WaveformTimeline) and stop passing `url`. Also surface
playPause() rejections instead of swallowing them.

Co-authored-by: mergetest <test@local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Palash Debnath
2026-06-12 16:17:50 +05:30
committed by GitHub
co-authored by mergetest Claude Fable 5
parent 35de7d03b4
commit 171febfd59
+11 -3
View File
@@ -94,8 +94,11 @@ export default function WaveformPlayer({
// create a detached one: Tauri's WebKit decodes (peaks render) but
// won't actually output sound for detached/blob-backed media — the
// same reason WaveformTimeline passes its <video> element.
// NOTE: the element's `src` is set in JSX, NOT via the `url` option —
// with an external `media`, wavesurfer only fetches `url` for peaks
// and never assigns it to the element, leaving play() with nothing
// to play (waveform drew, click did nothing).
media: mediaRef.current,
url: resolvedUrl,
});
} catch (initErr) {
console.warn('WaveformPlayer: WaveSurfer init failed, native fallback:', initErr);
@@ -146,7 +149,12 @@ export default function WaveformPlayer({
};
}, [resolvedUrl, failed, height, source, onEnded]);
const togglePlay = () => { try { wsRef.current?.playPause(); } catch { /* noop */ } };
const togglePlay = () => {
// playPause is async — a swallowed rejection here is exactly how the
// "click does nothing" bug hid; log it so playback failures are visible.
Promise.resolve(wsRef.current?.playPause())
.catch((e) => console.warn('WaveformPlayer: play failed:', e));
};
if (!resolvedUrl) return null;
@@ -180,7 +188,7 @@ export default function WaveformPlayer({
return (
<div className={`wf-player ${compact ? 'wf-player--compact' : ''} ${className}`}>
{/* Hidden but DOM-attached playback element (see WaveSurfer `media`). */}
<audio ref={mediaRef} preload="metadata" style={{ display: 'none' }} />
<audio ref={mediaRef} src={resolvedUrl} preload="metadata" style={{ display: 'none' }} />
<button
type="button"
className="wf-player__btn"