debug: add Web Audio console logs to diagnose waveform reactivity

This commit is contained in:
Michael committed 2026-05-04 00:48:08 +02:00
1 parent a89c08fd55
commit 0a91f6ec2c
1 file changed
+20 -12
+20 -12
View File
@@ -112,32 +112,34 @@ export function AudioProvider({ children }: { children: ReactNode }) {
// Web Audio analyser — uses the hidden analysis element (proxy URL → always CORS) // Web Audio analyser — uses the hidden analysis element (proxy URL → always CORS)
useEffect(() => { useEffect(() => {
if (!analysisRef.current || !currentEpisode) return; if (!analysisRef.current || !currentEpisode) return;
_gotRealDataLoggedRef.current = false;
let ctx: AudioContext | null = null; let ctx: AudioContext | null = null;
const setup = () => { const setup = () => {
try { try {
const AudioCtx = (window as any).AudioContext || (window as any).webkitAudioContext; const AudioCtx = (window as any).AudioContext || (window as any).webkitAudioContext;
if (!AudioCtx || !analysisRef.current) return; if (!AudioCtx || !analysisRef.current) { console.warn('[WA] setup: no AudioCtx or analysisRef'); return; }
ctx = new AudioCtx(); ctx = new AudioCtx();
console.log('[WA] ctx created, state:', ctx.state);
const source = ctx.createMediaElementSource(analysisRef.current); const source = ctx.createMediaElementSource(analysisRef.current);
const analyser = ctx.createAnalyser(); const analyser = ctx.createAnalyser();
analyser.fftSize = 256; analyser.fftSize = 256;
analyser.smoothingTimeConstant = 0.55; analyser.smoothingTimeConstant = 0.55;
const sink = ctx.createGain(); const sink = ctx.createGain();
sink.gain.value = 0; // silent output — but graph stays active so analyser gets data sink.gain.value = 0;
source.connect(analyser); source.connect(analyser);
analyser.connect(sink); analyser.connect(sink);
sink.connect(ctx.destination); sink.connect(ctx.destination);
webAudioRef.current = ctx; webAudioRef.current = ctx;
analyserRef.current = analyser; analyserRef.current = analyser;
dataArrayRef.current = new Uint8Array(analyser.frequencyBinCount); dataArrayRef.current = new Uint8Array(analyser.frequencyBinCount);
// If main audio already started playing before this effect ran, resume now console.log('[WA] graph ready. shouldResume:', shouldResumeCtxRef.current, 'mainPaused:', audioRef.current?.paused);
if (shouldResumeCtxRef.current || (audioRef.current && !audioRef.current.paused)) { if (shouldResumeCtxRef.current || (audioRef.current && !audioRef.current.paused)) {
ctx.resume(); ctx.resume().then(() => console.log('[WA] ctx resumed from setup'));
analysisRef.current?.play().catch(() => {}); analysisRef.current?.play().catch(e => console.warn('[WA] analysis play failed (setup):', e));
} }
} catch { } catch (e) {
// Proxy unavailable — visualizer falls back to simulation console.error('[WA] setup failed:', e);
} }
}; };
setup(); setup();
@@ -150,9 +152,14 @@ export function AudioProvider({ children }: { children: ReactNode }) {
}; };
}, [currentEpisode?._id]); }, [currentEpisode?._id]);
const _gotRealDataLoggedRef = useRef(false);
const getFrequencyData = () => { const getFrequencyData = () => {
if (!analyserRef.current || !dataArrayRef.current) return null; if (!analyserRef.current || !dataArrayRef.current) return null;
analyserRef.current.getByteFrequencyData(dataArrayRef.current as Uint8Array<ArrayBuffer>); analyserRef.current.getByteFrequencyData(dataArrayRef.current as Uint8Array<ArrayBuffer>);
if (!_gotRealDataLoggedRef.current) {
const sum = dataArrayRef.current.reduce((a, b) => a + b, 0);
if (sum > 0) { console.log('[WA] first real frequency data, sum:', sum); _gotRealDataLoggedRef.current = true; }
}
return dataArrayRef.current; return dataArrayRef.current;
}; };
@@ -168,11 +175,14 @@ export function AudioProvider({ children }: { children: ReactNode }) {
const handleMainPlay = () => { const handleMainPlay = () => {
setIsPlaying(true); setIsPlaying(true);
shouldResumeCtxRef.current = true; shouldResumeCtxRef.current = true;
if (webAudioRef.current?.state === 'suspended') webAudioRef.current.resume(); console.log('[WA] handleMainPlay, ctx state:', webAudioRef.current?.state ?? 'null');
if (webAudioRef.current?.state === 'suspended') {
webAudioRef.current.resume().then(() => console.log('[WA] ctx resumed from handleMainPlay'));
}
const el = analysisRef.current; const el = analysisRef.current;
if (el) { if (el) {
syncAnalysis(audioRef.current?.currentTime); syncAnalysis(audioRef.current?.currentTime);
el.play().catch(() => {}); el.play().catch(e => console.warn('[WA] analysis play failed (handleMainPlay):', e));
} }
}; };
@@ -269,14 +279,12 @@ export function AudioProvider({ children }: { children: ReactNode }) {
onError={() => setError("Impossible de charger ce fichier audio. Le lien est peut-être expiré ou protégé.")} onError={() => setError("Impossible de charger ce fichier audio. Le lien est peut-être expiré ou protégé.")}
autoPlay autoPlay
/> />
{/* Analysis audio: proxy URL, muted, Web Audio source only */} {/* Analysis audio: proxy URL, Web Audio source only (GainNode silences output) */}
<audio <audio
key={`analysis-${currentEpisode._id}`} key={`analysis-${currentEpisode._id}`}
ref={analysisRef} ref={analysisRef}
src={proxyUrl} src={proxyUrl}
crossOrigin="anonymous" crossOrigin="anonymous"
muted
autoPlay
preload="auto" preload="auto"
onError={() => { /* proxy fail: visualizer uses simulation */ }} onError={() => { /* proxy fail: visualizer uses simulation */ }}
/> />