Click here to Skip to main content
15,942,449 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
I have encountered an issue while making cross-browser calls between User 1 (using Chrome) and User 2 (using Firefox). Whenever User 2 tries to call User 1, the Chrome console displays the following error message: "script.js: Error: Could not start video source and i cannot see my video and second user video but in chrome which i called from,i can see that video."

To provide some context, I have already granted permission to the microphone and camera in the browser settings of both User 1 and User 2.

both Chrome and Firefox versions you are using support the necessary WebRTC features and signaling server is functioning correctly and is properly handling the exchange of offer and answer

Interestingly, the same error message is observed when testing the reverse scenario, where User 1 (Chrome) initiates a call to User 2 (Firefox). The error consistently occurs in both cases.

It seems that the error is related to the video source and arises when attempting to establish the WebRTC connection between Chrome and Firefox browsers.

Any insights or suggestions on how to resolve this issue would be greatly appreciated.I am developing an application in nodejs-kurento-js

below code i am getting error

What I have tried:

// Define WebSocket URL
const wsUrl = "ws://127.0.0.1:3000/one2one";

// DOM elements
const videoInput = document.getElementById("videoInput");
const videoOutput = document.getElementById("videoOutput");
const registerButton = document.getElementById("register");
const callButton = document.getElementById("call");
const terminateButton = document.getElementById("terminate");

// States
const RegisterState = {
	NOT_REGISTERED: 0,
	REGISTERING: 1,
	REGISTERED: 2,
};
let registerState = RegisterState.NOT_REGISTERED;

const CallState = {
	NO_CALL: 0,
	PROCESSING_CALL: 1,
	IN_CALL: 2,
};
let callState = CallState.NO_CALL;

// WebRTC variables
let webRtcPeer = null;

// Register event listener on window load
window.onload = function () {
	registerButton.addEventListener("click", register);
	callButton.addEventListener("click", call);
	terminateButton.addEventListener("click", stop);

	setRegisterState(RegisterState.NOT_REGISTERED);
	document.getElementById("name").focus();
};

// Register WebSocket message handler
function handleWebSocketMessage(message) {
	const parsedMessage = JSON.parse(message.data);
	console.log("Received message: " + message.data);
	console.log("events message: " + parsedMessage.id);
	switch (parsedMessage.id) {
		case "registerResponse":
			handleRegisterResponse(parsedMessage);
			break;
		case "callResponse":
			handleCallResponse(parsedMessage);
			break;
		case "incomingCall":
			handleIncomingCall(parsedMessage);
			break;
		case "startCommunication":
			handleStartCommunication(parsedMessage);
			break;
		case "stopCommunication":
			console.log("Communication ended by remote peer");
			stop(true);
			break;
		case "iceCandidate":
			webRtcPeer.addIceCandidate(parsedMessage.candidate);
			break;
		default:
			console.error("Unrecognized message", parsedMessage);
	}
}

// WebSocket initialization
const ws = new WebSocket(wsUrl);
ws.onmessage = handleWebSocketMessage;
window.onbeforeunload = function () {
	ws.close();
};

// Register functions
function setRegisterState(nextState) {
	registerState = nextState;

	switch (nextState) {
		case RegisterState.NOT_REGISTERED:
			registerButton.disabled = false;
			callButton.disabled = true;
			terminateButton.disabled = true;
			break;
		case RegisterState.REGISTERING:
			registerButton.disabled = true;
			break;
		case RegisterState.REGISTERED:
			registerButton.disabled = true;
			setCallState(CallState.NO_CALL);
			break;
		default:
			return;
	}
}

function handleRegisterResponse(message) {
	if (message.response === "accepted") {
		setRegisterState(RegisterState.REGISTERED);
	} else {
		setRegisterState(RegisterState.NOT_REGISTERED);
		const errorMessage = message.message
			? message.message
			: "Unknown reason for register rejection.";
		console.log(errorMessage);
		alert("Error registering user. See console for further information.");
	}
}

function register() {
	const name = document.getElementById("name").value;
	if (name === "") {
		window.alert("You must insert your user name");
		return;
	}

	setRegisterState(RegisterState.REGISTERING);

	const message = {
		id: "register",
		name: name,
	};
	sendMessage(message);
	document.getElementById("peer").focus();
}

// Call functions
function setCallState(nextState) {
	callState = nextState;

	switch (nextState) {
		case CallState.NO_CALL:
			callButton.disabled = false;
			terminateButton.disabled = true;
			break;
		case CallState.PROCESSING_CALL:
			callButton.disabled = true;
			terminateButton.disabled = true;
			break;
		case CallState.IN_CALL:
			callButton.disabled = true;
			terminateButton.disabled = false;
			break;
		default:
			return;
	}
}

