what is the appropriate way to achieve offer to recieve and send in webRTC? - webrtc

in my case after get everything done and running i want to migrate from add track to addTranciever
i have 2 peerConnection
yourConn = new RTCPeerConnection(servers);
yourConn2 = new RTCPeerConnection(servers);
and with following steps i see in many example casses i addTransciever like so
yourConn.addTransceiver(streams.getAudeoTracks()[0]);
how to recieve from yourConn peer ? and can i achieve that with send from peer 1 to peer 2
and p1 recieve from p2 with no need to negotiation again
what should i do also in ontrack event on both side with , should i use addTrack there or not if i wish
here yourConn2 event side here offer to send what about offer to recieve?
yourConn2.ontrack = (e) => {
e.transceiver.direction = 'sendrecv';
await e.transceiver.sender.replaceTrack(remoteStream);
};
should i grap
RemoteAudioFromlocal = yourConn2.getTransceivers()[0];
and i upgrade" the direction to sendrecv like so ?
RemoteAudioFromlocal.direction = "sendrecv"
await RemoteAudioFromlocal.reciever.replaceTrack(remotePeerStramIn);

i will answer my question since i figuer it out
from [Jan-Ivar Bruaroey blog1 i've discover all my question that i ask for
with addTransceiver() in one side i can get Transceivers within onTrackEvent
like so
if (e.transceiver.receiver.track) {
remoteVideo = document.getElementById("wbrtcremote");
transceiversRemotePeer = new MediaStream([e.transceiver.receiver.track]);
remoteVideo.srcObject = transceiversRemotePeer
}
that's all what i need to know the same on other side but here with a minor differnce like you need to change the direction since
The transceiver created by the sender is sendrecv by default with addtranciever
side
yourConn.addTransceiver(streams.getAudeoTracks()[0]);
. This gets mirrored by a transceiver on the receiver side for the same mid. Here it's exposed in the ontrack event,
yourConn2.ontrack = await e => {
/* do something with e.track */
e.transceiver.direction = 'sendrecv';
await e.transceiver.sender.replaceTrack(receiverTrack);
};
but in an "offer to receive" use case you could obtain it via getTransceivers() or like above code with e.transceiver.sender
on the receiver side(yourConn2), the direction is "downgraded" from sendrecv to recvonly because by default this transceiver is not configured to send anything back from receiverPc(yourConn2) to senderPc(yourConn).
After all, it was just created in response to setRemoteDescription(offer).
To fix this, you "upgrade" the direction to sendrecv and set a track to send.
e.transceiver.direction = 'sendrecv';
e.transceiver.sender.replaceTrack(localStream.getAudioTracks()[0]).then(() => {
});
If you do this prior to creating the local SDP answer on receiverPc, you should be able to achieve "sendrecv" without more SDP negotiations. The ontrack event is fired before the SRD promise is resolved, so any modification you do in that event should have completed before the SDP answer is created.

Related

Managing 2 conferences with Voximplant scenario

I am trying to make conference with Voximplant, and when user makes a call to another user, while the call is still going on, it makes another call to another user making two calls and the callees is added to a video conferencing.
But it seems the caller is billed twice and the scenerio doesnt look optimised. What should i do to bill once and optimize it?
Scenario:
require(Modules.Conference);
var call, conf = null;
VoxEngine.addEventListener(AppEvents.Started, handleConferenceStarted);
function handleConferenceStarted(e) {
// Create 2 conferences right after session to manage audio in the right way
if( conf === null ){
conf = VoxEngine.createConference(); // create conference
}
conf.addEventListener(CallEvents.Connected,function(){
Logger.write('Conference started')
})
}
VoxEngine.addEventListener(AppEvents.CallAlerting, function(e) {
e.call.addEventListener(CallEvents.Connected, handleCallConnected);
let new_call = VoxEngine.callUser(e.destination,e.callerid,e.displayName,{},true)
new_call.addEventListener(CallEvents.Connected,handleCallConnected);
e.call.answer();
});
function handleCallConnected(e) {
Logger.write('caller connected');
conf.add({
call: e.call,
mode: "FORWARD",
direction: "BOTH", scheme: e.scheme
});
}
You need to end the conference when there are no participants. Refer to the following article in our documentation: https://voximplant.com/docs/guides/conferences/howto. You can find the full scenario code there.
Additionally, I recommend to add some handlers for the CallEvents.Disconnected and the CallEvent.Failed events right after
new_call.addEventListener(CallEvents.Connected,handleCallConnected);
because sometimes the callee may be offline or press a reject button. 🙂

How to get multiple streams in a peerConnection

Hello I am going to create a surveillance system. I would like to get a webcam video and a shared screen, but using addtrack will only get the media stream I declared later. Is there any way to get both streams.
thanks.
here is code offer side
let stream = video.srcObject;
let stream2 = shareVideo.srcObject;
stream.getTracks().forEach(track => peerConnection.addTrack(track, stream));
stream2.getTracks().forEach(track => peerConnection.addTrack(track, stream2));
and here is answer side
peerConnections[id].ontrack = (event) => {
console.log(event);
when i checked log. event has one track and stream[0] has mediastream bu steam[1] has no mediastream

WebRTC: Detecting muted track faster post warm-up

I'm warming up my transceiver like so:
pc.addTranceiver('video')
This creates a dummy track in the transceiver's receiver. Soon after, the unmute event fires on that track.
Then, ~3 seconds later, the mute event fires.
My goal is to detect that a track is a dummy track as fast as possible.
ideas
send a message via the data channel telling the peer that the track is void. this is a pain since i'll have to send another message when I later call replaceTrack
write a frame of the track to canvas & see if it's an image. This seems really barbaric, but it's faster than 3 seconds.
anything better? it feels like this should be pretty simple.
This is a bug in Chrome (please ★ it so they'll fix it).
The spec says receiver tracks must start out muted and should stay that way until packets arrive. But Chrome fires the unmute event immediately, followed a few seconds later by a mute event due to inactivity (another bug):
const config = {sdpSemantics: "unified-plan"};
const pc1 = new RTCPeerConnection(), pc2 = new RTCPeerConnection();
pc1.addTransceiver("video");
pc2.ontrack = ({track}) => {
console.log(`track starts out ${track.muted? "muted":"unmuted"}`);
track.onmute = () => console.log("muted");
track.onunmute = () => console.log("unmuted");
};
pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate);
pc1.onnegotiationneeded = async e => {
await pc1.setLocalDescription(await pc1.createOffer());
await pc2.setRemoteDescription(pc1.localDescription);
await pc2.setLocalDescription(await pc2.createAnswer());
await pc1.setRemoteDescription(pc2.localDescription);
}
In Chrome you'll see incorrect behavior:
track starts out muted
unmuted
muted
In Firefox you'll see correct behavior:
track starts out muted
Chrome workaround:
Until Chrome fixes this, I'd use this workaround:
const video = document.createElement("video");
video.srcObject = new MediaStream([track]);
video.onloadedmetadata = () => log("unmuted workaround!");
Until this fires, assume the track to be muted.

Check if number has whatsapp via whatsapp web

I know it's possible to create a button to start a conversation for a number.
But is it possible to check first if this number has whatsapp?
I need a grid with multiple numbers, and show the option to start conversation only for numbers that have whatsapp.
Note: I want to make this process logged in to whatsapp web.
It is a bit old question, but i get this question when i search for the same thing. After some reads, this is what i get. Hope it could help someone that search the same thing.
You could use the Client.getNumberId() function to check if the mobile phone number is registered on WhatsApp or not, check out the documentation on https://docs.wwebjs.dev/Client.html.
Note: you might need to sanitized the phone number first to ensure it is in the right format, which is , etc 618123456789.
61 is the country code, and the 08123456789 is the usual mobile number (remove the first zero on it).
var client = whatsAppWebClient.client;
var mobile_no = '628123456789';
// Get the registered WhatsApp ID for a number
var number_details = await client.getNumberId(sanitized_number);
if(number_details) {
console.log("Sending message to ", number_details);
/* send message */
} else {
console.log(sanitized_number, "Mobile no is not registered on
}
import {Client} from 'whatsapp-web.js';
const client = new Client({
// client configuration if any
})
// other blocks of code goes here
//function for checking if number is registered on whatsapp
const isNumberOnWhatsapp = async (number) => {
return await client.isRegisteredUser(number)
}
client.initialize()

How to subscribe and unsubscribe from EventStream on the first event received?

I am trying to figure it out if there is a function in the Bacon.js API that allows to subscribe to an EventStream and when the first event fires up, the handle is unsubscribed. The way to do it that I know is the following:
let stream = new Bacon.Bus();
stream.onValue(val => {
doSomething(val);
return Bacon.noMore;
});
But is there something like stream.onValueOnce that automatically unsubscribe the handler after it is executed?
I also know that there is the Bacon.once that creates a EventStream that returns a single value and then ends the stream but this is not what I am looking for.
Update
As Bless Yahu sais, take or first methods can be used. To be more specific, you have to call it from the created eventStream like that:
let stream = new Bacon.Bus();
stream.first().onValue(val => {
doSomething(val);
});
Here is a fiddle that shows it:
https://fiddle.jshell.net/3kjtwcwy/
How about stream.take(1)? https://baconjs.github.io/api.html#observable-take
Or stream.first()? https://baconjs.github.io/api.html#observable-first