Skip to content

Commit

Permalink
Fixed Firefox issues for Scalable-Broadcast demo #88
Browse files Browse the repository at this point in the history
1) Firefox can NOT record remote-VIDEO-stream
2) Firefox can NOT removeStream
3) Firefox can NOT use replaceTrack for remoteMediaStream

So if any of the middle peer leaves, Firefox is no where. The only
solution for Firefox in such situation is “rejoin”.
  • Loading branch information
muaz-khan committed Feb 13, 2016
1 parent 3a6bc2c commit 05326ca
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 118 deletions.
58 changes: 28 additions & 30 deletions RTCMultiConnection.js
@@ -1,4 +1,4 @@
// Last time updated: 2016-02-11 6:44:44 AM UTC
// Last time updated: 2016-02-13 7:21:53 AM UTC

// ______________________________
// RTCMultiConnection-v3.0 (Beta)
Expand Down Expand Up @@ -277,8 +277,10 @@
} catch (e) {}
}

connection.peers[remoteUserId].peer = null;
delete connection.peers[remoteUserId];
if (connection.peers[remoteUserId]) {
connection.peers[remoteUserId].peer = null;
delete connection.peers[remoteUserId];
}
}

if (connection.broadcasters.indexOf(remoteUserId) !== -1) {
Expand All @@ -289,7 +291,6 @@
}
});
connection.broadcasters = newArray;

keepNextBroadcasterOnServer();
}
}
Expand Down Expand Up @@ -950,7 +951,7 @@
session = session || {};

if (!RTCPeerConnection.prototype.getSenders) {
this.addStream(session);
connection.addStream(session);
return;
}

Expand All @@ -960,7 +961,13 @@
}

if (session instanceof MediaStream) {
replaceTrack(session.getVideoTracks()[0], remoteUserId, isVideoTrack);
if (session.getVideoTracks().length) {
replaceTrack(session.getVideoTracks()[0], remoteUserId, true);
}

if (session.getAudioTracks().length) {
replaceTrack(session.getAudioTracks()[0], remoteUserId, false);
}
return;
}

Expand Down Expand Up @@ -1798,21 +1805,15 @@

return {
streamsToShare: userPreferences.streamsToShare || {},
session: connection.session,
rtcMultiConnection: connection,
connectionDescription: userPreferences.connectionDescription,
remoteUserId: remoteUserId,
localPeerSdpConstraints: userPreferences.localPeerSdpConstraints,
remotePeerSdpConstraints: userPreferences.remotePeerSdpConstraints,
dontGetRemoteStream: !!userPreferences.dontGetRemoteStream,
dontAttachLocalStream: !!userPreferences.dontAttachLocalStream,
optionalArgument: connection.optionalArgument,
iceServers: connection.iceServers,
renegotiatingPeer: !!userPreferences.renegotiatingPeer,
peerRef: userPreferences.peerRef,
enableDataChannels: !!connection.session.data,
localStreams: connection.attachStreams,
removeStreams: connection.removeStreams,
onLocalSdp: function(localSdp) {
self.onNegotiationNeeded(localSdp, remoteUserId);
},
Expand Down Expand Up @@ -1867,12 +1868,11 @@

if (isPluginRTC) {
var mediaElement = document.createElement('video');
var body = (document.body || document.documentElement);
var body = connection.videosContainer;
body.insertBefore(mediaElement, body.firstChild);

setTimeout(function() {
Plugin.attachMediaStream(mediaElement, stream);

self.onGettingRemoteMedia(mediaElement, remoteUserId);
}, 3000);
return;
Expand All @@ -1898,10 +1898,7 @@
self.onUserLeft(remoteUserId);
self.disconnectWith(remoteUserId);
}
},
processSdp: connection.processSdp,
beforeAddingStream: connection.beforeAddingStream,
beforeRemovingStream: connection.beforeRemovingStream
}
};
};

Expand Down Expand Up @@ -2192,7 +2189,6 @@
}

