@@ -62,8 +62,10 @@ public class RTCBandwidth: NSObject {
6262 }
6363 }
6464
65+ /// Disconnect from Bandwidth's WebRTC signaling server and remove all local connections.
6566 public func disconnect( ) {
6667 signaling? . disconnect ( )
68+ localConnections. removeAll ( )
6769 }
6870
6971 public func publish( audio: Bool , video: Bool , alias: String ? , completion: @escaping ( ) -> Void ) {
@@ -155,22 +157,60 @@ public class RTCBandwidth: NSObject {
155157 }
156158
157159 #if os(iOS)
158- public func setSpeaker( _ speaker: Bool ) {
160+ /// Determine whether the device's speaker should be in an enabled state.
161+ ///
162+ /// - Parameter isEnabled: A Boolean value indicating whether the device's speaker is in the enabled state.
163+ public func setSpeaker( _ isEnabled: Bool ) {
159164 audioQueue. async {
160165 defer {
161166 RTCAudioSession . sharedInstance ( ) . unlockForConfiguration ( )
162167 }
163168
164169 RTCAudioSession . sharedInstance ( ) . lockForConfiguration ( )
165170 do {
166- try RTCAudioSession . sharedInstance ( ) . overrideOutputAudioPort ( speaker ? . speaker : . none)
171+ try RTCAudioSession . sharedInstance ( ) . overrideOutputAudioPort ( isEnabled ? . speaker : . none)
167172 } catch {
168173 debugPrint ( error. localizedDescription)
169174 }
170175 }
171176 }
172177 #endif
173178
179+ /// Determine whether the local connection's audio should be in an enabled state. When `endpointId` is nil audio state will be set for all local connections.
180+ ///
181+ /// - Parameter endpointId: The endpoint id for the local connection.
182+ /// - Parameter isEnabled: A Boolean value indicating whether the audio is in the enabled state.
183+ public func setAudio( _ endpointId: String ? = nil , isEnabled: Bool ) {
184+ setTrack ( RTCAudioTrack . self, endpointId: endpointId, isEnabled: isEnabled)
185+ }
186+
187+ /// Determine whether the local connection's video should be in an enabled state. When `endpointId` is nil video state will be set for all local connections.
188+ ///
189+ /// - Parameter endpointId: The endpoint id for the local connection.
190+ /// - Parameter isEnabled: A Boolean value indicating whether the video is in the enabled state.
191+ public func setVideo( _ endpointId: String ? = nil , isEnabled: Bool ) {
192+ setTrack ( RTCVideoTrack . self, endpointId: endpointId, isEnabled: isEnabled)
193+ }
194+
195+ private func setTrack< T: RTCMediaStreamTrack > ( _ type: T . Type , endpointId: String ? , isEnabled: Bool ) {
196+ if let endpointId = endpointId {
197+ localConnections
198+ . filter { $0. endpointId == endpointId }
199+ . compactMap { $0. peerConnection }
200+ . forEach { setTrack ( T . self, peerConnection: $0, isEnabled: isEnabled) }
201+ } else {
202+ localConnections
203+ . compactMap { $0. peerConnection }
204+ . forEach { setTrack ( T . self, peerConnection: $0, isEnabled: isEnabled) }
205+ }
206+ }
207+
208+ private func setTrack< T: RTCMediaStreamTrack > ( _ type: T . Type , peerConnection: RTCPeerConnection , isEnabled: Bool ) {
209+ peerConnection. transceivers
210+ . compactMap { $0. sender. track as? T }
211+ . forEach { $0. isEnabled = isEnabled }
212+ }
213+
174214 private func createMediaSenders( peerConnection: RTCPeerConnection , audio: Bool , video: Bool ) {
175215 let streamId = " stream "
176216
@@ -226,39 +266,35 @@ public class RTCBandwidth: NSObject {
226266 let constraints = RTCMediaConstraints ( mandatoryConstraints: mandatoryConstraints, optionalConstraints: nil )
227267
228268 peerConnection. offer ( for: constraints) { offer, error in
229- // DispatchQueue.main.async {
230- if let error = error {
231- print ( error. localizedDescription)
232- }
233-
234- guard let offer = offer else {
269+ if let error = error {
270+ print ( error. localizedDescription)
271+ }
272+
273+ guard let offer = offer else {
274+ return
275+ }
276+
277+ self . signaling? . offer ( endpointId: endpointId, sdp: offer. sdp) { result in
278+ guard let result = result else {
235279 return
236280 }
237-
238- self . signaling ? . offer ( endpointId : endpointId , sdp : offer. sdp ) { result in
239- guard let result = result else {
240- return
281+
282+ peerConnection . setLocalDescription ( offer) { error in
283+ if let error = error {
284+ debugPrint ( error . localizedDescription )
241285 }
242-
243- peerConnection. setLocalDescription ( offer) { error in
244- // DispatchQueue.main.async {
245- if let error = error {
246- debugPrint ( error. localizedDescription)
247- }
248-
249- let sdp = RTCSessionDescription ( type: . answer, sdp: result. sdpAnswer)
250-
251- peerConnection. setRemoteDescription ( sdp) { error in
252- if let error = error {
253- debugPrint ( error. localizedDescription)
254- }
255-
256- completion ( )
257- }
258- // }
286+
287+ let sdp = RTCSessionDescription ( type: . answer, sdp: result. sdpAnswer)
288+
289+ peerConnection. setRemoteDescription ( sdp) { error in
290+ if let error = error {
291+ debugPrint ( error. localizedDescription)
292+ }
293+
294+ completion ( )
259295 }
260296 }
261- // }
297+ }
262298 }
263299 }
264300
@@ -294,10 +330,6 @@ public class RTCBandwidth: NSObject {
294330
295331 connection. peerConnection. add ( candidate)
296332 }
297-
298- private func endpointRemoved( with endpointId: String ) {
299- delegate? . bandwidth ( self , streamUnavailableAt: endpointId)
300- }
301333}
302334
303335extension RTCBandwidth : RTCPeerConnectionDelegate {
@@ -324,12 +356,14 @@ extension RTCBandwidth: RTCPeerConnectionDelegate {
324356 debugPrint ( " peerConnection didChange stateChanged: \( stateChanged) " )
325357 }
326358
359+ @available ( * , deprecated)
327360 public func peerConnection( _ peerConnection: RTCPeerConnection , didAdd stream: RTCMediaStream ) {
328- debugPrint ( " peerConnection didAdd stream: RTCMediaStream " )
361+
329362 }
330363
364+ @available ( * , deprecated)
331365 public func peerConnection( _ peerConnection: RTCPeerConnection , didRemove stream: RTCMediaStream ) {
332- debugPrint ( " peerConnection didRemove stream: RTCMediaStream " )
366+
333367 }
334368
335369 public func peerConnection( _ peerConnection: RTCPeerConnection , didChange newState: RTCIceConnectionState ) {
@@ -361,11 +395,14 @@ extension RTCBandwidth: RTCPeerConnectionDelegate {
361395 print ( " peerConnection didChange newState: \( newState) " )
362396
363397 if [ . disconnected, . failed] . contains ( newState) {
364- guard let remoteConnection = remoteConnections. first ( where: { $0. peerConnection == peerConnection } ) else {
398+ guard let index = remoteConnections. firstIndex ( where: { $0. peerConnection == peerConnection } ) else {
365399 return
366400 }
367-
368- delegate? . bandwidth ( self , streamUnavailableAt: remoteConnection. endpointId)
401+
402+ delegate? . bandwidth ( self , streamUnavailableAt: remoteConnections [ index] . endpointId)
403+
404+ remoteConnections [ index] . peerConnection. close ( )
405+ remoteConnections. remove ( at: index)
369406 }
370407 }
371408
@@ -388,6 +425,6 @@ extension RTCBandwidth: SignalingDelegate {
388425 }
389426
390427 func signaling( _ signaling: Signaling , didReceiveEndpointRemoved parameters: EndpointRemovedParameters ) {
391- endpointRemoved ( with : parameters. endpointId)
428+ delegate ? . bandwidth ( self , streamUnavailableAt : parameters. endpointId)
392429 }
393430}
0 commit comments