Skip to content

Commit 53f8557

Browse files
committed
Enable renegotation
No "perfect renegotiation" because that's too new and unsupported by browsers. Instead, a workaround by deferring adding the own offer: https://stackoverflow.com/questions/65059808/downward-compatibility-of-webrtc-renegotiation
1 parent f0774ad commit 53f8557

7 files changed

Lines changed: 209 additions & 40 deletions

File tree

coffee/gum.coffee

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ palava = @palava
55
class palava.Gum extends @EventEmitter
66
constructor: (config) ->
77
@config = config || { video: true, audio: true }
8-
@stream = null
8+
@stream = null # this stream switches from localStream to displayStream on request
9+
@localStream = null
10+
@displayStream = null
911

1012
changeConfig: (config) =>
1113
@config = config
@@ -17,16 +19,44 @@ class palava.Gum extends @EventEmitter
1719
@config
1820
).then(
1921
(stream) =>
22+
@localStream = stream.clone()
2023
@stream = stream
2124
@emit 'stream_ready', stream
2225
).catch(
2326
(error) =>
2427
@emit 'stream_error', error
2528
)
2629

30+
requestDisplaySharing: =>
31+
navigator.mediaDevices.getDisplayMedia(
32+
{video:true}
33+
).then(
34+
(stream) =>
35+
# add audio track to the display stream (if any)
36+
if @localStream.getAudioTracks().length > 0
37+
stream.addTrack(@localStream.getAudioTracks()[0], @localStream)
38+
@displayStream = stream.clone()
39+
@stream = stream
40+
@emit 'display_stream_ready', stream
41+
).catch(
42+
(error) =>
43+
@emit 'display_stream_error', error
44+
)
45+
46+
stopDisplaySharing: =>
47+
@stream = @localStream
48+
@emit 'display_stream_stop', @displayStream
49+
@displayStream = null
50+
2751
getStream: =>
2852
@stream
2953

54+
getLocalStream: =>
55+
@localStream
56+
57+
getDisplayStream: =>
58+
@displayStream
59+
3060
releaseStream: =>
3161
if @stream
3262
@stream.getAudioTracks().forEach( (track) => track.stop() )

coffee/local_peer.coffee

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ class palava.LocalPeer extends palava.Peer
3333
@emit 'stream_ready', e
3434
@userMedia.on 'stream_error', (e) =>
3535
@emit 'stream_error', e
36+
@userMedia.on 'display_stream_ready', (e) =>
37+
@emit 'display_stream_ready', e
38+
@userMedia.on 'display_stream_error', (e) =>
39+
@emit 'display_stream_error', e
3640
if @getStream()
3741
@ready = true
3842
@emit 'stream_ready'
@@ -54,6 +58,9 @@ class palava.LocalPeer extends palava.Peer
5458
getStream: =>
5559
@userMedia.getStream()
5660

61+
requestDisplaySharing: =>
62+
@userMedia.requestDisplaySharing()
63+
5764
# Updates the status of the local peer. The status is extended or updated with the given items.
5865
#
5966
# @param status [Object] Object containing the new items

coffee/remote_peer.coffee

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@ class palava.RemotePeer extends palava.Peer
2828

2929
@dataChannels = {}
3030

31+
@offers = offers
32+
@makingOffer = false
33+
@ignoreOffer = false
34+
@setRemoteAnswerPending = false
35+
3136
@setupRoom()
32-
@setupPeerConnection(offers)
3337
@setupDistributor()
34-
38+
@setupPeerConnection(offers)
3539
if offers
3640
@sendOffer()
3741

@@ -62,8 +66,7 @@ class palava.RemotePeer extends palava.Peer
6266
credential: @turnCredentials.password
6367
{iceServers: options}
6468

65-
# Sets up the peer connection and its events
66-
#
69+
# Sets up the peer connection and its events #
6770
# @nodoc
6871
#
6972
setupPeerConnection: (offers) =>
@@ -87,6 +90,9 @@ class palava.RemotePeer extends palava.Peer
8790
@ready = false
8891
@emit 'stream_removed'
8992

93+
@peerConnection.onnegotiationneeded = () =>
94+
@sendOffer()
95+
9096
@peerConnection.oniceconnectionstatechange = (event) =>
9197
connectionState = event.target.iceConnectionState
9298

@@ -107,12 +113,33 @@ class palava.RemotePeer extends palava.Peer
107113
@error = "connection_closed"
108114
@emit 'connection_closed'
109115

