fix: adjust webrtc javascript to initiate offer and receive media

This commit is contained in:
gari 2025-04-13 10:47:27 +02:00
parent 26624ec52d
commit 8558241aa5

View file

@ -1,10 +1,9 @@
const videoElement = document.getElementById('video'); const videoElement = document.getElementById('video');
let localConnection; let peerConnection; // Renamed for clarity
let wsConnection; let wsConnection;
let mediaConstraints = { video: true, audio: true }; // Removed mediaConstraints and iceCandidates (not needed here)
let iceCandidates = [];
const wsUrl = "ws://localhost:8080/api/v1/preview/5a59a94f-264a-4d24-9e57-8a9be0ecbdbd/KALANI-3.LOCAL%20%28OBS%29"; // Replace with your WebSocket URL const wsUrl = "ws://localhost:8080/api/v1/preview/5a59a94f-264a-4d24-9e57-8a9be0ecbdbd/KALANI-3.LOCAL%20%28OBS%29"; // Replace with your WebSocket URL if necessary
const peerConnectionConfig = { const peerConnectionConfig = {
iceServers: [{ urls: "stun:stun.l.google.com:19302" }] iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
}; };
@ -20,76 +19,92 @@ function initWebSocket() {
wsConnection.onmessage = async (message) => { wsConnection.onmessage = async (message) => {
const signal = JSON.parse(message.data); const signal = JSON.parse(message.data);
console.log("Received signal:", signal); // Add logging
if (signal.type === 'offer') { // The browser initiates with an offer, so it expects an answer or ICE candidates.
handleOffer(signal); // It should not receive an 'offer'.
} else if (signal.type === 'answer') { if (signal.type === 'answer') {
handleAnswer(signal); handleAnswer(signal);
} else if (signal.type === 'ice') { } else if (signal.type === 'ice') {
handleIceCandidate(signal); handleIceCandidate(signal);
} else {
console.warn("Received unexpected signal type:", signal.type);
} }
}; };
wsConnection.onerror = (error) => {
console.error('WebSocket Error:', error);
};
wsConnection.onclose = (event) => {
console.log('WebSocket closed:', event.code, event.reason);
};
} }
// Create an SDP offer // Create an SDP offer to receive media
async function createOffer() { async function createOffer() {
localConnection = new RTCPeerConnection(peerConnectionConfig); peerConnection = new RTCPeerConnection(peerConnectionConfig);
localConnection.onicecandidate = handleIceCandidateEvent;
localConnection.ontrack = (event) => { // Set up event handlers
peerConnection.onicecandidate = handleIceCandidateEvent;
peerConnection.ontrack = (event) => {
console.log("Track received:", event.track, "Stream:", event.streams[0]);
if (videoElement.srcObject !== event.streams[0]) {
videoElement.srcObject = event.streams[0]; videoElement.srcObject = event.streams[0];
console.log("Assigned stream to video element");
}
};
peerConnection.oniceconnectionstatechange = () => {
console.log("ICE connection state:", peerConnection.iceConnectionState);
};
peerConnection.onconnectionstatechange = () => {
console.log("Peer connection state:", peerConnection.connectionState);
}; };
const stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
stream.getTracks().forEach(track => localConnection.addTrack(track, stream));
const offer = await localConnection.createOffer(); // Configure to receive video and audio
await localConnection.setLocalDescription(offer); peerConnection.addTransceiver('video', { direction: 'recvonly' });
peerConnection.addTransceiver('audio', { direction: 'recvonly' });
try {
console.log("Creating offer...");
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
console.log("Offer created and set as local description:", offer);
const signalMessage = { const signalMessage = {
type: 'offer', type: 'offer',
sdp: offer.sdp sdp: offer.sdp
}; };
console.log("Sending offer via WebSocket:", signalMessage);
wsConnection.send(JSON.stringify(signalMessage)); wsConnection.send(JSON.stringify(signalMessage));
} catch (error) {
console.error("Error creating offer:", error);
} }
// Handle SDP offer from the server
function handleOffer(signal) {
const remoteDescription = new RTCSessionDescription({
type: 'offer',
sdp: signal.sdp
});
localConnection.setRemoteDescription(remoteDescription)
.then(() => {
return localConnection.createAnswer();
})
.then((answer) => {
return localConnection.setLocalDescription(answer);
})
.then(() => {
const answerMessage = {
type: 'answer',
sdp: localConnection.localDescription.sdp
};
wsConnection.send(JSON.stringify(answerMessage));
})
.catch(console.error);
} }
// Handle SDP answer from the server // Handle SDP answer from the server
function handleAnswer(signal) { async function handleAnswer(signal) {
console.log("Handling answer:", signal);
const remoteDescription = new RTCSessionDescription({ const remoteDescription = new RTCSessionDescription({
type: 'answer', type: 'answer',
sdp: signal.sdp sdp: signal.sdp
}); });
localConnection.setRemoteDescription(remoteDescription).catch(console.error); try {
await peerConnection.setRemoteDescription(remoteDescription);
console.log("Remote description (answer) set successfully.");
} catch (error) {
console.error("Error setting remote description (answer):", error);
}
} }
// Handle ICE candidates // Handle ICE candidates generated locally (send to server)
function handleIceCandidateEvent(event) { function handleIceCandidateEvent(event) {
console.log("Local ICE candidate event:", event);
if (event.candidate) { if (event.candidate) {
console.log("Sending ICE candidate:", event.candidate);
const iceMessage = { const iceMessage = {
type: 'ice', type: 'ice',
ice: { ice: {
@ -99,19 +114,30 @@ function handleIceCandidateEvent(event) {
} }
}; };
wsConnection.send(JSON.stringify(iceMessage)); wsConnection.send(JSON.stringify(iceMessage));
} else {
console.log("All local ICE candidates have been sent.");
} }
} }
// Handle ICE candidate from the server // Handle ICE candidate received from the server
function handleIceCandidate(signal) { async function handleIceCandidate(signal) {
console.log("Handling received ICE candidate:", signal);
if (!signal.ice || !signal.ice.candidate) {
console.warn("Received incomplete ICE candidate signal:", signal);
return;
}
try {
const candidate = new RTCIceCandidate({ const candidate = new RTCIceCandidate({
candidate: signal.ice.candidate, candidate: signal.ice.candidate,
sdpMid: signal.ice.sdpMid, sdpMid: signal.ice.sdpMid,
sdpMLineIndex: signal.ice.sdpMLineIndex sdpMLineIndex: signal.ice.sdpMLineIndex
}); });
await peerConnection.addIceCandidate(candidate);
localConnection.addIceCandidate(candidate).catch(console.error); console.log("Added received ICE candidate successfully.");
} catch (error) {
console.error("Error adding received ICE candidate:", error);
}
} }
// Initialize the connection // Initialize the connection when the page loads
initWebSocket(); window.onload = initWebSocket;