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

Feature request: Audio Visualizer #89

Open
ZohebMOPO opened this issue Jun 10, 2021 · 13 comments
Open

Feature request: Audio Visualizer #89

ZohebMOPO opened this issue Jun 10, 2021 · 13 comments
Assignees
Labels
enhancement New feature or request Intermediate

Comments

@ZohebMOPO
Copy link
Collaborator

Is your feature request related to a problem? Please describe.

At the time of joining the client should be able to know that how loud his/her voice is. For that Meet has a voice visualizer.
image
In the left corner, there is the voice visualizer.

Describe the solution you'd like

There are two ways of doing it which I figured out. 1) to collect the decibel of the client in the backend and according to that, we will send a response to the client via visualizer. For that, we can use a package called decibel-meter.
2) A package that does it all like getting the sound and sending the amplitude on its own. The package is called p5.js.

Describe alternatives you've considered

Well, after googling many times, I found this video which can make you clear what I am trying to say.

@welcome
Copy link

welcome bot commented Jun 10, 2021

Hello there!👋 Welcome to the project!🚀⚡

Thank you and congrats🎉for opening your very first issue in this project. Please adhere to our Contributing Guidelines.🙌 You may submit a PR if you like, make sure to follow our Pull Request Template. If you want to report a bug🐞 please follow our Issue Template. Also make sure you include steps to reproduce it and be patient while we get back to you.😄

Feel free to join our Discord Community.💖 We have different channels for active discussions.✨ Hope you have a great time there!😄

@ZohebMOPO ZohebMOPO added enhancement New feature or request Intermediate labels Jun 10, 2021
@ZohebMOPO ZohebMOPO changed the title Feature request Feature request: Audio Visualizer Jun 10, 2021
@ZohebMOPO
Copy link
Collaborator Author

ezgif com-gif-maker

@sansyrox @shivaylamba @raghavdhingra @midopooler

The Audio visualizer thing is working rn. This one is in a separate environment. I just wanna ask that in which part of the video call we should add the visualizer?

@sansyrox
Copy link
Member

@ZohebMOPO , on the screen where you select the username

@sansyrox
Copy link
Member

Also, once you integrate that, try using hooks instead of class components. Let us know if you face any issues.

@ZohebMOPO
Copy link
Collaborator Author

Yeah sure. I am not in home rn. Will let you know about that :)

@ZohebMOPO
Copy link
Collaborator Author

I will not be at my house for 2days because of the festival. Like I have changed them to functional components but haven't used the hooks properly. Sorry for that :(

@sansyrox
Copy link
Member

No worries @ZohebMOPO . You can take your time.

@ZohebMOPO
Copy link
Collaborator Author

ZohebMOPO commented Jul 22, 2021

import AudioVisualiser from "./Visualizer";

class AudioAnalyser extends Component {
  constructor(props) {
    super(props);
    this.state = { audioData: new Uint8Array(0) };
    this.tick = this.tick.bind(this);
  }

  componentDidMount() {
    this.audioContext = new (window.AudioContext ||
      window.webkitAudioContext)();
    this.analyser = this.audioContext.createAnalyser();
    this.dataArray = new Uint8Array(this.analyser.frequencyBinCount);
    this.source = this.audioContext.createMediaStreamSource(this.props.audio);
    this.source.connect(this.analyser);
    this.rafId = requestAnimationFrame(this.tick);
  }

  tick() {
    this.analyser.getByteTimeDomainData(this.dataArray);
    this.setState({ audioData: this.dataArray });
    this.rafId = requestAnimationFrame(this.tick);
  }

  componentWillUnmount() {
    cancelAnimationFrame(this.rafId);
    this.analyser.disconnect();
    this.source.disconnect();
  }

  render() {
    return <AudioVisualiser audioData={this.state.audioData} />;
  }
}

export default AudioAnalyser;


This was the class component, I am literally confused on how to use the DOM updates in useEffect.

Functional component..... 

