Files
mirotalk/public/js/detectSpeaking.js
T
2023-09-07 11:55:07 +02:00

74 lines
2.4 KiB
JavaScript

'use strict';
const bars = document.querySelectorAll('.volume-bar');
let scriptProcessor = null;
/**
* Check if audio context is supported
* @returns {boolean}
*/
function isAudioContextSupported() {
return !!(window.AudioContext || window.webkitAudioContext);
}
/**
* Start to handle microphone volume indicator
* @param {MediaStream} stream Media stream audio
*/
async function getMicrophoneVolumeIndicator(stream) {
if (isAudioContextSupported() && hasAudioTrack(stream)) {
stopMicrophoneProcessing();
console.log('Start microphone volume indicator for audio track', stream.getAudioTracks()[0]);
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const microphone = audioContext.createMediaStreamSource(stream);
scriptProcessor = audioContext.createScriptProcessor(1024, 1, 1);
scriptProcessor.onaudioprocess = function (event) {
const inputBuffer = event.inputBuffer.getChannelData(0);
let sum = 0;
for (let i = 0; i < inputBuffer.length; i++) {
sum += inputBuffer[i] * inputBuffer[i];
}
const rms = Math.sqrt(sum / inputBuffer.length);
const volume = Math.max(0, Math.min(1, rms * 10));
const finalVolume = Math.round(volume * 100);
if (myAudioStatus && finalVolume > 10) {
const config = {
type: 'micVolume',
peer_id: myPeerId,
volume: finalVolume,
};
handleMyVolume(config);
sendToDataChannel(config);
}
updateVolumeIndicator(volume);
};
microphone.connect(scriptProcessor);
scriptProcessor.connect(audioContext.destination);
} else {
console.warn('Microphone volume indicator not supported for this browser');
}
}
/**
* Stop microphone processing
*/
function stopMicrophoneProcessing() {
console.log('Stop microphone volume indicator');
if (scriptProcessor) {
scriptProcessor.disconnect();
scriptProcessor = null;
}
}
/**
* Update volume indicator
* @param {number} volume
*/
function updateVolumeIndicator(volume) {
const activeBars = Math.ceil(volume * bars.length);
bars.forEach((bar, index) => {
bar.classList.toggle('active', index < activeBars);
});
}