connection.peers[remoteUserId].channels.push(channel);

connection.onopen({
userid: remoteUserId,
extra: connection.peers[remoteUserId] ? connection.peers[remoteUserId].extra : {},
Expand Down Expand Up @@ -2502,6 +2498,7 @@

function observeObject(obj, callback) {
if (!Object.observe) return;
if (isMobileDevice) return;

Object.observe(obj, function(changes) {
var jsonStringified = JSON.stringify(changes);
Expand Down Expand Up @@ -2815,15 +2812,15 @@
}

var localStreams = [];
config.localStreams.forEach(function(stream) {
connection.attachStreams.forEach(function(stream) {
if (!!stream) localStreams.push(stream);
});

if (!renegotiatingPeer) {
peer = new RTCPeerConnection(navigator.onLine ? {
iceServers: config.iceServers,
iceServers: connection.iceServers,
iceTransports: 'all'
} : null, config.optionalArgument);
} : null, connection.optionalArgument);
} else {
peer = config.peerRef;

Expand All @@ -2834,9 +2831,9 @@
}
});

config.removeStreams.forEach(function(streamToRemove, index) {
connection.removeStreams.forEach(function(streamToRemove, index) {
if (stream === streamToRemove) {
stream = config.beforeRemovingStream(stream);
stream = connection.beforeRemovingStream(stream);
if (stream && !!peer.removeStream) {
peer.removeStream(stream);
}
Expand Down Expand Up @@ -2881,7 +2878,7 @@
return;
}

localStream = config.beforeAddingStream(localStream);
localStream = connection.beforeAddingStream(localStream);
if (localStream) {
peer.addStream(localStream);
}
Expand Down Expand Up @@ -2957,6 +2954,7 @@
};

this.addRemoteSdp = function(remoteSdp) {
remoteSdp.sdp = connection.processSdp(remoteSdp.sdp);
peer.setRemoteDescription(new RTCSessionDescription(remoteSdp), function() {}, function(error) {
if (!!connection.enableLogs) {
console.error(JSON.stringify(error, null, '\t'));
Expand All @@ -2970,7 +2968,7 @@
isOfferer = false;
}

if (config.enableDataChannels === true) {
if (connection.session.data === true) {
createDataChannel();
}

Expand Down Expand Up @@ -3027,10 +3025,10 @@
peer.channel = channel;
}

if (config.session.audio == 'two-way' || config.session.video == 'two-way' || config.session.screen == 'two-way') {
if (connection.session.audio == 'two-way' || connection.session.video == 'two-way' || connection.session.screen == 'two-way') {
defaults.sdpConstraints = setSdpConstraints({
OfferToReceiveAudio: config.session.audio == 'two-way' || (config.remoteSdp && config.remoteSdp.remotePeerSdpConstraints && config.remoteSdp.remotePeerSdpConstraints.OfferToReceiveAudio),
OfferToReceiveVideo: config.session.video == 'two-way' || config.session.screen == 'two-way' || (config.remoteSdp && config.remoteSdp.remotePeerSdpConstraints && config.remoteSdp.remotePeerSdpConstraints.OfferToReceiveAudio)
OfferToReceiveAudio: connection.session.audio == 'two-way' || (config.remoteSdp && config.remoteSdp.remotePeerSdpConstraints && config.remoteSdp.remotePeerSdpConstraints.OfferToReceiveAudio),
OfferToReceiveVideo: connection.session.video == 'two-way' || connection.session.screen == 'two-way' || (config.remoteSdp && config.remoteSdp.remotePeerSdpConstraints && config.remoteSdp.remotePeerSdpConstraints.OfferToReceiveAudio)
});
}

Expand All @@ -3044,7 +3042,7 @@
});

peer[isOfferer ? 'createOffer' : 'createAnswer'](function(localSdp) {
localSdp.sdp = config.processSdp(localSdp.sdp);
localSdp.sdp = connection.processSdp(localSdp.sdp);
peer.setLocalDescription(localSdp);
config.onLocalSdp({
type: localSdp.type,
Expand Down
10 changes: 5 additions & 5 deletions RTCMultiConnection.min.js

Large diffs are not rendered by default.

57 changes: 42 additions & 15 deletions demos/Scalable-Broadcast.html
Expand Up @@ -5,7 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">

<link rel="stylesheet" href="https://cdn.webrtc-experiment.com/style.css">
<link rel="stylesheet" href="https://cdn.webrtc-experiment.com/style.css">

<title>WebRTC Scalable Media Broadcast using RTCMultiConnection</title>

Expand Down Expand Up @@ -159,6 +159,8 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal

// this event is emitted when a broadcast is already created.
socket.on('join-broadcaster', function(hintsToJoinBroadcast) {
console.log('join-broadcaster', hintsToJoinBroadcast);

connection.session = hintsToJoinBroadcast.typeOfStreams;
connection.sdpConstraints.mandatory = {
OfferToReceiveVideo: !!connection.session.video,
Expand All @@ -168,6 +170,8 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal
});

socket.on('rejoin-broadcast', function(broadcastId) {
console.log('rejoin-broadcast', broadcastId);

connection.attachStreams = [];
socket.emit('check-broadcast-presence', broadcastId, function(isBroadcastExists) {
if(!isBroadcastExists) {
Expand All @@ -192,6 +196,8 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal

// this event is emitted when a broadcast is absent.
socket.on('start-broadcasting', function(typeOfStreams) {
console.log('start-broadcasting', typeOfStreams);

// host i.e. sender should always use this!
connection.sdpConstraints.mandatory = {
OfferToReceiveVideo: false,
Expand Down Expand Up @@ -234,8 +240,6 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal
}

if (connection.isInitiator == false && event.type === 'remote') {
repeatedlyRecordStream(event.stream);

// he is merely relaying the media
connection.dontCaptureUserMedia = true;
connection.attachStreams = [event.stream];
Expand All @@ -247,18 +251,39 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal
var socket = connection.getSocket();
socket.emit('can-relay-broadcast');

connection.getAllParticipants().forEach(function(p) {
if(p + '' != event.userid + '') {
var peer = connection.peers[p].peer;
peer.getLocalStreams().forEach(function(localStream) {
peer.removeStream(localStream);
});
peer.addStream(event.stream);
connection.dontAttachStream = true;
connection.renegotiate(p);
connection.dontAttachStream = false;
}
});
if(connection.DetectRTC.browser.name === 'Chrome') {
connection.getAllParticipants().forEach(function(p) {
if(p + '' != event.userid + '') {
var peer = connection.peers[p].peer;
peer.getLocalStreams().forEach(function(localStream) {
peer.removeStream(localStream);
});
peer.addStream(event.stream);
connection.dontAttachStream = true;
connection.renegotiate(p);
connection.dontAttachStream = false;
}
});
}

if(connection.DetectRTC.browser.name === 'Firefox') {
// Firefox is NOT supporting removeStream method
// that's why using alternative hack.
// NOTE: Firefox seems unable to replace-tracks of the remote-media-stream
// need to ask all deeper nodes to rejoin
connection.getAllParticipants().forEach(function(p) {
if(p + '' != event.userid + '') {
connection.replaceTrack(event.stream, p);
}
});
}

// Firefox is UN_UN_UABLE to record remote MediaStream
// WebAudio solution merely records audio
// so recording MUST_MUST be skipped for Firefox.
if(connection.DetectRTC.browser.name === 'Chrome') {
repeatedlyRecordStream(event.stream);
}
}
};

Expand Down Expand Up @@ -289,6 +314,8 @@ <h1><a href="https://github.com/muaz-khan/WebRTC-Scalable-Broadcast">WebRTC Scal
connection.userid = broadcastId;
}

console.log('check-broadcast-presence', broadcastId, isBroadcastExists);

socket.emit('join-broadcast', {
broadcastId: broadcastId,
userid: connection.userid,
Expand Down
13 changes: 11 additions & 2 deletions demos/addStream-in-Chat-room.html
Expand Up @@ -158,7 +158,16 @@ <h1>addStream in a Chat Room using RTCMultiConnection-v3.0</h1>

connection.enableFileSharing = true; // by default, it is "false".

connection.attachStreams.push(new webkitMediaStream());
if(typeof webkitMediaStream !== 'undefined') {
connection.attachStreams.push(new webkitMediaStream());
}
else if(typeof MediaStream !== 'undefined'){
connection.attachStreams.push(new MediaStream());
}
else {
console.error('Neither Chrome nor Firefox. This demo may NOT work.');
}

connection.dontCaptureUserMedia = true;
connection.session = {
data: true,
Expand All @@ -185,7 +194,7 @@ <h1>addStream in a Chat Room using RTCMultiConnection-v3.0</h1>
connection.onopen = function() {
if(connection.alreadyOpened) return;
connection.alreadyOpened = true;

document.getElementById('share-file').disabled = false;
document.getElementById('input-text-chat').disabled = false;
document.getElementById('btn-addStream').disabled = false;
Expand Down
2 changes: 1 addition & 1 deletion demos/index.html
Expand Up @@ -44,7 +44,7 @@ <h2><a href="#demos">RTCMultiConnection-v3.0 Demos</a></h2>
</li>

<li>
<a href="/demos/Scalable-Broadcast.html">All-in-One scalable broadcasting demo</a>
<a href="/demos/Scalable-Broadcast.html">Scalable Media Broadcast over Unlimited users!</a>
</li>

<li>
Expand Down
15 changes: 2 additions & 13 deletions dev/MultiPeersHandler.js
Expand Up @@ -86,21 +86,15 @@ function MultiPeers(connection) {

return {
streamsToShare: userPreferences.streamsToShare || {},
session: connection.session,
rtcMultiConnection: connection,
connectionDescription: userPreferences.connectionDescription,
remoteUserId: remoteUserId,
localPeerSdpConstraints: userPreferences.localPeerSdpConstraints,
remotePeerSdpConstraints: userPreferences.remotePeerSdpConstraints,
dontGetRemoteStream: !!userPreferences.dontGetRemoteStream,
dontAttachLocalStream: !!userPreferences.dontAttachLocalStream,
optionalArgument: connection.optionalArgument,
iceServers: connection.iceServers,
renegotiatingPeer: !!userPreferences.renegotiatingPeer,
peerRef: userPreferences.peerRef,
enableDataChannels: !!connection.session.data,
localStreams: connection.attachStreams,
removeStreams: connection.removeStreams,
onLocalSdp: function(localSdp) {
self.onNegotiationNeeded(localSdp, remoteUserId);
},
Expand Down Expand Up @@ -155,12 +149,11 @@ function MultiPeers(connection) {

if (isPluginRTC) {
var mediaElement = document.createElement('video');
var body = (document.body || document.documentElement);
var body = connection.videosContainer;
body.insertBefore(mediaElement, body.firstChild);

setTimeout(function() {
Plugin.attachMediaStream(mediaElement, stream);

self.onGettingRemoteMedia(mediaElement, remoteUserId);
}, 3000);
return;
Expand All @@ -186,10 +179,7 @@ function MultiPeers(connection) {
self.onUserLeft(remoteUserId);
self.disconnectWith(remoteUserId);
}
},
processSdp: connection.processSdp,
beforeAddingStream: connection.beforeAddingStream,
beforeRemovingStream: connection.beforeRemovingStream
}
};
};

Expand Down Expand Up @@ -480,7 +470,6 @@ function MultiPeers(connection) {
}

connection.peers[remoteUserId].channels.push(channel);

connection.onopen({
userid: remoteUserId,
extra: connection.peers[remoteUserId] ? connection.peers[remoteUserId].extra : {},
Expand Down

0 comments on commit 05326ca

Please sign in to comment.