From b893019f1ba3cca4405ece3f56b00cddbe2d3693 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Wed, 20 Jan 2021 12:59:12 -0500 Subject: [PATCH 01/15] Use concrete type for media types and update stream available --- Sources/BandwidthWebRTC/RTCBandwidth.swift | 26 +++++++++++++------ .../RTCBandwidthConnection.swift | 4 ++- .../RPC/RequestToPublishResult.swift | 2 +- .../Signaling/RPC/SDPNeededParameters.swift | 2 +- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Sources/BandwidthWebRTC/RTCBandwidth.swift b/Sources/BandwidthWebRTC/RTCBandwidth.swift index 2e32193..5f83d45 100644 --- a/Sources/BandwidthWebRTC/RTCBandwidth.swift +++ b/Sources/BandwidthWebRTC/RTCBandwidth.swift @@ -9,7 +9,7 @@ import Foundation import WebRTC public protocol RTCBandwidthDelegate { - func bandwidth(_ bandwidth: RTCBandwidth, streamAvailableAt connection: RTCBandwidthConnection, stream: RTCMediaStream?) + func bandwidth(_ bandwidth: RTCBandwidth, streamAvailableAt endpointId: String, mediaTypes: [MediaType], mediaStream: RTCMediaStream?, alias: String?, participantId: String?) func bandwidth(_ bandwidth: RTCBandwidth, streamUnavailableAt endpointId: String) } @@ -84,7 +84,7 @@ public class RTCBandwidth: NSObject { self.createMediaSenders(peerConnection: peerConnection, audio: audio, video: video) - let localConnection = RTCBandwidthConnection(endpointId: result.endpointId, peerConnection: peerConnection, alias: alias, participantId: nil) + let localConnection = RTCBandwidthConnection(endpointId: result.endpointId, peerConnection: peerConnection, mediaTypes: mediaTypes, alias: alias, participantId: nil) self.localConnections.append(localConnection) self.negotiateSDP(endpointId: result.endpointId, direction: result.direction, mediaTypes: result.mediaTypes, for: peerConnection) { @@ -197,7 +197,7 @@ public class RTCBandwidth: NSObject { return videoTrack } - private func negotiateSDP(endpointId: String, direction: String, mediaTypes: [String], for peerConnection: RTCPeerConnection, completion: @escaping () -> Void) { + private func negotiateSDP(endpointId: String, direction: String, mediaTypes: [MediaType], for peerConnection: RTCPeerConnection, completion: @escaping () -> Void) { debugPrint(direction) var mandatoryConstraints = [ @@ -206,8 +206,8 @@ public class RTCBandwidth: NSObject { ] if direction.contains("recv") { - mandatoryConstraints[kRTCMediaConstraintsOfferToReceiveAudio] = mediaTypes.contains("AUDIO") ? kRTCMediaConstraintsValueTrue : kRTCMediaConstraintsValueFalse - mandatoryConstraints[kRTCMediaConstraintsOfferToReceiveVideo] = mediaTypes.contains("VIDEO") ? kRTCMediaConstraintsValueTrue : kRTCMediaConstraintsValueFalse + mandatoryConstraints[kRTCMediaConstraintsOfferToReceiveAudio] = mediaTypes.contains(.audio) ? kRTCMediaConstraintsValueTrue : kRTCMediaConstraintsValueFalse + mandatoryConstraints[kRTCMediaConstraintsOfferToReceiveVideo] = mediaTypes.contains(.video) ? kRTCMediaConstraintsValueTrue : kRTCMediaConstraintsValueFalse } let constraints = RTCMediaConstraints(mandatoryConstraints: mandatoryConstraints, optionalConstraints: nil) @@ -251,7 +251,7 @@ public class RTCBandwidth: NSObject { private func handleSDPNeededEvent(parameters: SDPNeededParameters) { let peerConnection = RTCBandwidth.factory.peerConnection(with: configuration, constraints: mediaConstraints, delegate: self) - let remoteConnection = RTCBandwidthConnection(endpointId: parameters.endpointId, peerConnection: peerConnection, alias: parameters.alias, participantId: parameters.participantId) + let remoteConnection = RTCBandwidthConnection(endpointId: parameters.endpointId, peerConnection: peerConnection, mediaTypes: parameters.mediaTypes, alias: parameters.alias, participantId: parameters.participantId) remoteConnections.append(remoteConnection) @@ -288,10 +288,10 @@ extension RTCBandwidth: RTCPeerConnectionDelegate { public func peerConnection(_ peerConnection: RTCPeerConnection, didAdd rtpReceiver: RTCRtpReceiver, streams mediaStreams: [RTCMediaStream]) { debugPrint("peerConnection didAdd rtpReceiver: streams media Streams:") - guard let connection = remoteConnections.first(where: { $0.peerConnection == peerConnection }) else { return } + guard let remoteConnection = remoteConnections.first(where: { $0.peerConnection == peerConnection }) else { return } DispatchQueue.main.async { - self.delegate?.bandwidth(self, streamAvailableAt: connection, stream: mediaStreams.first) + self.delegate?.bandwidth(self, streamAvailableAt: remoteConnection.endpointId, mediaTypes: remoteConnection.mediaTypes, mediaStream: mediaStreams.first, alias: remoteConnection.alias, participantId: remoteConnection.participantId) } } @@ -325,6 +325,16 @@ extension RTCBandwidth: RTCPeerConnectionDelegate { signaling?.sendIceCandidate(endpointId: endpointId, candidate: candidate) } + public func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCPeerConnectionState) { + if [.disconnected, .failed].contains(newState) { + guard let remoteConnection = remoteConnections.first(where: { $0.peerConnection == peerConnection }) else { + return + } + + delegate?.bandwidth(self, streamUnavailableAt: remoteConnection.endpointId) + } + } + public func peerConnection(_ peerConnection: RTCPeerConnection, didRemove candidates: [RTCIceCandidate]) { debugPrint("peerConnection didRemove candidates: [RTCIceCandidate]") } diff --git a/Sources/BandwidthWebRTC/RTCBandwidthConnection.swift b/Sources/BandwidthWebRTC/RTCBandwidthConnection.swift index 98b7edb..3a380ba 100644 --- a/Sources/BandwidthWebRTC/RTCBandwidthConnection.swift +++ b/Sources/BandwidthWebRTC/RTCBandwidthConnection.swift @@ -11,12 +11,14 @@ import WebRTC public class RTCBandwidthConnection { let endpointId: String let peerConnection: RTCPeerConnection + let mediaTypes: [MediaType] let alias: String? let participantId: String? - init(endpointId: String, peerConnection: RTCPeerConnection, alias: String?, participantId: String?) { + init(endpointId: String, peerConnection: RTCPeerConnection, mediaTypes: [MediaType], alias: String?, participantId: String?) { self.endpointId = endpointId self.peerConnection = peerConnection + self.mediaTypes = mediaTypes self.alias = alias self.participantId = participantId } diff --git a/Sources/BandwidthWebRTC/Signaling/RPC/RequestToPublishResult.swift b/Sources/BandwidthWebRTC/Signaling/RPC/RequestToPublishResult.swift index 1ee70d9..ba593e4 100644 --- a/Sources/BandwidthWebRTC/Signaling/RPC/RequestToPublishResult.swift +++ b/Sources/BandwidthWebRTC/Signaling/RPC/RequestToPublishResult.swift @@ -9,6 +9,6 @@ import Foundation struct RequestToPublishResult: Decodable { let endpointId: String - let mediaTypes: [String] + let mediaTypes: [MediaType] let direction: String } diff --git a/Sources/BandwidthWebRTC/Signaling/RPC/SDPNeededParameters.swift b/Sources/BandwidthWebRTC/Signaling/RPC/SDPNeededParameters.swift index 67f5cc8..4121ea7 100644 --- a/Sources/BandwidthWebRTC/Signaling/RPC/SDPNeededParameters.swift +++ b/Sources/BandwidthWebRTC/Signaling/RPC/SDPNeededParameters.swift @@ -11,7 +11,7 @@ struct SDPNeededParameters: Codable { let alias: String let direction: String let endpointId: String - let mediaTypes: [String] + let mediaTypes: [MediaType] let participantId: String // let streamProperties: Any? // TODO: What should this do? } From a4af48b9b08c57de85103cc080d1a0897d2f3377 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Wed, 20 Jan 2021 13:14:58 -0500 Subject: [PATCH 02/15] Add participant id to the request to publish result --- .../BandwidthWebRTC/Signaling/RPC/RequestToPublishResult.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/BandwidthWebRTC/Signaling/RPC/RequestToPublishResult.swift b/Sources/BandwidthWebRTC/Signaling/RPC/RequestToPublishResult.swift index ba593e4..809624a 100644 --- a/Sources/BandwidthWebRTC/Signaling/RPC/RequestToPublishResult.swift +++ b/Sources/BandwidthWebRTC/Signaling/RPC/RequestToPublishResult.swift @@ -9,6 +9,7 @@ import Foundation struct RequestToPublishResult: Decodable { let endpointId: String + let participantId: String let mediaTypes: [MediaType] let direction: String } From 60dd3c26d626d02c711246a8866143d51e9cbe29 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Wed, 20 Jan 2021 13:44:12 -0500 Subject: [PATCH 03/15] Beautiful stream delegate and general clean up --- .../BandwidthWebRTC/PeerConnectionState.swift | 17 ---------- Sources/BandwidthWebRTC/RTCBandwidth.swift | 32 +++++++++++++------ ...thConnection.swift => RTCConnection.swift} | 14 ++++---- 3 files changed, 30 insertions(+), 33 deletions(-) delete mode 100644 Sources/BandwidthWebRTC/PeerConnectionState.swift rename Sources/BandwidthWebRTC/{RTCBandwidthConnection.swift => RTCConnection.swift} (63%) diff --git a/Sources/BandwidthWebRTC/PeerConnectionState.swift b/Sources/BandwidthWebRTC/PeerConnectionState.swift deleted file mode 100644 index db30575..0000000 --- a/Sources/BandwidthWebRTC/PeerConnectionState.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// PeerConnectionState.swift -// -// -// Created by Michael Hamer on 1/11/21. -// - -import Foundation - -public enum PeerConnectionState { - case new - case connecting - case connected - case disconnected - case failed - case closed -} diff --git a/Sources/BandwidthWebRTC/RTCBandwidth.swift b/Sources/BandwidthWebRTC/RTCBandwidth.swift index 5f83d45..8ba1d37 100644 --- a/Sources/BandwidthWebRTC/RTCBandwidth.swift +++ b/Sources/BandwidthWebRTC/RTCBandwidth.swift @@ -9,7 +9,7 @@ import Foundation import WebRTC public protocol RTCBandwidthDelegate { - func bandwidth(_ bandwidth: RTCBandwidth, streamAvailableAt endpointId: String, mediaTypes: [MediaType], mediaStream: RTCMediaStream?, alias: String?, participantId: String?) + func bandwidth(_ bandwidth: RTCBandwidth, streamAvailableAt endpointId: String, participantId: String, alias: String?, mediaTypes: [MediaType], mediaStream: RTCMediaStream?) func bandwidth(_ bandwidth: RTCBandwidth, streamUnavailableAt endpointId: String) } @@ -32,8 +32,8 @@ public class RTCBandwidth: NSObject { private let mediaConstraints = RTCMediaConstraints(mandatoryConstraints: nil, optionalConstraints: ["DtlsSrtpKeyAgreement": kRTCMediaConstraintsValueTrue]) - private var localConnections = [RTCBandwidthConnection]() - private var remoteConnections = [RTCBandwidthConnection]() + private var localConnections = [RTCConnection]() + private var remoteConnections = [RTCConnection]() #if os(iOS) private let audioSession = RTCAudioSession.sharedInstance() @@ -84,7 +84,7 @@ public class RTCBandwidth: NSObject { self.createMediaSenders(peerConnection: peerConnection, audio: audio, video: video) - let localConnection = RTCBandwidthConnection(endpointId: result.endpointId, peerConnection: peerConnection, mediaTypes: mediaTypes, alias: alias, participantId: nil) + let localConnection = RTCConnection(peerConnection: peerConnection, endpointId: result.endpointId, participantId: result.participantId, mediaTypes: mediaTypes, alias: alias) self.localConnections.append(localConnection) self.negotiateSDP(endpointId: result.endpointId, direction: result.direction, mediaTypes: result.mediaTypes, for: peerConnection) { @@ -250,13 +250,20 @@ public class RTCBandwidth: NSObject { } private func handleSDPNeededEvent(parameters: SDPNeededParameters) { - let peerConnection = RTCBandwidth.factory.peerConnection(with: configuration, constraints: mediaConstraints, delegate: self) - let remoteConnection = RTCBandwidthConnection(endpointId: parameters.endpointId, peerConnection: peerConnection, mediaTypes: parameters.mediaTypes, alias: parameters.alias, participantId: parameters.participantId) + let remotePeerConnection = RTCBandwidth.factory.peerConnection(with: configuration, constraints: mediaConstraints, delegate: self) + + let remoteConnection = RTCConnection( + peerConnection: remotePeerConnection, + endpointId: parameters.endpointId, + participantId: parameters.participantId, + mediaTypes: parameters.mediaTypes, + alias: parameters.alias + ) remoteConnections.append(remoteConnection) - negotiateSDP(endpointId: parameters.endpointId, direction: parameters.direction, mediaTypes: parameters.mediaTypes, for: peerConnection) { - + negotiateSDP(endpointId: parameters.endpointId, direction: parameters.direction, mediaTypes: parameters.mediaTypes, for: remotePeerConnection) { + } } @@ -291,7 +298,14 @@ extension RTCBandwidth: RTCPeerConnectionDelegate { guard let remoteConnection = remoteConnections.first(where: { $0.peerConnection == peerConnection }) else { return } DispatchQueue.main.async { - self.delegate?.bandwidth(self, streamAvailableAt: remoteConnection.endpointId, mediaTypes: remoteConnection.mediaTypes, mediaStream: mediaStreams.first, alias: remoteConnection.alias, participantId: remoteConnection.participantId) + self.delegate?.bandwidth( + self, + streamAvailableAt: remoteConnection.endpointId, + participantId: remoteConnection.participantId, + alias: remoteConnection.alias, + mediaTypes: remoteConnection.mediaTypes, + mediaStream: mediaStreams.first + ) } } diff --git a/Sources/BandwidthWebRTC/RTCBandwidthConnection.swift b/Sources/BandwidthWebRTC/RTCConnection.swift similarity index 63% rename from Sources/BandwidthWebRTC/RTCBandwidthConnection.swift rename to Sources/BandwidthWebRTC/RTCConnection.swift index 3a380ba..84cdb89 100644 --- a/Sources/BandwidthWebRTC/RTCBandwidthConnection.swift +++ b/Sources/BandwidthWebRTC/RTCConnection.swift @@ -1,5 +1,5 @@ // -// RTCBandwidthConnection.swift +// RTCConnection.swift // // // Created by Michael Hamer on 1/8/20. @@ -8,18 +8,18 @@ import Foundation import WebRTC -public class RTCBandwidthConnection { - let endpointId: String +public class RTCConnection { let peerConnection: RTCPeerConnection + let endpointId: String + let participantId: String let mediaTypes: [MediaType] let alias: String? - let participantId: String? - init(endpointId: String, peerConnection: RTCPeerConnection, mediaTypes: [MediaType], alias: String?, participantId: String?) { - self.endpointId = endpointId + init(peerConnection: RTCPeerConnection, endpointId: String, participantId: String, mediaTypes: [MediaType], alias: String?) { self.peerConnection = peerConnection + self.endpointId = endpointId + self.participantId = participantId self.mediaTypes = mediaTypes self.alias = alias - self.participantId = participantId } } From 4ae295d2e32bc10c6bad04ab938ca494f17c10c8 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Thu, 21 Jan 2021 16:13:03 -0500 Subject: [PATCH 04/15] Grab JSON RPC from the dev branch for now --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 1cb1d51..e609fe6 100644 --- a/Package.swift +++ b/Package.swift @@ -15,7 +15,7 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), - .package(url: "https://github.com/Bandwidth/json-rpc-websockets.git", .branch("main")), + .package(url: "https://github.com/Bandwidth/json-rpc-websockets.git", .branch("dev")), .package(url: "https://github.com/alexpiezo/WebRTC.git", .upToNextMajor(from: "1.1.31567")) ], targets: [ From 6c1288dee15cddac055c1a08cac5bd1bc1d8ae31 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Thu, 21 Jan 2021 16:18:01 -0500 Subject: [PATCH 05/15] Test removing the forced dispatch queues --- Sources/BandwidthWebRTC/RTCBandwidth.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/BandwidthWebRTC/RTCBandwidth.swift b/Sources/BandwidthWebRTC/RTCBandwidth.swift index 8ba1d37..2ef1efb 100644 --- a/Sources/BandwidthWebRTC/RTCBandwidth.swift +++ b/Sources/BandwidthWebRTC/RTCBandwidth.swift @@ -88,9 +88,9 @@ public class RTCBandwidth: NSObject { self.localConnections.append(localConnection) self.negotiateSDP(endpointId: result.endpointId, direction: result.direction, mediaTypes: result.mediaTypes, for: peerConnection) { - DispatchQueue.main.async { +// DispatchQueue.main.async { completion() - } +// } } } } @@ -213,7 +213,7 @@ public class RTCBandwidth: NSObject { let constraints = RTCMediaConstraints(mandatoryConstraints: mandatoryConstraints, optionalConstraints: nil) peerConnection.offer(for: constraints) { offer, error in - DispatchQueue.main.async { +// DispatchQueue.main.async { if let error = error { print(error.localizedDescription) } @@ -228,7 +228,7 @@ public class RTCBandwidth: NSObject { } peerConnection.setLocalDescription(offer) { error in - DispatchQueue.main.async { +// DispatchQueue.main.async { if let error = error { debugPrint(error.localizedDescription) } @@ -242,10 +242,10 @@ public class RTCBandwidth: NSObject { completion() } - } +// } } } - } +// } } } @@ -297,7 +297,7 @@ extension RTCBandwidth: RTCPeerConnectionDelegate { guard let remoteConnection = remoteConnections.first(where: { $0.peerConnection == peerConnection }) else { return } - DispatchQueue.main.async { +// DispatchQueue.main.async { self.delegate?.bandwidth( self, streamAvailableAt: remoteConnection.endpointId, @@ -306,7 +306,7 @@ extension RTCBandwidth: RTCPeerConnectionDelegate { mediaTypes: remoteConnection.mediaTypes, mediaStream: mediaStreams.first ) - } +// } } public func peerConnection(_ peerConnection: RTCPeerConnection, didChange stateChanged: RTCSignalingState) { From 659622e8c8b086987038a0ca046fccd668e52868 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Thu, 28 Jan 2021 17:08:42 -0500 Subject: [PATCH 06/15] Add disconnect to signaling --- .../Signaling/RPC/LeaveParameters.swift | 12 ++++++++++ .../BandwidthWebRTC/Signaling/Signaling.swift | 22 +++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 Sources/BandwidthWebRTC/Signaling/RPC/LeaveParameters.swift diff --git a/Sources/BandwidthWebRTC/Signaling/RPC/LeaveParameters.swift b/Sources/BandwidthWebRTC/Signaling/RPC/LeaveParameters.swift new file mode 100644 index 0000000..91db7fc --- /dev/null +++ b/Sources/BandwidthWebRTC/Signaling/RPC/LeaveParameters.swift @@ -0,0 +1,12 @@ +// +// LeaveParameters.swift +// +// +// Created by Michael Hamer on 1/28/21. +// + +import Foundation + +struct LeaveParameters: Codable { + +} diff --git a/Sources/BandwidthWebRTC/Signaling/Signaling.swift b/Sources/BandwidthWebRTC/Signaling/Signaling.swift index f3a1320..7d5c77a 100644 --- a/Sources/BandwidthWebRTC/Signaling/Signaling.swift +++ b/Sources/BandwidthWebRTC/Signaling/Signaling.swift @@ -16,7 +16,7 @@ enum SignalingMethod: String { case requestToPublish case sdpNeeded case setMediaPreferences - case unpublish + case leave } protocol SignalingDelegate { @@ -64,6 +64,17 @@ class Signaling { } } + func disconnect() { + let leaveParameters = LeaveParameters() + client.notify(method: SignalingMethod.leave.rawValue, parameters: leaveParameters) { _ in + + } + + client.disconnect { + + } + } + func setMediaPreferences(protocol: String, aggregationType: String, sendReceive: Bool, completion: @escaping (SetMediaPreferencesResult?) -> Void) { let parameters = SetMediaPreferencesParameters(protocol: `protocol`, aggregationType: aggregationType, sendReceive: sendReceive) do { @@ -101,9 +112,12 @@ class Signaling { sdpMLineIndex: Int(candidate.sdpMLineIndex), sdpMid: candidate.sdpMid ?? "") - try? client.notify(method: "addIceCandidate", parameters: parameters) { error in - if let error = error { - debugPrint(error.localizedDescription) + client.notify(method: "addIceCandidate", parameters: parameters) { result in + switch result { + case .success: + break + case .failure(let error): + print(error.localizedDescription) } } } From 11ed4d488195f61c67a5439cfed1bbba06fdf019 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Thu, 28 Jan 2021 17:27:49 -0500 Subject: [PATCH 07/15] Add unpublish to signaling server --- Sources/BandwidthWebRTC/Signaling/Signaling.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Sources/BandwidthWebRTC/Signaling/Signaling.swift b/Sources/BandwidthWebRTC/Signaling/Signaling.swift index 7d5c77a..9769597 100644 --- a/Sources/BandwidthWebRTC/Signaling/Signaling.swift +++ b/Sources/BandwidthWebRTC/Signaling/Signaling.swift @@ -16,6 +16,7 @@ enum SignalingMethod: String { case requestToPublish case sdpNeeded case setMediaPreferences + case unpublish case leave } @@ -75,6 +76,13 @@ class Signaling { } } + func unpublish(endpointId: String, completion: @escaping () -> Void) { + let unpublishParameters = UnpublishParameters(endpointId: endpointId) + client.notify(method: SignalingMethod.unpublish.rawValue, parameters: unpublishParameters) { _ in + completion() + } + } + func setMediaPreferences(protocol: String, aggregationType: String, sendReceive: Bool, completion: @escaping (SetMediaPreferencesResult?) -> Void) { let parameters = SetMediaPreferencesParameters(protocol: `protocol`, aggregationType: aggregationType, sendReceive: sendReceive) do { From f9fa0fafb8bcabe8c043b90395fd2a120a006838 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Fri, 29 Jan 2021 09:22:23 -0500 Subject: [PATCH 08/15] Pass unpublish signaling result --- Sources/BandwidthWebRTC/Signaling/Signaling.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/BandwidthWebRTC/Signaling/Signaling.swift b/Sources/BandwidthWebRTC/Signaling/Signaling.swift index 9769597..6bf46d4 100644 --- a/Sources/BandwidthWebRTC/Signaling/Signaling.swift +++ b/Sources/BandwidthWebRTC/Signaling/Signaling.swift @@ -76,10 +76,10 @@ class Signaling { } } - func unpublish(endpointId: String, completion: @escaping () -> Void) { + func unpublish(endpointId: String, completion: @escaping (Result<(), Error>) -> Void) { let unpublishParameters = UnpublishParameters(endpointId: endpointId) - client.notify(method: SignalingMethod.unpublish.rawValue, parameters: unpublishParameters) { _ in - completion() + client.notify(method: SignalingMethod.unpublish.rawValue, parameters: unpublishParameters) { result in + completion(result) } } From 62e2348bba43cf2ddbc03e632f864ab47679e8f6 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Fri, 29 Jan 2021 12:13:01 -0500 Subject: [PATCH 09/15] Add unpublish --- Sources/BandwidthWebRTC/RTCBandwidth.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Sources/BandwidthWebRTC/RTCBandwidth.swift b/Sources/BandwidthWebRTC/RTCBandwidth.swift index 2ef1efb..fd42aa2 100644 --- a/Sources/BandwidthWebRTC/RTCBandwidth.swift +++ b/Sources/BandwidthWebRTC/RTCBandwidth.swift @@ -96,6 +96,17 @@ public class RTCBandwidth: NSObject { } } + public func unpublish(endpointId: String) { + signaling?.unpublish(endpointId: endpointId) { result in + + } + + if let index = localConnections.firstIndex(where: { $0.endpointId == endpointId }) { + localConnections[index].peerConnection.close() + localConnections.remove(at: index) + } + } + // MARK: Media public func captureLocalVideo(renderer: RTCVideoRenderer) { From 258e715393c01b594a26ef9414aee39114c0419d Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Fri, 29 Jan 2021 12:31:32 -0500 Subject: [PATCH 10/15] Forward the send ICE candidate closure from the signaling server --- Sources/BandwidthWebRTC/RTCBandwidth.swift | 31 +++++++++++-------- .../BandwidthWebRTC/Signaling/Signaling.swift | 22 ++++++------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/Sources/BandwidthWebRTC/RTCBandwidth.swift b/Sources/BandwidthWebRTC/RTCBandwidth.swift index fd42aa2..70e8efc 100644 --- a/Sources/BandwidthWebRTC/RTCBandwidth.swift +++ b/Sources/BandwidthWebRTC/RTCBandwidth.swift @@ -307,17 +307,15 @@ extension RTCBandwidth: RTCPeerConnectionDelegate { debugPrint("peerConnection didAdd rtpReceiver: streams media Streams:") guard let remoteConnection = remoteConnections.first(where: { $0.peerConnection == peerConnection }) else { return } - -// DispatchQueue.main.async { - self.delegate?.bandwidth( - self, - streamAvailableAt: remoteConnection.endpointId, - participantId: remoteConnection.participantId, - alias: remoteConnection.alias, - mediaTypes: remoteConnection.mediaTypes, - mediaStream: mediaStreams.first - ) -// } + + self.delegate?.bandwidth( + self, + streamAvailableAt: remoteConnection.endpointId, + participantId: remoteConnection.participantId, + alias: remoteConnection.alias, + mediaTypes: remoteConnection.mediaTypes, + mediaStream: mediaStreams.first + ) } public func peerConnection(_ peerConnection: RTCPeerConnection, didChange stateChanged: RTCSignalingState) { @@ -343,11 +341,18 @@ extension RTCBandwidth: RTCPeerConnectionDelegate { public func peerConnection(_ peerConnection: RTCPeerConnection, didGenerate candidate: RTCIceCandidate) { debugPrint("peerConnection didGenerate candidate: RTCIceCandidate") - guard let endpointId = remoteConnections.first(where: { $0.peerConnection == peerConnection })?.endpointId else { + guard let remoteConnection = remoteConnections.first(where: { $0.peerConnection == peerConnection }) else { return } - signaling?.sendIceCandidate(endpointId: endpointId, candidate: candidate) + signaling?.sendIceCandidate( + endpointId: remoteConnection.endpointId, + sdp: candidate.sdp, + sdpMLineIndex: Int(candidate.sdpMLineIndex), + sdpMid: candidate.sdpMid ?? "" + ) { _ in + + } } public func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCPeerConnectionState) { diff --git a/Sources/BandwidthWebRTC/Signaling/Signaling.swift b/Sources/BandwidthWebRTC/Signaling/Signaling.swift index 6bf46d4..726281f 100644 --- a/Sources/BandwidthWebRTC/Signaling/Signaling.swift +++ b/Sources/BandwidthWebRTC/Signaling/Signaling.swift @@ -7,7 +7,7 @@ import Foundation import JSONRPCWebSockets -import WebRTC +//import WebRTC enum SignalingMethod: String { case addICECandidate = "addIceCandidate" @@ -113,20 +113,16 @@ class Signaling { } } - func sendIceCandidate(endpointId: String, candidate: RTCIceCandidate) { - let parameters = AddICECandidateSendParameters( + func sendIceCandidate(endpointId: String, sdp: String, sdpMLineIndex: Int, sdpMid: String, completion: @escaping (Result<(), Error>) -> Void) { + let addICECandidateParameters = AddICECandidateSendParameters( endpointId: endpointId, - candidate: candidate.sdp, - sdpMLineIndex: Int(candidate.sdpMLineIndex), - sdpMid: candidate.sdpMid ?? "") + candidate: sdp, + sdpMLineIndex: sdpMLineIndex, + sdpMid: sdpMid + ) - client.notify(method: "addIceCandidate", parameters: parameters) { result in - switch result { - case .success: - break - case .failure(let error): - print(error.localizedDescription) - } + client.notify(method: SignalingMethod.addICECandidate.rawValue, parameters: addICECandidateParameters) { result in + completion(result) } } } From 296fc524fd3b71abd42ceab3a02ef06fa4381fe5 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Fri, 29 Jan 2021 12:41:14 -0500 Subject: [PATCH 11/15] Disconnect --- Sources/BandwidthWebRTC/RTCBandwidth.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Sources/BandwidthWebRTC/RTCBandwidth.swift b/Sources/BandwidthWebRTC/RTCBandwidth.swift index 70e8efc..098875b 100644 --- a/Sources/BandwidthWebRTC/RTCBandwidth.swift +++ b/Sources/BandwidthWebRTC/RTCBandwidth.swift @@ -62,6 +62,10 @@ public class RTCBandwidth: NSObject { } } + public func disconnect() { + signaling?.disconnect() + } + public func publish(audio: Bool, video: Bool, alias: String?, completion: @escaping () -> Void) { var mediaTypes = [MediaType]() @@ -88,9 +92,7 @@ public class RTCBandwidth: NSObject { self.localConnections.append(localConnection) self.negotiateSDP(endpointId: result.endpointId, direction: result.direction, mediaTypes: result.mediaTypes, for: peerConnection) { -// DispatchQueue.main.async { - completion() -// } + completion() } } } From 83b7c9aa8856acedfeb70d84f1f8c0ab041c6188 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Fri, 29 Jan 2021 14:11:49 -0500 Subject: [PATCH 12/15] Monitor peer connection state --- Sources/BandwidthWebRTC/RTCBandwidth.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/BandwidthWebRTC/RTCBandwidth.swift b/Sources/BandwidthWebRTC/RTCBandwidth.swift index 098875b..ed4cafb 100644 --- a/Sources/BandwidthWebRTC/RTCBandwidth.swift +++ b/Sources/BandwidthWebRTC/RTCBandwidth.swift @@ -358,6 +358,8 @@ extension RTCBandwidth: RTCPeerConnectionDelegate { } public func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCPeerConnectionState) { + print("peerConnection didChange newState: \(newState)") + if [.disconnected, .failed].contains(newState) { guard let remoteConnection = remoteConnections.first(where: { $0.peerConnection == peerConnection }) else { return From f6a0b2df608311b34ee2b2df7a3fb6e0d6d460a2 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Mon, 1 Feb 2021 13:55:08 -0500 Subject: [PATCH 13/15] Rename package and use versioned json-rpc-websockets --- Package.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index e609fe6..4c0b43c 100644 --- a/Package.swift +++ b/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( - name: "webrtc-swift", + name: "bandwidth-webrtc", platforms: [.iOS(.v13), .macOS(.v10_15)], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. @@ -15,7 +15,7 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), - .package(url: "https://github.com/Bandwidth/json-rpc-websockets.git", .branch("dev")), + .package(url: "https://github.com/Bandwidth/json-rpc-websockets.git", .upToNextMajor(from: "0.1.0")), .package(url: "https://github.com/alexpiezo/WebRTC.git", .upToNextMajor(from: "1.1.31567")) ], targets: [ From d36c947ab8a0c6a37b5366d14b05c4f25df1494e Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Mon, 1 Feb 2021 14:02:30 -0500 Subject: [PATCH 14/15] Remove commented out import --- Sources/BandwidthWebRTC/Signaling/Signaling.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/BandwidthWebRTC/Signaling/Signaling.swift b/Sources/BandwidthWebRTC/Signaling/Signaling.swift index 726281f..6e7c860 100644 --- a/Sources/BandwidthWebRTC/Signaling/Signaling.swift +++ b/Sources/BandwidthWebRTC/Signaling/Signaling.swift @@ -7,7 +7,6 @@ import Foundation import JSONRPCWebSockets -//import WebRTC enum SignalingMethod: String { case addICECandidate = "addIceCandidate" From c6c5f23535b1a0e00a1391510e816cf71156ee00 Mon Sep 17 00:00:00 2001 From: Mike Hamer Date: Mon, 1 Feb 2021 14:13:43 -0500 Subject: [PATCH 15/15] Rename RTCConnection to Connection --- .../{RTCConnection.swift => Connection.swift} | 4 ++-- Sources/BandwidthWebRTC/RTCBandwidth.swift | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) rename Sources/BandwidthWebRTC/{RTCConnection.swift => Connection.swift} (91%) diff --git a/Sources/BandwidthWebRTC/RTCConnection.swift b/Sources/BandwidthWebRTC/Connection.swift similarity index 91% rename from Sources/BandwidthWebRTC/RTCConnection.swift rename to Sources/BandwidthWebRTC/Connection.swift index 84cdb89..1245828 100644 --- a/Sources/BandwidthWebRTC/RTCConnection.swift +++ b/Sources/BandwidthWebRTC/Connection.swift @@ -1,5 +1,5 @@ // -// RTCConnection.swift +// Connection.swift // // // Created by Michael Hamer on 1/8/20. @@ -8,7 +8,7 @@ import Foundation import WebRTC -public class RTCConnection { +class Connection { let peerConnection: RTCPeerConnection let endpointId: String let participantId: String diff --git a/Sources/BandwidthWebRTC/RTCBandwidth.swift b/Sources/BandwidthWebRTC/RTCBandwidth.swift index ed4cafb..a1e42ef 100644 --- a/Sources/BandwidthWebRTC/RTCBandwidth.swift +++ b/Sources/BandwidthWebRTC/RTCBandwidth.swift @@ -32,8 +32,8 @@ public class RTCBandwidth: NSObject { private let mediaConstraints = RTCMediaConstraints(mandatoryConstraints: nil, optionalConstraints: ["DtlsSrtpKeyAgreement": kRTCMediaConstraintsValueTrue]) - private var localConnections = [RTCConnection]() - private var remoteConnections = [RTCConnection]() + private var localConnections = [Connection]() + private var remoteConnections = [Connection]() #if os(iOS) private let audioSession = RTCAudioSession.sharedInstance() @@ -88,7 +88,7 @@ public class RTCBandwidth: NSObject { self.createMediaSenders(peerConnection: peerConnection, audio: audio, video: video) - let localConnection = RTCConnection(peerConnection: peerConnection, endpointId: result.endpointId, participantId: result.participantId, mediaTypes: mediaTypes, alias: alias) + let localConnection = Connection(peerConnection: peerConnection, endpointId: result.endpointId, participantId: result.participantId, mediaTypes: mediaTypes, alias: alias) self.localConnections.append(localConnection) self.negotiateSDP(endpointId: result.endpointId, direction: result.direction, mediaTypes: result.mediaTypes, for: peerConnection) { @@ -265,7 +265,7 @@ public class RTCBandwidth: NSObject { private func handleSDPNeededEvent(parameters: SDPNeededParameters) { let remotePeerConnection = RTCBandwidth.factory.peerConnection(with: configuration, constraints: mediaConstraints, delegate: self) - let remoteConnection = RTCConnection( + let remoteConnection = Connection( peerConnection: remotePeerConnection, endpointId: parameters.endpointId, participantId: parameters.participantId,