socket-signaler-client
Version:
Client for SocketIO WebRTC streaming webcam chatrooms
1 lines • 7.14 kB
JavaScript
!function(e,t){"use strict";"function"==typeof define&&define.amd?define(["https://cdnjs.cloudflare.com/ajax/libs/EventEmitter/4.2.11/EventEmitter.min.js","https://cdn.socket.io/socket.io-1.3.3.js"],function(e,n){return t(window,e,n)}):"object"==typeof exports?module.exports=t(window,require("wolfy87-eventemitter"),require("socket.io-client")):e.PeerConnectionClient=t(window,e.EventEmitter,e.io)}(this,function(e,t,n){"use strict";function i(t){this.peerConnections=[],this.constraints=navigator.mozGetUserMedia?{offerToReceiveAudio:!0,offerToReceiveVideo:!0}:{mandatory:{OfferToReceiveAudio:!0,OfferToReceiveVideo:!0}},this.iceServers={iceServers:[{url:"stun:stun.services.mozilla.com"},{url:"stun:stun.l.google.com:19302"}]},this.setupRTCObjects=function(){this.PeerConnection=e.RTCPeerConnection||e.mozRTCPeerConnection||e.webkitRTCPeerConnection,this.SessionDescription=e.RTCSessionDescription||e.mozRTCSessionDescription||e.webkitRTCSessionDescription,navigator.getUserMedia=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia,this.RTCIceCandidate=e.RTCIceCandidate||e.mozRTCIceCandidate},this.generateDefaults=function(t){return t=t||{},t.server=t.server||"http://"+e.location.host+"/",t.room=t.room||"default",t.debug=t.debug||!1,t},this.bindEvents=function(){this.socket.on("initialized",this.getPeerList.bind(this)),this.socket.on("list",this.generateConnections.bind(this)),this.socket.on("offer",this.createAnswer.bind(this)),this.socket.on("answer",this.handleAnswer.bind(this)),this.socket.on("icecandidate",this.receiveIceCandidate.bind(this)),this.socket.on("newconnection",this.addPeer.bind(this)),this.socket.on("disconnect",this.disconnectConnection.bind(this)),this.socket.on("peerconnected",this.peerConnected.bind(this)),this.socket.on("streamremoved",this.removeRemoteStream.bind(this))},this.getPeerList=function(){this.socket.emit("list")},this.generateConnections=function(e){t.debug&&console.log("Received list, creating connection(s) for "+e.length+" peers"),e.forEach(this.addPeer.bind(this))},this.addPeer=function(e,t){if(!this.hasPeer(e)){console.log("Adding peer: "+e);var n={connection:new this.PeerConnection(this.iceServers),id:e};return n=this.bindConnectionEvents(n,t),this.peerConnections.push(n),this.localStream&&this.addStreamToPeer(this.localStream,n),n}},this.bindConnectionEvents=function(e,n){return t.debug&&console.log("Binding connection events for peer: "+e.id),e.connection.onicecandidate=function(n){t.debug&&"verbose"===t.debug&&console.log("Sending ICE candidate to "+e.id),t.debug&&"verbose"===t.debug&&console.log("Full event ",n),t.debug&&"verbose"===t.debug&&console.log("Stringified event ",JSON.stringify(n)),console.log(Object.keys(n)),n.candidate&&this.socket.emit("icecandidate",{target:e.id,candidate:n.candidate})}.bind(this),e.connection.onaddstream=function(i){t.debug&&console.log("Remote stream added from "+e.id),n?t.debug&&console.log("onaddstream event suppressed"):this.emit("remoteStreamAdded",i.stream,e.id)}.bind(this),e.connection.ondatachannel=function(n){t.debug&&console.log("Data channel added from "+e.id),this.emit("dataChannelAdded",n.channel,e.id)}.bind(this),e.connection.oniceconnectionstatechange=function(){switch(e.connection.iceConnectionState){case"disconnected":case"failed":this.logError("iceConnectionState is disconnected, closing connections to "+e.id),e.connection.close();break;case"completed":e.connection.onicecandidate=function(){}}}.bind(this),e},this.createOffer=function(e){t.debug&&console.log("Creating offer for: "+e.id),e.connection.createOffer(function(t){e.connection.setLocalDescription(new this.SessionDescription(t),this.sendOffer({target:e.id,offer:t}),this.logError)}.bind(this),this.logError,this.constraints)},this.sendOffer=function(e){t.debug&&console.log("Sending offer to "+e.target),this.socket.emit("offer",e)},this.createAnswer=function(e){var n=this.getPeer(e.sender),i=e.offer;t.debug&&console.log("Creating answer for "+n.id),n.connection.setRemoteDescription(new this.SessionDescription(i),function(){n.connection.createAnswer(function(e){n.connection.setLocalDescription(new this.SessionDescription(e),this.sendAnswer({target:n.id,answer:e}),this.logError)}.bind(this),this.logError,this.constraints)}.bind(this),this.logError)},this.sendAnswer=function(e){t.debug&&console.log("Sent answer to peer: "+e.target),this.socket.emit("answer",e)},this.handleAnswer=function(e){var n=this.getPeer(e.sender),i=e.answer;t.debug&&console.log("Handling answer from: "+n.id),n.connection.setRemoteDescription(new this.SessionDescription(i),function(){this.peerConnected(n.id),this.socket.emit("peerconnected",n.id)}.bind(this),this.logError)},this.peerConnected=function(e){this.emit("peerconnected",e),t.debug&&console.log("Signaling with peer: "+e)},this.disconnectConnection=function(e){var n=this.getPeer(e);n.connection.close(),this.emit("peerDisconnected",e),this.emit("remoteStreamRemoved",e),t.debug&&console.log("Disconnected with peer: "+e),this.peerConnections.forEach(function(t,n,i){t.id===e&&i.splice(n,1)})},this.getPeer=function(e){var t;return this.peerConnections.forEach(function(n){n.id===e&&(t=n)}),t||(t=this.addPeer(e)),t},this.hasPeer=function(e){var t=!1;return this.peerConnections.forEach(function(n){n.id===e&&(t=!0)}),t},this.logError=function(e){console.error(t.debug?e:"There was an error with the signaller")},this.addStream=function(e){this.peerConnections.forEach(function(t){this.addStreamToPeer(e,t)}.bind(this))},this.addStreamToPeer=function(e,n){t.debug&&console.log("Stream added to "+n.id),n.connection.addStream(e),this.createOffer(n)},this.addLocalStream=function(e){e=e||{},navigator.getUserMedia({audio:e.audio||!0,video:e.video||!0},function(e){this.localStream=e,this.addStream(e),this.emit("localStreamAdded",e),t.debug&&console.log("Local stream added")}.bind(this),this.logError)},this.removeLocalStream=function(){this.localStream.stop(),this.localStream=void 0,this.peerConnections.forEach(function(e){t.debug&&console.log("Local stream removed from "+e.id),this.socket.emit("streamremoved",e.id),this.regenStream(e,!0)}.bind(this)),this.emit("localStreamRemoved")},this.removeRemoteStream=function(e){this.emit("remoteStreamRemoved",e),t.debug&&console.log("Removing stream from: "+e),this.regenStream(this.getPeer(e))},this.regenStream=function(e,n){t.debug&&console.log("Regenerating PeerConnection for "+e.id),n=n&&e.connection.getRemoteStreams().length,e.connection=new this.PeerConnection(this.iceServers),this.bindConnectionEvents(e,n),this.localStream&&this.addStreamToPeer(this.localStream,e)},this.receiveIceCandidate=function(e){if(t.debug&&"verbose"===t.debug&&console.log("Received candidate",e.candidate),e.candidate.candidate){var n=this.getPeer(e.sender),i=e.candidate.candidate,o=e.candidate.sdpMLineIndex;t.debug&&"verbose"===t.debug&&console.log("Added ICE candidate from "+n.id),n.connection.addIceCandidate(new this.RTCIceCandidate({candidate:i,sdpMLineIndex:o}))}},this.setupRTCObjects(),t=this.generateDefaults(t),this.socket=n(t.server+t.room),this.bindEvents()}return i.prototype=new t,i});