You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

79 lines
2.2 KiB

import { useEffect, useRef, useState } from "react";
export default function VoiceAnalysis(){
const [volume, setVolume] = useState(0);
const refVolumeInterval=useRef();
const refAnalyser=useRef();
const refVolumes=useRef();
async function setup(){
try{
const audioStream = await navigator.mediaDevices.getUserMedia({
audio: {
echoCancellation: true
},
video: false
});
audioStream.getAudioTracks().forEach(track => {
console.log(`Track ID: ${track.id}, Label: ${track.label}`);
});
const audioContext = new AudioContext();
const source = audioContext.createMediaStreamSource(audioStream);
const analyser = audioContext.createAnalyser();
analyser.fftSize = 512;
analyser.minDecibels = -127;
analyser.maxDecibels = 0;
analyser.smoothingTimeConstant = 0.4;
source.connect(analyser);
const volumes = new Uint8Array(analyser.frequencyBinCount);
refAnalyser.current = analyser;
refVolumes.current = volumes;
}catch(e){
console.error('error start audio stream',e);
}
}
const volumeCallback = () => {
const volumes = refVolumes.current;
refAnalyser.current.getByteFrequencyData(volumes);
let volumeSum = 0;
for(const volume of volumes)
volumeSum += volume;
const averageVolume = volumeSum / volumes.length;
// console.log(`Average Volume: ${averageVolume}`);
setVolume(averageVolume);
};
useEffect(()=>{
setup().then(() => {
refVolumeInterval.current = setInterval(() => {
volumeCallback();
}, 100); // Adjust the interval as needed
});
return () => {
clearInterval(refVolumeInterval.current);
};
},[]);
return (
<div className="voice-analysis border flex flex-col justify-end">
{/* <p>Volume: {volume}</p> */}
<div className="w-full bg-amber-600" style={{ height: `${volume/127*100}%` }}></div>
</div>
);
}