[webRTC for ios vol3] trickle ICE
전회의 보통에 접속하는 녀석은 이쪽.
ぃ tp // 코 m / 나카 도리 보오 ks / ms / 9f1b1c 32f2fc6에서 c70
이번은 Trickle ICE 합니다.
연결이 빨라지는 사람.
아티팩트
참고
지난번부터 변경
v2_v3.diff
diff --git a/webrtcExample/ViewController.swift b/webrtcExample/ViewController.swift
index fff27b8..a560ddb 100644
--- a/webrtcExample/ViewController.swift
+++ b/webrtcExample/ViewController.swift
@@ -43,18 +43,18 @@ class ViewController: UIViewController {
self.wamp.publishAnswer(sdp: localSdp)
}
+ }, didGenerateCandidate: { (candidate) in
+
+ self.wamp.publishCandidate(candidate: candidate)
+
}, didReceiveRemoteStream: { () in
self.stateWebrtcConnected()
})
- wamp.connect(onConnected: {
-
+ wamp.connect(onConnected: {
self.stateConnected()
-
}, onReceiveAnswer: { (answerSdp) in
- print("onReceiveAnswer")
-
self.webRTC.receiveAnswer(remoteSdp: answerSdp)
}, onReceiveOffer: { (offerSdp) in
@@ -63,13 +63,15 @@ class ViewController: UIViewController {
return;
}
- print("onReceiveOffer")
-
self.stateReceivedOffer()
self.webRTC.receiveOffer(remoteSdp: offerSdp)
+ }, onReceiveCandidate: { (candidate) in
+
+ self.webRTC.receiveCandidate(candidate: candidate)
+
})
-
+
}
private func changeButton(title:String, color:UIColor, enabled:Bool){
@@ -103,7 +105,6 @@ class ViewController: UIViewController {
stateOffering()
-
webRTC.createOffer()
}
diff --git a/webrtcExample/wamp/Wamp.swift b/webrtcExample/wamp/Wamp.swift
index 9714d4f..76a0e89 100644
--- a/webrtcExample/wamp/Wamp.swift
+++ b/webrtcExample/wamp/Wamp.swift
@@ -15,20 +15,27 @@ class Wamp: NSObject, SwampSessionDelegate {
private static let AnswerTopic = "com.nakadoribook.webrtc.answer"
private static let OfferTopic = "com.nakadoribook.webrtc.offer"
+ private static let CandidateTopic = "com.nakadoribook.webrtc.candidate"
private var swampSession:SwampSession?
private var onConnected:(()->())?
private var onReceiveAnswer:((_ sdp:NSDictionary)->())?
private var onReceiveOffer:((_ sdp:NSDictionary)->())?
+ private var onReceiveCandidate:((_ sdp:NSDictionary)->())?
private override init() {
super.init()
}
- func connect(onConnected:@escaping (()->()), onReceiveAnswer:@escaping ((_ sdp:NSDictionary)->()), onReceiveOffer:@escaping ((_ sdp:NSDictionary)->())){
+ func connect(onConnected:@escaping (()->())
+ , onReceiveAnswer:@escaping ((_ sdp:NSDictionary)->())
+ , onReceiveOffer:@escaping ((_ sdp:NSDictionary)->())
+ , onReceiveCandidate:@escaping ((_ candidate:NSDictionary)->())
+ ){
self.onConnected = onConnected
self.onReceiveAnswer = onReceiveAnswer
self.onReceiveOffer = onReceiveOffer
+ self.onReceiveCandidate = onReceiveCandidate
// let swampTransport = WebSocketSwampTransport(wsEndpoint: URL(string: "wss://nakadoribooks-webrtc.herokuapp.com")!)
let swampTransport = WebSocketSwampTransport(wsEndpoint: URL(string: "ws://192.168.1.2:8000")!)
@@ -47,11 +54,16 @@ class Wamp: NSObject, SwampSessionDelegate {
swampSession?.publish(Wamp.AnswerTopic, options: [:], args: [sdp], kwargs: [:])
}
+ func publishCandidate(candidate:NSDictionary){
+ swampSession?.publish(Wamp.CandidateTopic, options: [:], args: [candidate], kwargs: [:])
+ }
+
// MARK: private
private func subscribe(){
_subscribeOffer()
_subscribeAnswer()
+ _subscribeCandidate()
}
private func _subscribeOffer(){
@@ -89,6 +101,25 @@ class Wamp: NSObject, SwampSessionDelegate {
})
}
+ private func _subscribeCandidate(){
+ swampSession?.subscribe(Wamp.CandidateTopic, onSuccess: { (subscription) in
+
+ }, onError: { (details, error) in
+ print("onError: \(error)")
+ }, onEvent: { (details, results, kwResults) in
+
+ guard let candidate = results?.first as? NSDictionary else{
+ print("no args")
+ return;
+ }
+
+ print("receiveCandidate:\(candidate)")
+ if let callback = self.onReceiveCandidate{
+ callback(candidate)
+ }
+ })
+ }
+
// MARK: SwampSessionDelegate
func swampSessionHandleChallenge(_ authMethod: String, extra: [String: Any]) -> String{
diff --git a/webrtcExample/webrtc/WebRTC.swift b/webrtcExample/webrtc/WebRTC.swift
index 0a5b51b..f511c48 100644
--- a/webrtcExample/webrtc/WebRTC.swift
+++ b/webrtcExample/webrtc/WebRTC.swift
@@ -10,6 +10,8 @@ import UIKit
class WebRTC: NSObject, RTCPeerConnectionDelegate, RTCEAGLVideoViewDelegate {
+ private var didGenerateCandidate:((_ candidate:NSDictionary)->())?
+
private var didReceiveRemoteStream:(()->())?
private var onCreatedLocalSdp:((_ localSdp:NSDictionary)->())?
@@ -45,8 +47,12 @@ class WebRTC: NSObject, RTCPeerConnectionDelegate, RTCEAGLVideoViewDelegate {
setupLocalStream()
}
- func connect(iceServerUrlList:[String], onCreatedLocalSdp:@escaping ((_ localSdp:NSDictionary)->()), didReceiveRemoteStream:@escaping (()->())){
+ func connect(iceServerUrlList:[String]
+ , onCreatedLocalSdp:@escaping ((_ localSdp:NSDictionary)->())
+ , didGenerateCandidate:@escaping ((_ localSdp:NSDictionary)->())
+ , didReceiveRemoteStream:@escaping (()->())){
self.onCreatedLocalSdp = onCreatedLocalSdp
+ self.didGenerateCandidate = didGenerateCandidate
self.didReceiveRemoteStream = didReceiveRemoteStream
let configuration = RTCConfiguration()
@@ -65,7 +71,18 @@ class WebRTC: NSObject, RTCPeerConnectionDelegate, RTCEAGLVideoViewDelegate {
_receiveOffer(remoteSdp: remoteSdp)
}
+ func receiveCandidate(candidate:NSDictionary){
+ guard let candidate = candidate as? [AnyHashable:Any]
+ , let rtcCandidate = RTCIceCandidate(fromJSONDictionary: candidate) else{
+ print("invalid candiate")
+ return
+ }
+
+ self.peerConnection?.add(rtcCandidate)
+ }
+
// Offerを作る
+
func createOffer(){
_createOffer()
}
@@ -83,7 +100,7 @@ class WebRTC: NSObject, RTCPeerConnectionDelegate, RTCEAGLVideoViewDelegate {
// 1. remote SDP を登録
peerConnection?.setRemoteDescription(sdp, completionHandler: { (error) in
-
+
})
}
@@ -109,10 +126,16 @@ class WebRTC: NSObject, RTCPeerConnectionDelegate, RTCEAGLVideoViewDelegate {
// 3.ローカルにSDPを登録
self.peerConnection?.setLocalDescription(sdp, completionHandler: { (error) in
+ // 3. answer を送る
+ guard let callback = self.onCreatedLocalSdp, let localDescription = WebRTCUtil.jsonFromDescription(description: self.peerConnection?.localDescription) else{
+ print("no localDescription")
+ return ;
+ }
+
+ callback(localDescription)
+ self.onCreatedLocalSdp = nil
})
- // 4. peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceGatheringState)
- // で complete になったら Answerを送る
})
})
}
@@ -132,8 +155,15 @@ class WebRTC: NSObject, RTCPeerConnectionDelegate, RTCEAGLVideoViewDelegate {
})
- // 3. peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceGatheringState)
- // で complete になったら offerを送る
+ // 3. offer を送る
+ guard let callback = self.onCreatedLocalSdp, let localDescription = WebRTCUtil.jsonFromDescription(description: self.peerConnection?.localDescription) else{
+ print("no localDescription")
+ return ;
+ }
+
+ callback(localDescription)
+ self.onCreatedLocalSdp = nil
+
})
}
@@ -183,10 +213,20 @@ class WebRTC: NSObject, RTCPeerConnectionDelegate, RTCEAGLVideoViewDelegate {
public func peerConnectionShouldNegotiate(_ peerConnection: RTCPeerConnection){}
public func peerConnection(_ peerConnection: RTCPeerConnection, didRemove stream: RTCMediaStream){}
public func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceConnectionState){}
- public func peerConnection(_ peerConnection: RTCPeerConnection, didGenerate candidate: RTCIceCandidate){ }
public func peerConnection(_ peerConnection: RTCPeerConnection, didRemove candidates: [RTCIceCandidate]){}
public func peerConnection(_ peerConnection: RTCPeerConnection, didOpen dataChannel: RTCDataChannel){}
public func peerConnection(_ peerConnection: RTCPeerConnection, didChange stateChanged: RTCSignalingState){}
+ public func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceGatheringState){}
+
+ // for Trickle ice
+ public func peerConnection(_ peerConnection: RTCPeerConnection, didGenerate candidate: RTCIceCandidate){
+ print("didGenerate candidate")
+
+ if let didGenerateCandidate = self.didGenerateCandidate, let candidateJson = WebRTCUtil.jsonFromData(data: candidate.jsonData()){
+ print("didGenerateCandidate")
+ didGenerateCandidate(candidateJson)
+ }
+ }
public func peerConnection(_ peerConnection: RTCPeerConnection, didAdd stream: RTCMediaStream){
print("peerConnection didAdd stream:")
@@ -209,22 +249,6 @@ class WebRTC: NSObject, RTCPeerConnectionDelegate, RTCEAGLVideoViewDelegate {
}
}
- public func peerConnection(_ peerConnection: RTCPeerConnection, didChange newState: RTCIceGatheringState){
- print("peerConnection didChange newState: RTCIceGatheringState, \(newState)")
-
- if newState != .complete{
- return;
- }
-
- guard let callback = self.onCreatedLocalSdp, let localDescription = WebRTCUtil.jsonFromDescription(description: self.peerConnection?.localDescription) else{
- print("no localDescription")
- return ;
- }
-
- callback(localDescription)
- self.onCreatedLocalSdp = nil
- }
-
// MARK: RTCEAGLVideoViewDelegate
func videoView(_ videoView: RTCEAGLVideoView, didChangeVideoSize size: CGSize) {
이상.
다음
일단, IOS는 이상으로.
다음은 Android 할 예정.
찍은 온천은 쿠니오카야키
시대와 함께 만드는 물건은 거물 중심에서 소품, 즉 식기 중심으로 옮겨 왔습니다만, 그래도 사람들의 생활에 밀착한 구이를 계속 만들어 온 것에는 변함이 없습니다. 흙을 살려 장식을 앞두고, 사용의 용이성과 따뜻함, 그리고 아름다움을 추구하면서 현재에 이릅니다.
h tp // w w. 그렇다면 오카야키. 이 m/후아트레. HTML
사용의 용이성, 온기, 그리고 아름다움.
제조의 대선배군요.
온천 엄청 멋지기 때문에 추천합니다.
Reference
이 문제에 관하여([webRTC for ios vol3] trickle ICE), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/nakadoribooks/items/a0f19dd96b0763c35ed2
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여([webRTC for ios vol3] trickle ICE), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/nakadoribooks/items/a0f19dd96b0763c35ed2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)