diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2020-03-29 14:35:47 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2020-04-29 17:51:19 +0200 |
commit | 3544203a6b644eb8a619897c6da03c49a5d114cd (patch) | |
tree | 8da547659002459776813414706872ed4f14c0a5 | |
parent | 923cd9b5f1868d03a2cd7239aa1ec973150a9b51 (diff) |
Forward ICE messages across communication channel
This also allows adding streams.
-rw-r--r-- | src/webchat.js | 19 | ||||
-rw-r--r-- | src/webrtc.js | 46 |
2 files changed, 54 insertions, 11 deletions
diff --git a/src/webchat.js b/src/webchat.js index c8b6f0e..34701f2 100644 --- a/src/webchat.js +++ b/src/webchat.js @@ -136,15 +136,6 @@ $(document).ready(function () { }) }, 500) - navigator.mediaDevices.getUserMedia({audio: true, video: true}) - .then(stream => { - console.log('Got MediaStream:', stream) - showStream($('#me')[0], stream) - }) - .catch(error => { - alert('Error accessing media devices: ' + error) - }) - var server = new Server() server.ready(function () { var webrtc = new WebRTC(server) @@ -160,6 +151,16 @@ $(document).ready(function () { } }) + navigator.mediaDevices.getUserMedia({audio: true, video: true}) + .then(stream => { + console.log('Got MediaStream:', stream) + showStream($('#me')[0], stream) + webrtc.addStream(stream) + }) + .catch(error => { + alert('Error accessing media devices: ' + error) + }) + $('#message-input').submit(function (event) { var message = $(this).find('input').val() if (message) { diff --git a/src/webrtc.js b/src/webrtc.js index 312afa3..6c31476 100644 --- a/src/webrtc.js +++ b/src/webrtc.js @@ -4,6 +4,7 @@ class WebRTC { this.configuration = {iceServers: [{urls: 'stun:stun.l.google.com:19302'}]} this.server = server this.peerConnections = {} + this.streams = [] // generate an identity identifier const numbers = window.crypto.getRandomValues(new Uint8Array(4)) const symbols = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('') @@ -12,9 +13,46 @@ class WebRTC { server.sendMessage({announce: true, sender: this.identity}) } + addStream(stream) { + this.streams.push(stream) + // register stream with existing connections + Object.keys(this.peerConnections).forEach(identity => { + const peerConnection = this.peerConnections[identity] + stream.getTracks().forEach(track => { this._addTrack(peerConnection, track, stream) }) + }) + } + + _addTrack(peerConnection, track, stream) { + // send the track over the peer connection + peerConnection.addTrack(track, stream) + } + getPeerConnection(identity) { - if (!(identity in this.peerConnections)) { - const peerConnection = new RTCPeerConnection(this.configuration) + const self = this + if (!(identity in self.peerConnections)) { + const peerConnection = new RTCPeerConnection(self.configuration) + // handle connection state changes + peerConnection.addEventListener('connectionstatechange', event => { + }) + // set up event handler to handled incoming tracks + peerConnection.addEventListener('track', event => { + }) + // support delivering messages through the control channel for ICE + peerConnection.addEventListener('icecandidate', event => { + self.server.sendMessage({icecandidate: event.candidate, sender: self.identity, receipient: identity}) + }) + // re-send the offer if renegotiation is needed + peerConnection.addEventListener('negotiationneeded', event => { + peerConnection.createOffer().then(offer => { + peerConnection.setLocalDescription(offer).then(x => { + self.server.sendMessage({offer: offer, sender: self.identity, receipient: identity}) + }) + }) + }) + // add any existing streams to the connection + this.streams.forEach(stream => { + stream.getTracks().forEach(track => { this._addTrack(peerConnection, track, stream) }) + }) this.peerConnections[identity] = peerConnection } return this.peerConnections[identity] @@ -46,6 +84,10 @@ class WebRTC { // handle answers to offers peerConnection = self.getPeerConnection(msg.sender) peerConnection.setRemoteDescription(new RTCSessionDescription(msg.answer)).then(x => {}) + } else if ('icecandidate' in msg && msg.receipient === self.identity && msg.sender in self.peerConnections) { + // handle ICE candidate messages + peerConnection = self.getPeerConnection(msg.sender) + peerConnection.addIceCandidate(msg.icecandidate) } } } |