async function startListening() {
stream = await navigator.mediaDevices.getUserMedia({
audio: {
channelCount: 1,
echoCancellation: true,
autoGainControl: true,
noiseSuppression: true,
},
});
mediaRecorder = new MediaRecorder(stream);
micStream = audioMotion.audioCtx.createMediaStreamSource(stream);
audioMotion.connectInput(micStream);
mediaRecorder.ondataavailable = async (event) => {
const base64Data = await blobToBase64(event.data);
socket.send(JSON.stringify({ type: 'audioIn', data: base64Data }));
// console.log('Send voice data:', base64Data);
};
async function blobToBase64(blob) {
const reader = new FileReader();
reader.readAsDataURL(blob);
return new Promise((resolve) => {
reader.onloadend = () => resolve(reader.result.split(',')[1]);
});
}
mediaRecorder.start(1000);
}
If I am using the echoCancellation: true
it is working fine on PC but when using it on mobile devices the when volume buttons are clicked the call volume is displayed and the volume cannot be controlled unless we manually adjust the media volume. If I turn it off, the playback from the device is taken as input.
here is my Audio Playback method.
async function playAudioResponse(audioBase64) {
try {
if (!audioBase64 || audioBase64.trim() === '') {
// console.error('Empty or invalid audio data received.');
return;
}
const binaryString = atob(audioBase64);
const len = binaryString.length;
const buffer = new Float32Array(len); // 8-bit
for (let i = 0; i < len; i++) {
buffer[i] = decodeSample(binaryString.charCodeAt(i)) / 32768;
}
// console.log('buffer', buffer)
audioWriter(buffer).then((data) => {
audioMotion.connectInput(micStream);
audioMotion.volume = 1;
}).catch((error) => {
// console.error('Error writing audio data:', error);
});
} catch (error) {
console.error('Error playing audio:', error);
}
}
And in the above play audio response, i am using a WebAudioWrite
which uses AudioWorkletNode
Thanks in advance.