See more:
scaledrone / webrtc Goto Github PK
View Code? Open in Web Editor NEWVideo chat App with WebRTC using Scaledrone Realtime Messaging Service
Home Page: https://www.scaledrone.com/
Video chat App with WebRTC using Scaledrone Realtime Messaging Service
Home Page: https://www.scaledrone.com/
Hi!
I would like to ask for some help on retrieving the number of users in the room. I'm using the WebRTC tutorial here
There is a part where we call startWebRTC
function based on the number of members in the room.
room.on('members', members => {
if (members.length >= 3) {
return alert('The room is full');
}
// If we are the second user to connect to the room we will be creating the offer
const isOfferer = members.length === 2;
startWebRTC(isOfferer);
startListentingToSignals();
});
I might have missunderstood the documentation, I thought this listener will retrieve every member in the room.
When I log out the room and the members variable provided by the listener I get these:
room:
Room {
name: "observable-REMOVED"
scaledrone: Scaledrone {args: Arguments(1), originalInstance: Scaledrone, readyState: 2, callbackId: 2, callbacks: {…}, …}
_cache: [{…}]
_events: {
data: [{…}]
member_join: [{…}]
members: Array(5)
0: {callback: ƒ, context: undefined, ctx: Room}
1: {callback: ƒ, context: undefined, ctx: Room}
2: {callback: ƒ, context: undefined, ctx: Room}
3: {callback: ƒ, context: undefined, ctx: Room}
4: {callback: ƒ, context: undefined, ctx: Room}
...
As you can see here, there is 5 ppl in the room already, while the event listener will log this:
members array in the listener
MEMBERS:
0: {id: "BlrBA6qWpK"}
length: 1
__proto__: Array(0)
Can you please help me out with this one? Is there any other way to retrieve the number of users in the room?
Also forgot to mention that I can see the connected members if I visit my scaledrone dashboard.
Thanks!
Hello, I am trying to integrate this code in my app where I am trying to pass the streams to my modules which hold the canvas elements.
I tried using async/await but unfortunately I am getting below error:
export default function getDrone() {
return new Promise((resolve, reject) => {
const drone = new Scaledrone('fBAkzbVAOmA2wbU0');
const roomName = 'observable-room';
const configuration = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
};
let room;
let pc;
const streamArr = [];
async function handleError(error) {
window.console.error(error);
drone.close();
reject(error);
}
async function handleClose() {
window.console.log('Drone disconnected');
}
async function handleSuccess() {
window.console.log('Drone connected');
// window.console.log(drone);
}
async function handleRoom(error) {
if (error) {
handleError(error);
}
handleSuccess();
}
async function handleOpen(error) {
if (error) {
handleError(error);
}
window.console.log('Drone connecting');
try {
room = await drone.subscribe(roomName);
room.on('open', handleRoom);
room.on('members', handleMembers);
} catch (e) {
handleError(new Error('Failed to subscribe to room'));
}
}
// Send signaling data via Scaledrone
function sendMessage(message) {
drone.publish({
room: roomName,
message
});
}
function localDescCreated(desc) {
pc.setLocalDescription(desc, () => sendMessage({ sdp: pc.localDescription }), handleError);
}
async function startWebRTC(isOfferer) {
let remoteStream;
let sourceStream;
pc = new RTCPeerConnection(configuration);
// 'onicecandidate' notifies us whenever an ICE agent needs to deliver a
// message to the other peer through the signaling server
pc.onicecandidate = event => {
if (event.candidate) {
sendMessage({ candidate: event.candidate });
}
};
// If user is offerer let the 'negotiationneeded' event create the offer
var isNegotiating = false;
if (isOfferer) {
pc.onnegotiationneeded = () => {
console.log('creating offer');
if (isNegotiating) {
console.log('Skiping nested negotiation');
return;
}
isNegotiating = true;
pc.createOffer()
.then(localDescCreated)
.catch(handleError);
};
}
pc.onsignalingstatechange = e => {
// Workaround for Chrome: skip nested negotiations
isNegotiating = pc.signalingState !== 'stable';
};
pc.oniceconnectionstatechange = e => {
// Workaround for Chrome: skip nested negotiations
console.log('state change:', e, e.currentTarget.remoteDescription.sdp);
};
// When a remote stream arrives display it in the #remoteVideo element
pc.ontrack = event => {
const stream = event.streams[0];
remoteStream = stream;
streamArr.push(remoteStream);
};
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true
})
.then(stream => {
// Display your local video in #localVideo element
sourceStream = stream;
streamArr.push(sourceStream);
// Add your stream to be sent to the conneting peer
stream.getTracks().forEach(track => pc.addTrack(track, stream));
}, handleError);
// Listen to signaling data from Scaledrone
room.on('data', (message, client) => {
// Message was sent by us
if (client.id === drone.clientId) {
return;
}
if (message.sdp) {
// This is called after receiving an offer or answer from another peer
pc.setRemoteDescription(
new RTCSessionDescription(message.sdp),
() => {
// When receiving an offer lets answer it
if (pc.remoteDescription.type === 'offer') {
pc.createAnswer()
.then(localDescCreated)
.catch(handleError);
}
},
handleError
);
} else if (message.candidate) {
// Add the new ICE candidate to our connections remote description
pc.addIceCandidate(new RTCIceCandidate(message.candidate), onSuccess, handleError);
}
});
}
async function onSuccess() {
resolve(streamArr); //return streams array here back to my module.
console.log('success');
}
// I am getting 13 success output and also list of streams but connection is closed and also below error
async function handleMembers(members) {
if (members) {
// handleError(error);
// console.log(members);
const isOfferer = members.length === 2;
await startWebRTC(isOfferer);
}
// handleSuccess();
}
// drone.on('authenticate', handleRoom);
drone.on('error', handleError);
drone.on('close', handleClose);
drone.on('open', handleOpen);
});
}
This is the error I am getting:
ScaledroneMeet.js:17 DOMException
_callee$ @ ScaledroneMeet.js:17
tryCatch @ runtime.js:65
invoke @ runtime.js:303
prototype.(anonymous function) @ runtime.js:117
asyncGeneratorStep @ bundle.js:4186
_next @ bundle.js:4188
(anonymous) @ bundle.js:4188
(anonymous) @ bundle.js:4188
_handleError @ ScaledroneMeet.js:2
handleError @ ScaledroneMeet.js:2
scaledrone.min.js:288 WebSocket is already in CLOSING or CLOSED state.
(anonymous) @ scaledrone.min.js:288
(anonymous) @ scaledrone.min.js:29
nextTick @ scaledrone.min.js:17
characterData (async)
scheduleDrain @ scaledrone.min.js:17
immediate @ scaledrone.min.js:17
unwrap @ scaledrone.min.js:29
Promise.then @ scaledrone.min.js:29
Scaledrone._sendMessage @ scaledrone.min.js:288
Scaledrone.publish @ scaledrone.min.js:288
sendMessage @ ScaledroneMeet.js:59
pc.onicecandidate @ ScaledroneMeet.js:76
ScaledroneMeet.js:26 Drone disconnected
2scaledrone.min.js:288 WebSocket is already in CLOSING or CLOSED state.
(anonymous) @ scaledrone.min.js:288
(anonymous) @ scaledrone.min.js:29
nextTick @ scaledrone.min.js:17
characterData (async)
scheduleDrain @ scaledrone.min.js:17
immediate @ scaledrone.min.js:17
unwrap @ scaledrone.min.js:29
Promise.then @ scaledrone.min.js:29
Scaledrone._sendMessage @ scaledrone.min.js:288
Scaledrone.publish @ scaledrone.min.js:288
sendMessage @ ScaledroneMeet.js:59
pc.onicecandidate @ ScaledroneMeet.js:76
I imported the code as such:
<script src='https://cdn.scaledrone.com/scaledrone.min.js'></script> and I can see the source no problem. It's when the second participant connects I get above error.
I would appreciate any directions! Thanks.
demo https://scaledrone.github.io/webrtc/index.html#bda2af silently fails. console:
onaddstream is deprecated! Use peerConnection.ontrack instead.
script.js:72
MediaStreamError { name: "NotAllowedError", message: "The request is not allowed by the user agent or the platform in the current context.", constraint: "", stack: "" }
script.js:22:3
Hi I am trying to have more than 2 users in the video chat? I've tried to dynamically add new videos, but the webrtc tends to error out. Do you have any resources I can look at to refactor this code? Thanks.
I tried the same code in my project. It works fine with wifi but doesn’t work with mobile data(3G/4G)
DOMException: Failed to set local answer sdp: Called in wrong state: kStable
I am trying to run the webRTC code which i have mentioned below, it is working fine when i am connecting with two devices using same network. But it is not connecting when the devices are in different networks and i am getting DOM Exception. please help me to fix it.
// Generate random room name if needed
if (!location.hash) {
location.hash = Math.floor(Math.random() * 0xFFFFFF).toString(16);
}
const roomHash = location.hash.substring(1);
// TODO: Replace with your own channel ID
const drone = new ScaleDrone('yiS12Ts5RdNhebyM');
// Room name needs to be prefixed with 'observable-'
const roomName = 'observable-' + roomHash;
const configuration = {
iceServers: [{
urls: 'stun:stun.l.google.com:19302'
}]
};
let room;
let pc;
function onSuccess() {};
function onError(error) {
console.error(error);
};
drone.on('open', error => {
if (error) {
return console.error(error);
}
room = drone.subscribe(roomName);
room.on('open', error => {
if (error) {
onError(error);
}
});
// We're connected to the room and received an array of 'members'
// connected to the room (including us). Signaling server is ready.
room.on('members', members => {
console.log('MEMBERS', members);
// If we are the second user to connect to the room we will be creating the offer
const isOfferer = members.length === 2;
startWebRTC(isOfferer);
});
});
// Send signaling data via Scaledrone
function sendMessage(message) {
drone.publish({
room: roomName,
message
});
}
function startWebRTC(isOfferer) {
pc = new RTCPeerConnection(configuration);
// 'onicecandidate' notifies us whenever an ICE agent needs to deliver a
// message to the other peer through the signaling server
pc.onicecandidate = event => {
if (event.candidate) {
sendMessage({'candidate': event.candidate});
}
};
// If user is offerer let the 'negotiationneeded' event create the offer
if (isOfferer) {
pc.onnegotiationneeded = () => {
pc.createOffer().then(localDescCreated).catch(onError);
}
}
// When a remote stream arrives display it in the #remoteVideo element
pc.ontrack = event => {
const stream = event.streams[0];
if (!remoteVideo.srcObject || remoteVideo.srcObject.id !== stream.id) {
remoteVideo.srcObject = stream;
}
};
navigator.mediaDevices.getUserMedia({
audio: true,
video: true,
}).then(stream => {
// Display your local video in #localVideo element
localVideo.srcObject = stream;
// Add your stream to be sent to the conneting peer
stream.getTracks().forEach(track => pc.addTrack(track, stream));
}, onError);
// Listen to signaling data from Scaledrone
room.on('data', (message, client) => {
// Message was sent by us
if (client.id === drone.clientId) {
return;
}
if (message.sdp) {
// This is called after receiving an offer or answer from another peer
pc.setRemoteDescription(new RTCSessionDescription(message.sdp), () => {
// When receiving an offer lets answer it
if (pc.remoteDescription.type === 'offer') {
pc.createAnswer().then(localDescCreated).catch(onError);
}
}, onError);
} else if (message.candidate) {
// Add the new ICE candidate to our connections remote description
pc.addIceCandidate(
new RTCIceCandidate(message.candidate), onSuccess, onError
);
}
});
}
function localDescCreated(desc) {
pc.setLocalDescription(
desc,
() => sendMessage({'sdp': pc.localDescription}),
onError
);
}
hello there please tell me is there any possibillity for above question i tried it but i grtting this error
Uncaught (in promise) DOMException: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Error processing ICE candidate
We have integrate this code but only support Mozilla Firefox,but not support rest all of these browser please suggest for supporting all browser.
I added the following code (i found online) to add a mute/unmute button and it doesnt work. Any idea why?
In index.html i added:
<button id="mute_btn" onclick="muteBtnClick()">Mute Mic</button>
In script.js i added at the very bottom:
function muteBtnClick() {
var btn = document.getElementById("mute_btn");
if (isMicMuted()) {
muteMic(false);
btn.innerHTML = "Mute Mic";
} else {
muteMic(true);
btn.innerHTML = "Unmute Mic";
}
}
function isMicMuted() {
return !(localStream.getAudioTracks()[0].enabled); }
function muteMic (mute) {
localStream.getAudioTracks()[0].enabled = !mute;
};
Can i use this code?
I've tried to connect from Safari to Chrome and vice versa.
If Safari is the initial member Safari give an error;
Unhandled Promise Rejection: InvalidStateError: Description type incompatible with current signaling state
If Chrome is the initial member, then Chrome's error is
DOMException: Error processing ICE candidate
I have had this working for a project in the past but can't see what the issue is
I'm posting this here in hopes it'll be useful to others. This project seems old and not updated anymore.
I built a chat room and referenced this code, and it worked fine in Firefox/Chromium on everything except for iPads or Safari browsers. I've made some progress in resolving why.
The most important change needed is that Safari only supports the modern Promise-based syntax for the WebRTC APIs whereas this project is using callbacks.
e.g.: instead of setLocalDescription(desc, onSuccess, onFailure)
change those to setLocalDescription(desc).then(onSuccess).catch(onFailure)
and Safari makes more progress.
Symptoms I noticed (my logic was closely inspired by this webrtc demo's, so this is probably true of this project still too):
The culprit was: the sendOffer() and then setLocalDescription logic was failing on Safari and the SDP message was not being sent. Firefox and Chrome supported the legacy APIs and worked OK, but Safari, being later to the WebRTC bandwagon, only opted to support the Promise-based APIs.
I also found this web page to be a valuable resource: https://webrtchacks.com/guide-to-safari-webrtc/
An important aspect of iPad is they seem to not support send-only or receive-only channels: it needs to be a bidirectional video call. I think this webrtc demo should be doing that OK: on the initial offer the iPad needs to attach their own local video channel to the call to begin with, and receive video from the answerer and then all works OK.
I am doing video chat using ScaleDrone , I want to check if any user haven't Join the Video chat First User that was calling to other User need to know the Status of the call,
Like in Facebook if any user not picking the call it will say user Unreachable.
Hi,
It seems the script does NOT work for now!?
may I ask to test it and let me know the outcome?
Thanks
The live demo fails with an error that says "ReferenceError: ScaleDrone is not defined"
I am trying to run this example with Chrome of window 10 and Safari 11 of iPad, but it's not working.
Each browser has displaying only local stream not remote one.
There is no issue on browsers because this demo is working on same.
Hi,
I've been testing with the code as provided on my webpage but the remoteVideo is not showing. In my developer console for Chrome, I have this error message: DOMException: Error processing ICE candidate.
I checked out the live demo on https://scaledrone.github.io/webrtc/index.html
The live demo also has the same error message DOMException: Error processing ICE candidate in the console.
When I log onto scaledrone, I can see that there are 2 users in the room, but for both users, the remoteVideo is not showing
everything is working great i want to add a function for end stream if user one is end stream it should be disconnect from both side.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.