@@ -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
0 commit comments