UNPKG

infobip-rtc

Version:

Infobip RTC JavaScript SDK - Infobip WebRTC API Implementation

103 lines 3.65 kB
import { throttle } from "lodash-es"; const AUDIO_ENERGY_THRESHOLD = 0.12; const AUDIO_ENERGY_DELAY = 50; const EVENT_COOLDOWN_MILLIS = 1000; export class DefaultAudioStreamEnergyMonitor { constructor(onAudioEnergyDetected, logger, callId) { this.onAudioEnergyDetected = onAudioEnergyDetected; this.logger = logger; this.callId = callId; this.audioContext = new AudioContext(); this.analyser = this.audioContext.createAnalyser(); this.analyser.fftSize = 512; this.dataArray = new Float32Array(this.analyser.fftSize); this.throttledEmitAudioEnergyDetected = throttle(() => this.onAudioEnergyDetected(), EVENT_COOLDOWN_MILLIS, { leading: true, trailing: false }); } static create(onAudioEnergyDetected, logger, callId) { if (typeof window.AudioContext === 'undefined') { logger.warn("Could not initialize energy monitor. Web Audio API is not supported in this browser.", callId); return null; } return new DefaultAudioStreamEnergyMonitor(onAudioEnergyDetected, logger, callId); } start(stream) { const tracks = stream.getAudioTracks(); if (tracks.length < 1) { this.logger.warn("Could not start energy monitor. There are no audio tracks.", this.callId); return; } this.swapClonedTrack(tracks[0]); this.source = this.audioContext.createMediaStreamSource(new MediaStream([this.clonedTrack])); this.source.connect(this.analyser); this.startAudioEnergyDetection(); } stop() { this.removeClonedTrack(); this.clearAnalyserInterval(); } destroy() { if (this.analyserInterval) { clearInterval(this.analyserInterval); this.analyserInterval = null; } if (this.source) { this.source.disconnect(); this.source = null; } if (this.analyser) { this.analyser.disconnect(); this.analyser = null; } if (this.audioContext) { this.audioContext.close().catch(err => { this.logger.error(`Failed to close AudioContext: ${err}`, this.callId); }); this.audioContext = null; } this.removeClonedTrack(); this.dataArray = null; } swapClonedTrack(track) { this.removeClonedTrack(); this.addClonedTrack(track); } startAudioEnergyDetection() { this.clearAnalyserInterval(); this.startAnalyserInterval(); } clearAnalyserInterval() { if (this.analyserInterval) { clearInterval(this.analyserInterval); } } startAnalyserInterval() { this.analyserInterval = setInterval(() => { const energy = this.checkEnergy(); if (energy > AUDIO_ENERGY_THRESHOLD) { this.throttledEmitAudioEnergyDetected(); } }, AUDIO_ENERGY_DELAY); } checkEnergy() { this.analyser.getFloatTimeDomainData(this.dataArray); return this.rms(this.dataArray); } rms(dataArray) { let sum = 0; for (let i = 0; i < dataArray.length; i++) { sum += dataArray[i] * dataArray[i]; } return Math.sqrt(sum / dataArray.length); } removeClonedTrack() { if (this.clonedTrack) { this.clonedTrack.stop(); this.clonedTrack = null; } } addClonedTrack(track) { this.clonedTrack = track.clone(); this.clonedTrack.enabled = true; } } //# sourceMappingURL=AudioStreamEnergyMonitor.js.map