parent
ba2f167e91
commit
a1f20d0121
7 changed files with 176 additions and 57 deletions
@ -0,0 +1,79 @@ |
||||
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> |
||||
); |
||||
} |
||||
Loading…
Reference in new issue