110-
# TODO onsignalingstatechange
111-
112116
if @room.localPeer.getStream()
113-
@peerConnection.addStream @room.localPeer.getStream()
114-
else
115-
# not suppored yet
117+
for track in @room.localPeer.getStream().getTracks()
118+
@peerConnection.addTrack(track, @room.localPeer.getStream())
119+
120+
@room.localPeer.on 'display_stream_ready', (stream) =>
121+
videoSender = @peerConnection.getSenders().find(
122+
(sender) => sender.track.kind == "video"
123+
)
124+
if videoSender
125+
# if there is a local video track then replace it because that's faster
126+
# and does not need renegotiation
127+
videoSender.replaceTrack(track)
128+
else
129+
@peerConnection.addTrack(stream.getVideoTracks()[0],
130+
@room.localPeer.getStream())
131+
132+
@room.localPeer.on 'display_stream_stop', (stream) =>
133+
localVideoTracks = @room.localPeer.getLocalStream().getVideoTracks()
134+
if localVideoTracks.length > 0
135+
# if there was a local video track then reuse the display video track
136+
# because it's faster and does not need renegotiation
137+
videoSender = @peerConnection.getSenders().find(
138+
(sender) => sender.track.kind == "video"
139+
)
140+
videoSender.replaceTrack(localVideoTracks[0])
141+
else
142+
@peerConnection.removeTrack(stream.getVideoTracks()[0])
116143

117144
# data channel setup
118145

@@ -140,8 +167,6 @@ class palava.RemotePeer extends palava.Peer
140167
# @nodoc
141168
#
142169
setupDistributor: =>
143-
# TODO _ in events also in rtc-server
144-
# TODO consistent protocol naming
145170
@distributor = new palava.Distributor(@room.channel, @id)
146171

147172
@distributor.on 'peer_left', (msg) =>
@@ -157,16 +182,22 @@ class palava.RemotePeer extends palava.Peer
157182
return if msg.candidate == ""
158183
candidate = new RTCIceCandidate({candidate: msg.candidate, sdpMLineIndex: msg.sdpmlineindex, sdpMid: msg.sdpmid})
159184
unless @room.options.filterIceCandidateTypes.includes(candidate.type)
160-
@peerConnection.addIceCandidate(candidate)
185+
await @peerConnection.addIceCandidate(candidate)
161186

162187
@distributor.on 'offer', (msg) =>
163-
@peerConnection.setRemoteDescription(new RTCSessionDescription(msg.sdp))
164-
@emit 'offer' # ignored so far
188+
# we sent an offer already and are the preferred offerer, so we don't back down
189+
return if @pendingOffer && @offers
190+
191+
# we backed down, so we drop the pending offer and choose the other peer's offer
192+
@pendingOffer = null
193+
194+
await @peerConnection.setRemoteDescription(new RTCSessionDescription(msg.sdp))
165195
@sendAnswer()
166196

167197
@distributor.on 'answer', (msg) =>
168-
@peerConnection.setRemoteDescription(new RTCSessionDescription(msg.sdp))
169-
@emit 'answer' # ignored so far
198+
await @peerConnection.setLocalDescription(@pendingOffer) if @pendingOffer
199+
@pendingOffer = null
200+
await @peerConnection.setRemoteDescription(new RTCSessionDescription(msg.sdp))
170201

171202
@distributor.on 'peer_updated_status', (msg) =>
172203
@status = msg.status
@@ -199,30 +230,32 @@ class palava.RemotePeer extends palava.Peer
199230
@on 'oaerror', (e) => @room.emit('peer_oaerror', @, e)
200231
@on 'channel_ready', (n, c) => @room.emit('peer_channel_ready', @, n, c)
201232

202-
# Sends the offer for a peer connection
203-
#
204-
# @nodoc
233+
sendMessage: (data) =>
234+
@distributor.send
235+
event: 'message'
236+
data: data
237+
238+
# Sends the offer to create a peer connection
205239
#
206240
sendOffer: =>
207-
@peerConnection.createOffer @sdpSender('offer'), @oaError, palava.browser.getConstraints()
241+
@peerConnection.createOffer @sdpSender('offer'), @oaError, palava.browser.getConstraints() if @peerConnection.signalingState == "stable" && !@pendingOffer
208242

209243
# Sends the answer to create a peer connection
210244
#
211245
sendAnswer: =>
212246
@peerConnection.createAnswer @sdpSender('answer'), @oaError, palava.browser.getConstraints()
213247

214-
sendMessage: (data) =>
215-
@distributor.send
216-
event: 'message'
217-
data: data
218248

219-
# Helper for sending sdp
249+
# Send offer/answer
220250
#
221251
# @nodoc
222252
#
223253
sdpSender: (event) =>
224254
(sdp) =>
225-
@peerConnection.setLocalDescription(sdp)
255+
if event == 'offer'
256+
@pendingOffer = sdp
257+
else
258+
await @peerConnection.setLocalDescription(sdp)
226259
@distributor.send
227260
event: event
228261
sdp: sdp

coffee/room.coffee

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class palava.Room extends @EventEmitter
8585

8686
@options.ownStatus[key] = status[key] for key in status
8787
@options.ownStatus.user_agent ||= palava.browser.getUserAgent()
88+
@options.ownStatus.user_agent_version ||= palava.browser.getUserAgentVersion()
8889

8990
@distributor.send
9091
event: 'join_room'

palava.bundle.js

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)