react-web-audio
react-web-audio copied to clipboard
Trying to convert class to hook style components
I've taken a wack at trying to convert AudioAnalyser.js
to a Hook style Component. I got stuck on one error
The Code
import React, { Component, useRef, useEffect, useState } from 'react';
import AudioVisualiser from './AudioVisualiser';
export const AudioAnalyser = ( { audio } ) => {
// constructor(props) {
// super(props);
// this.state = { audioData: new Uint8Array(0) };
// this.tick = this.tick.bind(this);
// }
const isMounted = useRef()
const [audioData, setAudioData] = useState(new Uint8Array(0))
// const [audioContext, setaudioContext] = useState()
// const [analyser, setAnalyser] = useState()
// usest
const audioContext = useRef(null)
const analyser = useRef(new Uint8Array(0))
const dataArray = useRef(null)
const source = useRef(null)
let rafId = useRef(null)
useEffect(() => {
if(!isMounted.current){
handleMount() // mount logic
isMounted.current = true
} else {
if(!analyser.current) return
tick() // update logic
}
// return () => {
// cancelAnimationFrame(rafId.current);
// analyser.current.disconnect();
// source.current.disconnect();
// }
})
async function handleMount() {
try {
// this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
const newAudCtx = new (window.AudioContext || window.webkitAudioContext)()
audioContext.current = newAudCtx
const newAnlyzer = newAudCtx.createAnalyser()
analyser.current = newAnlyzer
const newDtArr = new Uint8Array(newAnlyzer.current.frequencyBinCount)
dataArray.current = newDtArr
const newSrc = audioContext.current.createMediaStreamSource(audio);
source.current = newSrc
newSrc.connect(newAnlyzer)
const newRafId = requestAnimationFrame(tick())
rafId.current = newRafId
} catch (error) {
console.warn('audio analyser mount fail');
}
}
function tick() {
if(!analyser.current) return
analyser.current.getByteTimeDomainData(dataArray.current);
// setState({ audioData: this.dataArray });
setAudioData(dataArray.current)
rafId.current = requestAnimationFrame(tick());
}
return <AudioVisualiser audioData={audioData} />
}
export default AudioAnalyser;
The Error
[!error] TypeError: Failed to execute 'getByteTimeDomainData' on 'AnalyserNode': parameter 1 is not of type 'Uint8Array'.
function tick() {
67 | if(!analyser.current) return
> 68 | analyser.current.getByteTimeDomainData(dataArray.current);
| ^
69 | // setState({ audioData: this.dataArray });
70 | setAudioData(dataArray.current)
71 | rafId.current = requestAnimationFrame(tick());
The Question
can't tell if this is an initialization issue or a order of operations issue. Any guidance on how to correct is greatly appreciated.