import React, { useState, useEffect } from "react";
import Visualizerf from "./AudioAnalyserf";
function AudioAnalyserf({ audio }) {
  const [audioData, setaudioData] = useState(new Uint8Array(0));

  const audioContext = new window.AudioContext();
  const analyser = audioContext.createAnalyser();
  const dataArray = new Uint8Array(analyser.frequencyBinCount);
  const source = audioContext.createMediaElementSource(audio);
  source.connect(analyser);
  const rafId = requestAnimationFrame(tick);

  const tick = () => {
    analyser.getByteTimeDomainData(dataArray);
    setaudioData(dataArray);
    rafId = requestAnimationFrame(this.tick);
  };

  const unMount = () => {
    cancelAnimationFrame(this.rafId);
    analyser.disconnect();
    source.disconnect();
  };

  useEffect(() => {
    // Idk what I am doing :((((
  }, []);
  return (
    <div>
      <Visualizerf audioData={audioData} />
    </div>
  );
}

export default AudioAnalyserf;

``

@ZohebMOPO
Copy link
Collaborator Author

How do I make updates using useEffect @raghavdhingra

@raghavdhingra
Copy link
Member

raghavdhingra commented Jul 22, 2021

useEffect is a life cycle hook. It has a dependency list, over which the function call itself when ever any of the value from that list changes.
For e.g.
const callBackFunction = () => { // do some changes }
const dependencyArray = [value, object, list, ...]
useEffect(callBackFunction, dependencyArray);
So, if any of the values changes within the list via state change, or any hook change, the callback function will call itself. Hence you can define the callback function as per the way you want

@ZohebMOPO
Copy link
Collaborator Author

ZohebMOPO commented Jul 23, 2021

Class component:-


class AudioAnalyser extends Component {
  constructor(props) {
    super(props);
    this.state = { audioData: new Uint8Array(0) };
    this.tick = this.tick.bind(this);
  }

  componentDidMount() {
    this.audioContext = new (window.AudioContext ||
      window.webkitAudioContext)();
    this.analyser = this.audioContext.createAnalyser();
    this.dataArray = new Uint8Array(this.analyser.frequencyBinCount);
    this.source = this.audioContext.createMediaStreamSource(this.props.audio);
    this.source.connect(this.analyser);
    this.rafId = requestAnimationFrame(this.tick);
  }

  tick() {
    this.analyser.getByteTimeDomainData(this.dataArray);
    this.setState({ audioData: this.dataArray });
    this.rafId = requestAnimationFrame(this.tick);
  }

  componentWillUnmount() {
    cancelAnimationFrame(this.rafId);
    this.analyser.disconnect();
    this.source.disconnect();
  }

  render() {
    return <AudioVisualiser audioData={this.state.audioData} />;
  }
}

export default AudioAnalyser;
import Visualizerf from "./AudioAnalyserf";
function AudioAnalyserf({ audio }) {
  const [audioData, setaudioData] = useState(new Uint8Array(0));

  const audioContext = new window.AudioContext();
  const analyser = audioContext.createAnalyser();
  const dataArray = new Uint8Array(analyser.frequencyBinCount);
  const source = audioContext.createMediaElementSource(audio);
  source.connect(analyser);
  const rafId = requestAnimationFrame(tick);

  const tick = () => {
    analyser.getByteTimeDomainData(dataArray);
    setaudioData(dataArray);
    rafId = requestAnimationFrame(tick);
  };

  const unMount = () => {
    cancelAnimationFrame(rafId);
    analyser.disconnect();
    source.disconnect();
  };

  useEffect(() => {
    return unMount;
  }, []);

  return (
    <div>
      <Visualizerf audioData={audioData} />
    </div>
  );
}

export default AudioAnalyserf;```

so it will look like this?

@ZohebMOPO
Copy link
Collaborator Author

ZohebMOPO commented Jul 23, 2021

@raghavdhingra Sorry for the late reply. Schools are going offline and I am kinda stuck in that thing cuz I didn't do anything the whole summer haha. Anyways, will the functional component look like this?

@ZohebMOPO
Copy link
Collaborator Author

I am hella confused about converting this to functional components. I am used to class components cuz my first programming lang was Java. I am not sure when I will come out of this learning curve :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Intermediate
Projects
None yet
Development

No branches or pull requests

3 participants