Docs updated 03th November 2019
This package was created to simplify work with original WebRTC. Yes, you can create voice/video chat with multiple users by use this package.
Tested only on Chrome. Most likely this package does not work in other browsers. If you need support for other browsers, write to me
This specification is very confusing, the intricacies of which will be described here.
Like WebRTC, this package assumes that users are already connected to the server(sockets or etc) that will connect them.
npm i webrtc-unified
Same packet for server and client
Client file for direct connection - client.js or client.min.js
Full example code server-demo.js
// require lib
const Voicer = require('webrtc-unified/server');
// create server instance
const voicer = Voicer();
// some code
// example connection event handler
function onClient(ws, req) {
// create client instance
// you can put off initializing client instance before getting data for this package
ws.voicer = voicer.addClient({
// function for send information(object) to client
// you must get data on client and use appropriate function in client lib
send: data => ws.send(JSON.stringify({
action: 'webrtc-unified',
data: data
})),
// user data for sending this value to client
// if don`t set client get undefined
// don`t require
// userId: some value/can be object,
// client id for sending this value to client
// if don`t set the lib sets random string
// don`t require, must be unique
// better to use userId
// clientId: string,
});
// we get some data from client
ws.on('message', mess => {
let data;
try {
data = JSON.parse(mess);
} catch (e) {
// fall
return ws.terminate();
};
// we get message for lib
if (data.action === 'webrtc-unified'){
// if you dont call voicer.addClient here, its place for do it
// if(!ws.voicer) ws.voicer = voicer.addClient({send: function})
// send message to lib
return ws.voicer.receive(data.data);
}
else console.log(data);
});
// when connection closed, use close for disconnect this user from other and destroy client instance
ws.on('close', function () {
ws.voicer.close();
ws.voicer = undefined;
});
}
Full example code client-demo.js
// ignore this file if you include client.js file early
const WebRTCUnified = require('webrtc-unified/client');
let rtcUnified = new WebRTCUnified();
// add ice server
// rtcUnified.addIceServer({
// url: `turn:someserver.example:3478?transport=tcp`,
// username: "username",
// credential: "credential",
// })
// create connection with our server
var socket = new WebSocket('ws' + location.origin.slice(4) + '/ws');
// function to send data to the server
function func_send(data) {
socket.send(JSON.stringify({
action: 'webrtc-unified',
data: data
}));
};
// reload page if connection lost
socket.onclose = function () {
location.reload();
};
// get a messages handler function
let conn_handler = rtcUnified.setConnect(func_send);
// handle socket a connected state
socket.onopen = function () {
// join to default room
rtcUnified.joinRoom('default');
};
// handle messages
socket.onmessage = function (msg) {
var json = JSON.parse(msg.data);
if (json.action === 'webrtc-unified') conn_handler(json.data);
else console.log(json);
};
// bind actions
butt_micro.onclick = function () {
if (this.innerHTML == 'Enable micro') {
rtcUnified.setMedia({
type: 'audio',
enable: true,
});
this.innerHTML = 'Mute micro';
} else {
rtcUnified.setMedia({
type: 'audio',
enable: false,
});
this.innerHTML = 'Enable micro';
}
}
butt_micro.onclick();
butt_cam.onclick = function () {
if (this.innerHTML == 'Enable cam') {
rtcUnified.setMedia({
type: 'video',
enable: true,
});
this.innerHTML = 'Disable cam';
} else {
rtcUnified.setMedia({
type: 'video',
enable: false,
});
this.innerHTML = 'Enable cam';
}
}
butt_screen.onclick = function () {
if (this.innerHTML == 'Enable screen') {
rtcUnified.setMedia({
type: 'display',
enable: true,
});
this.innerHTML = 'Disable screen';
} else {
rtcUnified.setMedia({
type: 'display',
enable: false,
});
this.innerHTML = 'Enable screen';
}
};
// user reject request to use audio/video/screen
rtcUnified.on('rejectUseMedia', function (media_type) {
alert('reject request to use ' + media_type);
});
// handle local stream for draw
rtcUnified.on('addedLocalStream', function (stream, media_type) {
// ignore voice
if (media_type == 'audio') return;
// ignore screen
if (media_type == 'screen' && you.srcObject) return;
you.srcObject = stream;
you.play();
});
// handle local stream for remove
rtcUnified.on('removedLocalStream', function (stream, media_type) {
// ignore voice
if (media_type == 'audio') return;
you.srcObject = undefined;
});
// handle remote stream for draw
rtcUnified.on('addedRemoteStream', function (stream, media_type, clientId) {
// media_type - screen accepted as video on remote client
// but just in case screen type check
var tag = media_type === 'screen' ? 'video' : media_type;
var remote = document.createElement(tag);
document.body.appendChild(remote);
remote.srcObject = stream;
remote.play();
remote.volume = 1;
remote.dataset.clientId = clientId;
});
// handle remote stream for remove
rtcUnified.on('removedRemoteStream', function (stream, media_type, clientId) {
let mediaList = document.querySelectorAll('[data-client-id="' + clientId + '"]');
for (let i = 0; i < mediaList.length; i++)
if (mediaList[i].srcObject === stream)
mediaList[i].remove();
});
The media this is any audio or video resource that is broadcast to other chat participants
audio
- microphonevideo
- webcamdisplay
- desktop, specific program or etc
Returns WebRTCUnified
instance
iceServer
- an object containing following properties:-
url
- required, URL which can be used to connect to the server. Example:turn:someserver.example:3478?transport=tcp
-
username
- Optional. if the RTCIceServer is a TURN server, then this is the username to use during the authentication process.
-
credential
- Optional. The credential to use when logging into the server. This is only used if the RTCIceServer represents a TURN server.
The RTCIceServer dictionary defines how to connect to a single ICE server (such as a STUN or TURN server). It includes both the URL and the necessary credentials, if any, to connect to the server.
By default added stun:stun.l.google.com:19302
- function
sendData
- is called when need senddata
to server -
data
- an object with data for server
Returns: function for messages from server, receives an object from the server side
- roomId - an string with room id, can be user id or etc
Will join other users in the room. If the user is already another in the room, first they will exit.
Leave current room
options
- an object containing following properties:-
type
- type of media
-
enable
- optional an boolean. If not set, toggled current state
-
args
- optional an object fornavigator.mediaDevices.getUserMedia/getDisplayMedia
Turn on / off media
type
- type of media
Returns: native browser stream or undefined. Use to verify enabled media
options
- an object containing following properties:-
type
- type of media
-
args
- optional an object fornavigator.mediaDevices.getUserMedia/getDisplayMedia
Turn on media. Better use setMedia
to manage state
Set handle, allowed rtcUnified.once
Handled when called setConnect
options
- an object containing following properties:-
clientId
- Client system identifier unique to each connection
-
userId
- The identifier of the user who transmitted the server
-
roomId
- Room id
Handled when user connected to room, before connecting to other chat participants
Handled when it was called or the server kicked the user from the room
options
- an object containing following properties:-
clientId
- Client system identifier unique to each connection
-
userId
- The identifier of the user who transmitted the server
Handled when user connected to room, before connecting with him
options
- an object containing following properties:-
clientId
- client system identifier unique to each connection
-
userId
- the identifier of the user who transmitted the server
Handled when user leaves from room, before disconnect with him
type
- type of media
Handled when user reject use media
stream
- native browser streamtype
- type of media
Handled when media has been added by setMedia
or createStream
methods
stream
- native browser streamtype
- type of media
Handled when media has been removed by setMedia
method
stream
- native browser streamtype
- type of mediaclientId
- client system identifier unique to each connectionuserId
- the identifier of the user who transmitted the server
Handled when a room user started broadcasting media
stream
- native browser streamtype
- type of mediaclientId
- client system identifier unique to each connectionuserId
- the identifier of the user who transmitted the server
Handled when a room user has finished broadcasting media
- Tested only on Chrome
- getUserMedia - Privacy and security