Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to convert class to hook style components #34

Open
wchorski opened this issue Mar 4, 2023 · 0 comments
Open

Trying to convert class to hook style components #34

wchorski opened this issue Mar 4, 2023 · 0 comments

Comments

@wchorski
Copy link

wchorski commented Mar 4, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant