This repository has been archived by the owner on Nov 21, 2020. It is now read-only.
forked from sergiopaniego/WebRTCiOS
/
PeersManager.swift
173 lines (147 loc) · 7.16 KB
/
PeersManager.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//
// PeersManager.swift
// WebRTCapp
//
// Created by Sergio Paniego Blanco on 20/05/2018.
// Copyright © 2018 Sergio Paniego Blanco. All rights reserved.
//
import Foundation
import WebRTC
import Starscream
class PeersManager: NSObject {
var localPeer: RTCPeerConnection?
var remotePeer: RTCPeerConnection?
var peerConnectionFactory: RTCPeerConnectionFactory?
var connectionConstraints: RTCMediaConstraints?
var webSocketListener: WebSocketListener?
var webSocket: WebSocket?
var localVideoTrack: RTCVideoTrack?
var localAudioTrack: RTCAudioTrack?
var peerConnection: RTCPeerConnection?
var view: UIView!
var remoteStreams: [RTCMediaStream]
var remoteParticipant: RemoteParticipant?
init(view: UIView) {
self.view = view
self.remoteStreams = []
}
func setWebSocketAdapter(webSocketAdapter: WebSocketListener) {
self.webSocketListener = webSocketAdapter
}
// Function that start everything related with WebRTC use
func start() {
let videoEncoderFactory = RTCDefaultVideoEncoderFactory()
let videoDecoderFactory = RTCDefaultVideoDecoderFactory()
peerConnectionFactory = RTCPeerConnectionFactory(encoderFactory: videoEncoderFactory, decoderFactory: videoDecoderFactory)
let mandatoryConstraints = [
"OfferToReceiveAudio": "true",
"OfferToReceiveVideo": "true"
]
let sdpConstraints = RTCMediaConstraints(mandatoryConstraints: mandatoryConstraints, optionalConstraints: nil)
createLocalPeerConnection(sdpConstraints: sdpConstraints)
}
func createLocalPeerConnection(sdpConstraints: RTCMediaConstraints) {
let config = RTCConfiguration()
config.bundlePolicy = .maxCompat
config.iceServers = [RTCIceServer(urlStrings: ["stun:stun.l.google.com:19302"])]
config.rtcpMuxPolicy = .require
localPeer = peerConnectionFactory!.peerConnection(with: config, constraints: sdpConstraints, delegate: nil)
}
func createLocalOffer(mediaConstraints: RTCMediaConstraints) {
localPeer!.offer(for: mediaConstraints, completionHandler: { (sessionDescription, error) in
self.localPeer!.setLocalDescription(sessionDescription!, completionHandler: {(error) in
print("Local Peer local Description set: " + error.debugDescription)
})
var localOfferParams: [String:String] = [:]
localOfferParams["audioActive"] = "true"
localOfferParams["videoActive"] = "true"
localOfferParams["doLoopback"] = "false"
localOfferParams["hasAudio"] = "true"
localOfferParams["hasVideo"] = "true"
localOfferParams["frameRate"] = "30"
localOfferParams["typeOfVideo"] = "CAMERA"
localOfferParams["videoDimensions"] = "{\"width\":640,\"height\":480}"
localOfferParams["sdpOffer"] = sessionDescription!.sdp
if (self.webSocketListener!.id) > 1 {
self.webSocketListener!.sendJson(method: "publishVideo", params: localOfferParams)
} else {
self.webSocketListener!.localOfferParams = localOfferParams
}
})
}
func createRemotePeerConnection(remoteParticipant: RemoteParticipant) {
let mandatoryConstraints = [
"OfferToReceiveAudio": "true",
"OfferToReceiveVideo": "true"
]
let sdpConstraints = RTCMediaConstraints(mandatoryConstraints: mandatoryConstraints, optionalConstraints: nil)
let config = RTCConfiguration()
config.bundlePolicy = .maxCompat
config.iceServers = [RTCIceServer(urlStrings: ["stun:stun.l.google.com:19302"])]
config.rtcpMuxPolicy = .require
self.remotePeer = (peerConnectionFactory?.peerConnection(with: config, constraints: sdpConstraints, delegate: nil))!
remoteParticipant.peerConnection = self.remotePeer
self.remoteParticipant = remoteParticipant
self.remoteParticipant?.peerConnection = self.remotePeer
}
}
extension PeersManager: RTCPeerConnectionDelegate {
func peerConnection(_ peerConnection: RTCPeerConnection, didChange stateChanged: RTCSignalingState) {
print("peerConnection new signaling state: \(stateChanged)")
}
func peerConnection(_ peerConnection: RTCPeerConnection, didAdd stream: RTCMediaStream) {
if peerConnection == self.localPeer {
print("local peerConnection did add stream")
} else {
print("remote peerConnection did add stream")
if (stream.audioTracks.count > 1 || stream.videoTracks.count > 1) {
print("Weird looking stream")
}
remoteStreams.append(stream)
}
}
func peerConnection(_ peerConnection: RTCPeerConnection, didRemove stream: RTCMediaStream) {
print("peerConnection did remote stream")
}
func peerConnectionShouldNegotiate(_ peerConnection: RTCPeerConnection) {
if peerConnection == self.localPeer {
print("local peerConnection should negotiate")
} else {
print("remote peerConnection should negotiate")
}
}
func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceConnectionState) {
print("peerConnection new connection state: \(newState.rawValue)")
}
func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceGatheringState) {
print("peerConnection new gathering state: \(newState.rawValue)")
}
func peerConnection(_ peerConnection: RTCPeerConnection, didGenerate candidate: RTCIceCandidate) {
if peerConnection == self.localPeer {
var iceCandidateParams: [String: String] = [:]
iceCandidateParams["sdpMid"] = candidate.sdpMid
iceCandidateParams["sdpMLineIndex"] = String(candidate.sdpMLineIndex)
iceCandidateParams["candidate"] = String(candidate.sdp)
if self.webSocketListener!.userId != nil {
iceCandidateParams["endpointName"] = self.webSocketListener!.userId
self.webSocketListener!.sendJson(method: "onIceCandidate", params: iceCandidateParams)
} else {
self.webSocketListener!.addIceCandidate(iceCandidateParams: iceCandidateParams)
}
print("NEW local ice candidate")
} else {
var iceCandidateParams: [String: String] = [:]
iceCandidateParams["sdpMid"] = candidate.sdpMid
iceCandidateParams["sdpMLineIndex"] = String(candidate.sdpMLineIndex)
iceCandidateParams["candidate"] = String(candidate.sdp)
iceCandidateParams["endpointName"] = self.remoteParticipant!.id
self.webSocketListener!.sendJson(method: "onIceCandidate", params: iceCandidateParams)
print("NEW remote ice candidate")
}
}
func peerConnection(_ peerConnection: RTCPeerConnection, didRemove candidates: [RTCIceCandidate]) {
}
func peerConnection(_ peerConnection: RTCPeerConnection, didOpen dataChannel: RTCDataChannel) {
print("peerConnection did open data channel")
}
}