I am unable to play the audio stream recieving from socket. I am capturing audio and and emitting the stream as a Blob.
"use client";
import socket from "@/socket-io";
export const CaptureAudioStream = (
roomId: string,
isMuted: boolean,
setIsMuted: (isMuted: boolean) => void
) => {
let mediaRecorder: MediaRecorder | null = null;
let audioChunks: Blob[] = [];
const startCapture = async () => {
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: false,
});
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.addEventListener("dataavailable", (event) => {
if (!isMuted) {
audioChunks.push(event.data);
}
});
mediaRecorder.addEventListener("stop", () => {
if (roomId && !isMuted && audioChunks.length > 0) {
const audioBlob = new Blob(audioChunks, { type: "audio/webm" });
const audioUrl = URL.createObjectURL(audioBlob);
if (roomId && !isMuted) {
socket.emit("audio_stream", {
room_id: roomId,
audio_data: audioUrl,
});
}
}
audioChunks = [];
startRecording();
});
startRecording();
} catch (error) {
console.error("Error starting audio capture:", error);
}
};
const startRecording = () => {
if (mediaRecorder && mediaRecorder.state === "inactive") {
mediaRecorder.start();
setTimeout(() => {
if (mediaRecorder && mediaRecorder.state === "recording") {
mediaRecorder.stop();
}
}, 1000);
}
};
const stopCapture = () => {
if (mediaRecorder) {
mediaRecorder.stop();
mediaRecorder = null;
}
};
startCapture();
return {
stopCapture,
};
};
I start initiate this function when I connect to socket
const audioStreamRef = useRef<{
stopCapture: () => void;
} | null>(null);
const startAudioCapture = useCallback(() => {
if (audioStreamRef.current) {
audioStreamRef.current.stopCapture();
}
audioStreamRef.current = CaptureAudioStream(room, isMuted, setIsMuted);
}, [room, isMuted, setIsMuted]);
useEffect(() => {
const onConnect = () => {
setIsConnected(true);
startAudioCapture();
};
const onDisconnect = () => {
setIsConnected(false);
};
if (socket.connected) {
onConnect();
}
socket.on("connect", onConnect);
socket.on("disconnect", onDisconnect);
return () => {
socket.off("connect", onConnect);
socket.off("disconnect", onDisconnect);
};
}, [setIsConnected, startAudioCapture, isMuted, room]);
Then at event listener of audio_stream
, I am playing audio
"use client";
import socket from "@/socket-io";
import { useSocketState } from "@/store/useSocketState";
import { useEffect, useRef } from "react";
export const useAudioReceiver = () => {
const { room } = useSocketState();
const audioRef = useRef<HTMLAudioElement | null>(null);
useEffect(() => {
if (!audioRef.current) {
audioRef.current = new Audio();
}
const handleAudioStream = (data: {
room_id: string;
audio_data: string;
}) => {
if (audioRef.current) {
audioRef.current = new Audio(data.audio_data);
audioRef.current.play().catch((error) => {
console.error("Error playing audio:", error);
});
}
};
socket.on("audio_stream", handleAudioStream);
// Cleanup on component unmount
return () => {
socket.off("audio_stream", handleAudioStream);
if (audioRef.current) {
audioRef.current.pause();
audioRef.current = null;
}
};
}, [room]);
};
audio is emitting correctly as blob like this:
captured audio blob is correct because I have tested it by capturing and then playing on my side, my own voice started coming back to me but when I emit it and start recieving it in useAudioReciever
hook, it do not play
I have also tried AudioContext method and also transmitted as base64 encoded but nothing is working
I would really appreciate some help on what I am doing wrong. Thanks!