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