RTCMultiConnection tips and tricks for advance users!
Modify Signaling-Server.js
and add this line:
io.on('connection', onConnection);
// add this line,
// quickly after above line
io.set('origins', 'https://domain.com');
Otherwise:
// Seach & modify this function on Signaling-Server.js
function onConnection(socket) {
if (socket.handshake.headers.origin == 'https://domain.com') {
console.log(socket.handshake.headers.origin + ' Allowed.');
} else {
console.log(socket.handshake.he aders.origin + ' Not Allowed.');
socket.disconnect();
return;
}
// rest of the code from Signaling-Server.js
}
Now you've restricted the usage of socket.io only on domain https://domain.com:9001
.
It happens all insidde the onstream
event.
connection.onstream = function(event) {
if (event.type == 'local') {
showLocalVideo(event);
return;
}
if (event.type == 'remote') {
var numberOfUsers = connection.getAllParticipants().length;
if (numberOfUsers == 1) {
showFirstUserVideoOnFullScreen(event);
} else {
showSecondAndUpcomingVideosInSmallDiv(event);
}
}
};
function showLocalVideo(event) {}
function showFirstUserVideoOnFullScreen(event) {}
function showSecondAndUpcomingVideosInSmallDiv(event) {}
- We are comparing
even.type == local or remote
to detect video's type. - We can differentiate between audio, video and screen using
event.stream.isScreen
orevent.stream.isAudio
orevent.stream.isVideo
. - Unique
event.streamid
to set uniqueIDs
for each video element.
E.g.
connection.onstream = function(event) {
var videoElement = event.mediaElement;
// "streamid" uniquely identifies each video
videoElement.id = event.streamid;
// single user can share multiple videos (+multiple screens)
videoElement.setAttribute('data-userid', event.userid);
videoElement.onclick = function() {
// get the unique stream-id
var streamid = this.id;
// get user-id
var userid = this.getAttribute('data-userid');
// you can access native RTCPeerConnection object
var allVideosComingFromThisUser = connection.peers[userid].peer.getRemoteStreams();
// you can access the MediaStream data
var streamEvent = connection.streamEvents[streamid];
console.log(streamEvent.type, streamEvent.stream.isScreen, streamEvent.stream, streamEvent.mediaElement);
};
};
As you can see in the above snippet, we are setting two HTML attributes:
id
which isevent.streamid
data-userid
which isevent.userid
id
helps us access MediaStream
object. We can detect type of stream, active tracks, etc.
data-userid
helps us detect who is sending the video stream.
You can always reset the video.src
:
videoElement.onclick = function() {
// get the unique stream-id
var streamid = this.id;
// you can access the MediaStream data
var streamEvent = connection.streamEvents[streamid];
// access native MediaStreamObject
var mediaStream = streamEvent.stream;
// reset the URL
videoElement.src = URL.createObjectURL(mediaStream);
videoElement.play();
};
You can merge or stop tracks:
videoElement.onclick = function() {
// get the unique stream-id
var streamid = this.id;
// you can access the MediaStream data
var streamEvent = connection.streamEvents[streamid];
// access native MediaStreamObject
var mediaStream = streamEvent.stream;
// add new track
mediaStream.addTrack(newTrack);
// remove existing track
var videoTrack = mediaStream.getVideoTracks()[0];
mediaStream.removeTrack(videoTrack);
};
You can renegotiate peers to share new tracks:
videoElement.onclick = function() {
// get user-id
var userid = this.getAttribute('data-userid');
// renegotiate to update RTCPeerConnection
// it will reset ports; access all fresh tracks; etc.
connection.renegotiate(userid);
};
<script>
// add this script before loading "RTCMultiConnection.min.js"
window.getExternalIceServers = true;
</script>
<script src="https://muazkhan.com:9001/dist/RTCMultiConnection.min.js"></script>
Now you will get maximum WebRTC success across all devices.
window.getExternalIceServers
boolean variable tries to load STUN+TURN servers from xirsys.com. It isdisabled
by default.
Object.observe
has been removed since v3.2.95
. So you've to manually update-extra-data or set stream-end-handlers:
connection.extra.something = 'something';
connection.updateExtraData();
When attaching external streams:
connection.attachStreams.push(yourExternalStrea);
connection.setStreamEndHandler(yourExternalStrea);
Change userid using this method:
connection.changeUserId('your-new-userid');
<script src="https://cdn.WebRTC-Experiment.com/RecordRTC.js"></script>
<script>
var listOfRecorders = {};
connection.onstream = function(event) {
var recorder = RecordRTC(event.stream, {
type: 'video',
recorderType: MediaStreamRecorder
});
recorder.startRecording();
listOfRecorders[event.streamid] = recorder;
};
btnStopRecording.onclick = function() {
var streamid = prompt('Enter stream-id');
if(!listOfRecorders[streamid]) throw 'Wrong stream-id';
var recorder = listOfRecorders[streamid];
recorder.stopRecording(function() {
var blob = recorder.getBlob();
window.open( URL.createObjectURL(blob) );
// or upload to server
var formData = new FormData();
formData.append('file', blob);
$.post('/server-address', formData, serverCallback);
});
};
</script>
Wanna try a hack? You will be able to record entire tab + all audios.
First of all, install this Google Chrome extension:
Now, install last Google Chrome Canary. Remember, chrome version 53+.
Now open options page chrome://extensions/?options=ndcljioonkecdnaaihodjgiliohngojp
and enable this check-box:
Enable audio+tab recording?
Now click "R" icon to record any tab. Above chrome-extension will record entire tab activity along with all audios at once!!!
To repeat, audio+tab
recording option allows you record entire tab activity; all videos on tab, all audios on the tab, dashboards or any activity!
Again, above chrome extension requires Google Chrome version greater than or equal to 53.
connection.session = {
audio: true,
screen: true
};
connection.onstream = function(event) {
if(connection.attachStreams.length <= 1) return;
var screenStream, audioStream;
connection.attachStreams.forEach(function(stream) {
if(stream.isScreen) screenStream = true;
if(stream.isAudio) audioSTream = true;
});
if(!screenStream || !audioStream) return;
var audioPlusScreenStream = new MediaStream();
audioPlusScreenStream.addTrack( screenStream.getVideoTracks()[0] );
audioPlusScreenStream.addTrack( audioStream.getAudioTracks()[0] );
var recorder = RecordRTC(audioPlusScreenStream, {
type: 'video',
recorderType: MediaStreamRecorder
});
recorder.startRecording();
};
There are two possible methods:
- Share room-id as URL-hash
- Share room-id as URL-query-parameters
var roomid = 'xyz';
connection.open(roomid, function() {
var urlToShare = 'https://yourDomain.com/room.html#' + roomid;
// or second technique
var urlToShare = 'https://yourDomain.com/room.html?roomid=' + roomid;
window.open(urlToShare);
});
Now target users can read room-id as following:
if(location.hash.length > 1) {
var roomid = location.hash.replace('#', '');
// auto join room
connection.join(roomid);
}
Or read URL-query-parameters:
(function() {
var params = {},
r = /([^&=]+)=?([^&]*)/g;
function d(s) {
return decodeURIComponent(s.replace(/\+/g, ' '));
}
var match, search = window.location.search;
while (match = r.exec(search.substring(1)))
params[d(match[1])] = d(match[2]);
window.params = params;
})();
if(params.roomid) {
// auto join room
connection.join(params.roomid);
}
If you want to hide HTML for non-moderators or for users that are MERELY expected to join a room:
if(params.roomid || location.hash.length > 1) { // whatever condition suits you
$('.moderators-sections').hide();
// or simple javascript
Array.prototype.slice.call(document.querySelectorAll('.moderators-sections')).forEach(function(div) {
div.style.display = 'none';
// or
div.parentNode.removeChild(div);
});
}
PHP/ASPNET-MVC/Ruby developers can easily omit or remove those "redundant" HTML parts before serving the HTML to the browser.
Remember, both open, join, or openOrJoin
all these methods supports second-callback-parameter, which means that either you joined or opened the room. E.g. connection.open('roomid', successCallback);
RTCMultiConnection v2 users should check this wiki-page: https:/muaz-khan/RTCMultiConnection/wiki/Presence-Detection
v3 users should check this API (connection.checkPresence
):
v3 users can get list of existing public-rooms using this API (connection.getPublicModerators
):
However v2 users can use connection.onNewSession
event: https://www.rtcmulticonnection.org/docs/onNewSession/
- Getting Started guide for RTCMultiConnection
- Installation Guide
- How to Use?
- API Reference
- Upgrade from v2 to v3
- How to write iOS/Android applications?
- Tips & Tricks
RTCMultiConnection is released under MIT licence . Copyright (c) Muaz Khan.