function handleCallResponse(message) {
	if (message.response !== "accepted") {
		console.log("Call not accepted by peer. Closing call");
		const errorMessage = message.message
			? message.message
			: "Unknown reason for call rejection.";
		console.log(errorMessage);
		stop(true);
	} else {
		setCallState(CallState.IN_CALL);
		webRtcPeer.processAnswer(message.sdpAnswer);
	}
}

function call() {
	const peerName = document.getElementById("peer").value;
	if (peerName === "") {
		window.alert("You must specify the peer name");
		return;
	}

	setCallState(CallState.PROCESSING_CALL);
	showSpinner(videoInput, videoOutput);

	const options = {
		localVideo: videoInput,
		remoteVideo: videoOutput,
		onicecandidate: onIceCandidate,
		iceServer: [
			{
				urls: [
					"stun.stun.l.google.com:19302",
					"stun.stun1.l.google.com:19302",
					"stun.stun2.l.google.com:19302",
					"stun.stun3.l.google.com:19302",
					"stun.stun4.l.google.com:19302",
					"stun.stun.ekiga.net",
					"stun.stun.ideasip.com",
					"stun.stun.rixtelecom.se",
				],
			},
		],
	};

	webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv(
		options,
		function (error) {
			if (error) {
				console.error(error);
				setCallState(CallState.NO_CALL);
			}

			this.generateOffer(function (error, offerSdp) {
				if (error) {
					console.error(error);
					setCallState(CallState.NO_CALL);
				}

				const message = {
					id: "call",
					from: document.getElementById("name").value,
					to: peerName,
					sdpOffer: offerSdp,
				};

				sendMessage(message);
			});
		}
	);
}

function onIceCandidate(candidate) {
	console.log("*****LOCAL CANDIDATE" + JSON.stringify(candidate));

	const message = {
		id: "onIceCandidate",
		candidate: candidate,
	};
	sendMessage(message);
}

function sendMessage(message) {
	const jsonMessage = JSON.stringify(message);
	console.log("Sending message: " + jsonMessage);
	ws.send(jsonMessage);
}

function stop(message) {
	setCallState(CallState.NO_CALL);
	if (webRtcPeer) {
		webRtcPeer.dispose();
		webRtcPeer = null;

		if (!message) {
			sendMessage({ id: "stop" });
		}
	}
	hideSpinner(videoInput, videoOutput);
}

function handleIncomingCall(message) {
	if (callState !== CallState.NO_CALL) {
		const response = {
			id: "incomingCallResponse",
			from: message.from,
			callResponse: "reject",
			message: "busy",
		};
		return sendMessage(response);
	}

	setCallState(CallState.PROCESSING_CALL);
	if (
		confirm("User " + message.from + " is calling you. Do you accept the call?")
	) {
		showSpinner(videoInput, videoOutput);

		const options = {
			localVideo: videoInput,
			remoteVideo: videoOutput,
			onicecandidate: onIceCandidate,
			iceServer: [
				{
					urls: [
						"stun.stun.l.google.com:19302",
						"stun.stun1.l.google.com:19302",
						"stun.stun2.l.google.com:19302",
						"stun.stun3.l.google.com:19302",
						"stun.stun4.l.google.com:19302",
						"stun.stun.ekiga.net",
						"stun.stun.ideasip.com",
						"stun.stun.rixtelecom.se",
					],
				},
			],
		};

		webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv(
			options,
			function (error) {
				if (error) {
					console.error("Error: " + error.message);
					setCallState(CallState.NO_CALL);
				}

				this.generateOffer(function (error, offerSdp) {
					if (error) {
						console.error(error);
						setCallState(CallState.NO_CALL);
					}
					const response = {
						id: "incomingCallResponse",
						from: message.from,
						callResponse: "accept",
						sdpOffer: offerSdp,
					};
					sendMessage(response);
				});
			}
		);
	} else {
		const response = {
			id: "incomingCallResponse",
			from: message.from,
			callResponse: "reject",
			message: "user declined",
		};
		sendMessage(response);
		stop(true);
	}
}

function handleStartCommunication(message) {
	setCallState(CallState.IN_CALL);
	webRtcPeer.processAnswer(message.sdpAnswer);
}

function showSpinner() {
	for (var i = 0; i < arguments.length; i++) {
		arguments[i].poster = "./img/transparent-1px.png";
		arguments[i].style.background =
			'center transparent url("./img/spinner.gif") no-repeat';
	}
}

function hideSpinner() {
	for (var i = 0; i < arguments.length; i++) {
		arguments[i].src = "";
		arguments[i].poster = "./img/webrtc.png";
		arguments[i].style.background = "";
	}
}
Posted
Updated 20-May-23 2:14am
v2
Comments

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900