Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2020-03-29 14:35:47 +0200
committerArthur de Jong <arthur@arthurdejong.org>2020-04-29 17:51:19 +0200
commit3544203a6b644eb8a619897c6da03c49a5d114cd (patch)
tree8da547659002459776813414706872ed4f14c0a5
parent923cd9b5f1868d03a2cd7239aa1ec973150a9b51 (diff)
Forward ICE messages across communication channel
This also allows adding streams.
-rw-r--r--src/webchat.js19
-rw-r--r--src/webrtc.js46
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)
}
}
}