react-native-altibbi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +190 -0
- package/android/build.gradle +104 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/altibbi/AltibbiModule.kt +18 -0
- package/android/src/main/java/com/altibbi/AltibbiPackage.kt +18 -0
- package/android/src/main/java/com/altibbi/OTCustomAudioDevice.java +1146 -0
- package/android/src/main/java/com/altibbi/OTPublisherLayout.java +61 -0
- package/android/src/main/java/com/altibbi/OTPublisherViewManager.java +30 -0
- package/android/src/main/java/com/altibbi/OTRN.java +101 -0
- package/android/src/main/java/com/altibbi/OTScreenCapturer.java +120 -0
- package/android/src/main/java/com/altibbi/OTSessionManager.java +1281 -0
- package/android/src/main/java/com/altibbi/OTSubscriberLayout.java +68 -0
- package/android/src/main/java/com/altibbi/OTSubscriberViewManager.java +30 -0
- package/android/src/main/java/com/altibbi/Socket.kt +294 -0
- package/android/src/main/java/com/altibbi/SocketEventEmitter.kt +25 -0
- package/android/src/main/java/com/altibbi/utils/EventUtils.java +189 -0
- package/android/src/main/java/com/altibbi/utils/Utils.java +135 -0
- package/ios/Altibbi-Bridging-Header.h +6 -0
- package/ios/Altibbi.mm +10 -0
- package/ios/Altibbi.swift +4 -0
- package/ios/OTCustomAudioDriver.swift +696 -0
- package/ios/OTPublisher.m +16 -0
- package/ios/OTPublisherManager.swift +21 -0
- package/ios/OTPublisherView.swift +28 -0
- package/ios/OTRN.swift +27 -0
- package/ios/OTScreenCapture.h +27 -0
- package/ios/OTScreenCapture.m +171 -0
- package/ios/OTSessionManager.m +127 -0
- package/ios/OTSessionManager.swift +866 -0
- package/ios/OTSubscriber.m +15 -0
- package/ios/OTSubscriberManager.swift +21 -0
- package/ios/OTSubscriberView.swift +29 -0
- package/ios/OpenTokReactNative.h +13 -0
- package/ios/OpenTokReactNative.m +13 -0
- package/ios/SocketReactNative.m +38 -0
- package/ios/SocketReactNative.swift +276 -0
- package/ios/Utils/EventUtils.swift +143 -0
- package/ios/Utils/Utils.swift +126 -0
- package/lib/commonjs/connection.js +200 -0
- package/lib/commonjs/connection.js.map +1 -0
- package/lib/commonjs/data.js +12 -0
- package/lib/commonjs/data.js.map +1 -0
- package/lib/commonjs/index.js +275 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/scoket.js +245 -0
- package/lib/commonjs/scoket.js.map +1 -0
- package/lib/commonjs/service.js +21 -0
- package/lib/commonjs/service.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/video/OT.js +57 -0
- package/lib/commonjs/video/OT.js.map +1 -0
- package/lib/commonjs/video/OTError.js +17 -0
- package/lib/commonjs/video/OTError.js.map +1 -0
- package/lib/commonjs/video/OTPublisher.js +171 -0
- package/lib/commonjs/video/OTPublisher.js.map +1 -0
- package/lib/commonjs/video/OTSession.js +205 -0
- package/lib/commonjs/video/OTSession.js.map +1 -0
- package/lib/commonjs/video/OTSubscriber.js +185 -0
- package/lib/commonjs/video/OTSubscriber.js.map +1 -0
- package/lib/commonjs/video/contexts/OTContext.js +11 -0
- package/lib/commonjs/video/contexts/OTContext.js.map +1 -0
- package/lib/commonjs/video/helpers/OTHelper.js +92 -0
- package/lib/commonjs/video/helpers/OTHelper.js.map +1 -0
- package/lib/commonjs/video/helpers/OTPublisherHelper.js +117 -0
- package/lib/commonjs/video/helpers/OTPublisherHelper.js.map +1 -0
- package/lib/commonjs/video/helpers/OTSessionHelper.js +206 -0
- package/lib/commonjs/video/helpers/OTSessionHelper.js.map +1 -0
- package/lib/commonjs/video/helpers/OTSubscriberHelper.js +121 -0
- package/lib/commonjs/video/helpers/OTSubscriberHelper.js.map +1 -0
- package/lib/commonjs/video/index.js +42 -0
- package/lib/commonjs/video/index.js.map +1 -0
- package/lib/commonjs/video/views/OTPublisherView.js +26 -0
- package/lib/commonjs/video/views/OTPublisherView.js.map +1 -0
- package/lib/commonjs/video/views/OTSubscriberView.js +25 -0
- package/lib/commonjs/video/views/OTSubscriberView.js.map +1 -0
- package/lib/module/connection.js +180 -0
- package/lib/module/connection.js.map +1 -0
- package/lib/module/data.js +6 -0
- package/lib/module/data.js.map +1 -0
- package/lib/module/index.js +12 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/scoket.js +235 -0
- package/lib/module/scoket.js.map +1 -0
- package/lib/module/service.js +14 -0
- package/lib/module/service.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/video/OT.js +49 -0
- package/lib/module/video/OT.js.map +1 -0
- package/lib/module/video/OTError.js +10 -0
- package/lib/module/video/OTError.js.map +1 -0
- package/lib/module/video/OTPublisher.js +162 -0
- package/lib/module/video/OTPublisher.js.map +1 -0
- package/lib/module/video/OTSession.js +195 -0
- package/lib/module/video/OTSession.js.map +1 -0
- package/lib/module/video/OTSubscriber.js +175 -0
- package/lib/module/video/OTSubscriber.js.map +1 -0
- package/lib/module/video/contexts/OTContext.js +4 -0
- package/lib/module/video/contexts/OTContext.js.map +1 -0
- package/lib/module/video/helpers/OTHelper.js +82 -0
- package/lib/module/video/helpers/OTHelper.js.map +1 -0
- package/lib/module/video/helpers/OTPublisherHelper.js +110 -0
- package/lib/module/video/helpers/OTPublisherHelper.js.map +1 -0
- package/lib/module/video/helpers/OTSessionHelper.js +195 -0
- package/lib/module/video/helpers/OTSessionHelper.js.map +1 -0
- package/lib/module/video/helpers/OTSubscriberHelper.js +112 -0
- package/lib/module/video/helpers/OTSubscriberHelper.js.map +1 -0
- package/lib/module/video/index.js +7 -0
- package/lib/module/video/index.js.map +1 -0
- package/lib/module/video/views/OTPublisherView.js +18 -0
- package/lib/module/video/views/OTPublisherView.js.map +1 -0
- package/lib/module/video/views/OTSubscriberView.js +17 -0
- package/lib/module/video/views/OTSubscriberView.js.map +1 -0
- package/lib/typescript/src/connection.d.ts +40 -0
- package/lib/typescript/src/connection.d.ts.map +1 -0
- package/lib/typescript/src/data.d.ts +7 -0
- package/lib/typescript/src/data.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +12 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/scoket.d.ts +100 -0
- package/lib/typescript/src/scoket.d.ts.map +1 -0
- package/lib/typescript/src/service.d.ts +9 -0
- package/lib/typescript/src/service.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +22 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +178 -0
- package/react-native-altibbi.podspec +46 -0
- package/src/connection.ts +255 -0
- package/src/data.ts +21 -0
- package/src/index.tsx +80 -0
- package/src/scoket.ts +365 -0
- package/src/service.ts +20 -0
- package/src/types.ts +22 -0
- package/src/video/OT.js +65 -0
- package/src/video/OTError.js +14 -0
- package/src/video/OTPublisher.js +193 -0
- package/src/video/OTSession.js +168 -0
- package/src/video/OTSubscriber.js +148 -0
- package/src/video/contexts/OTContext.js +5 -0
- package/src/video/helpers/OTHelper.js +91 -0
- package/src/video/helpers/OTPublisherHelper.js +122 -0
- package/src/video/helpers/OTSessionHelper.js +233 -0
- package/src/video/helpers/OTSubscriberHelper.js +125 -0
- package/src/video/index.js +13 -0
- package/src/video/views/OTPublisherView.js +19 -0
- package/src/video/views/OTSubscriberView.js +18 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//
|
|
2
|
+
// OTSubscriber.m
|
|
3
|
+
// OpenTokReactNative
|
|
4
|
+
//
|
|
5
|
+
// Created by Manik Sachdeva on 1/18/18.
|
|
6
|
+
// Copyright © 2018 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
#import <React/RCTViewManager.h>
|
|
11
|
+
|
|
12
|
+
@interface RCT_EXTERN_MODULE(OTSubscriberSwift, RCTViewManager)
|
|
13
|
+
RCT_EXPORT_VIEW_PROPERTY(streamId, NSString)
|
|
14
|
+
@end
|
|
15
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//
|
|
2
|
+
// OTSubscriberManager.swift
|
|
3
|
+
// OpenTokReactNative
|
|
4
|
+
//
|
|
5
|
+
// Created by Manik Sachdeva on 1/18/18.
|
|
6
|
+
// Copyright © 2018 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
|
|
11
|
+
@objc(OTSubscriberSwift)
|
|
12
|
+
class OTSubscriberManager: RCTViewManager {
|
|
13
|
+
override func view() -> UIView {
|
|
14
|
+
return OTSubscriberView();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override static func requiresMainQueueSetup() -> Bool {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//
|
|
2
|
+
// OTSubscriberView.swift
|
|
3
|
+
// OpenTokReactNative
|
|
4
|
+
//
|
|
5
|
+
// Created by Manik Sachdeva on 1/18/18.
|
|
6
|
+
// Copyright © 2018 Facebook. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
|
|
11
|
+
@objc(OTSubscriberView)
|
|
12
|
+
class OTSubscriberView: UIView {
|
|
13
|
+
@objc var streamId: NSString?
|
|
14
|
+
override init(frame: CGRect) {
|
|
15
|
+
super.init(frame: frame)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
required init?(coder aDecoder: NSCoder) {
|
|
19
|
+
fatalError("init(coder:) has not been implemented")
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
override func layoutSubviews() {
|
|
23
|
+
if let subscriberView = OTRN.sharedState.subscribers[streamId! as String]?.view {
|
|
24
|
+
subscriberView.frame = self.bounds
|
|
25
|
+
addSubview(subscriberView)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//
|
|
2
|
+
// OpenTokReactNative.h
|
|
3
|
+
// OpenTokReactNative
|
|
4
|
+
//
|
|
5
|
+
// Created by Manik Sachdeva on 5/16/18.
|
|
6
|
+
// Copyright © 2018 TokBox Inc. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
|
|
11
|
+
@interface OpenTokReactNative : NSObject
|
|
12
|
+
|
|
13
|
+
@end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
#import <React/RCTEventEmitter.h>
|
|
3
|
+
|
|
4
|
+
@interface RCT_EXTERN_MODULE(SocketReactNative, RCTEventEmitter)
|
|
5
|
+
|
|
6
|
+
RCT_EXTERN_METHOD(initialize:(NSDictionary *)args
|
|
7
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
8
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
9
|
+
|
|
10
|
+
RCT_EXTERN_METHOD(connect:(RCTPromiseResolveBlock)resolve
|
|
11
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
12
|
+
|
|
13
|
+
RCT_EXTERN_METHOD(disconnect:(RCTPromiseResolveBlock)resolve
|
|
14
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
15
|
+
|
|
16
|
+
RCT_EXTERN_METHOD(subscribe:(NSString*)channelName
|
|
17
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
18
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
19
|
+
|
|
20
|
+
RCT_EXTERN_METHOD(unsubscribe:(NSString*)channelName
|
|
21
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
22
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
23
|
+
|
|
24
|
+
RCT_EXTERN_METHOD(trigger:(NSString*)channelName
|
|
25
|
+
eventName:(NSString*)eventName
|
|
26
|
+
data:id
|
|
27
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
28
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
29
|
+
|
|
30
|
+
RCT_EXTERN_METHOD(onAuthorizer:(NSString*)channelName
|
|
31
|
+
socketID:(NSString*)socketID
|
|
32
|
+
data:(NSDictionary*)data
|
|
33
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
34
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
35
|
+
|
|
36
|
+
RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(getSocketId)
|
|
37
|
+
|
|
38
|
+
@end
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import PusherSwift
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
@objc(SocketReactNative)
|
|
5
|
+
@objcMembers class SocketReactNative: RCTEventEmitter, PusherDelegate, Authorizer {
|
|
6
|
+
private static var shared: SocketReactNative!
|
|
7
|
+
private static var pusher: Pusher!
|
|
8
|
+
|
|
9
|
+
private var authorizerCompletionHandlers = [String: ([String:String]) -> Void]()
|
|
10
|
+
private var authorizerCompletionHandlerTimeout = 10 // seconds
|
|
11
|
+
|
|
12
|
+
private let subscriptionErrorType = "SubscriptionError"
|
|
13
|
+
private let authErrorType = "AuthError"
|
|
14
|
+
private let socketEventPrefix = "SocketReactNative"
|
|
15
|
+
|
|
16
|
+
override init() {
|
|
17
|
+
super.init()
|
|
18
|
+
|
|
19
|
+
SocketReactNative.shared = self
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
override func supportedEvents() -> [String]! {
|
|
23
|
+
return ["\(socketEventPrefix):onConnectionStateChange",
|
|
24
|
+
"\(socketEventPrefix):onSubscriptionError",
|
|
25
|
+
"\(socketEventPrefix):onSubscriptionCount",
|
|
26
|
+
"\(socketEventPrefix):onAuthorizer",
|
|
27
|
+
"\(socketEventPrefix):onError",
|
|
28
|
+
"\(socketEventPrefix):onDecryptionFailure",
|
|
29
|
+
"\(socketEventPrefix):onEvent",
|
|
30
|
+
"\(socketEventPrefix):onMemberAdded",
|
|
31
|
+
"\(socketEventPrefix):onMemberRemoved"]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private func callback(name:String, body:Any) -> Void {
|
|
35
|
+
let socketEventName = "\(socketEventPrefix):\(name)"
|
|
36
|
+
SocketReactNative.shared.sendEvent(withName:socketEventName, body:body)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
func initialize(_ args:[String: Any], resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
|
|
40
|
+
if SocketReactNative.pusher != nil {
|
|
41
|
+
SocketReactNative.pusher.unsubscribeAll()
|
|
42
|
+
SocketReactNative.pusher.disconnect()
|
|
43
|
+
}
|
|
44
|
+
var authMethod:AuthMethod = .noMethod
|
|
45
|
+
if args["authEndpoint"] is String {
|
|
46
|
+
authMethod = .endpoint(authEndpoint: args["authEndpoint"] as! String)
|
|
47
|
+
} else if args["authorizer"] is Bool {
|
|
48
|
+
authMethod = .authorizer(authorizer: SocketReactNative.shared)
|
|
49
|
+
}
|
|
50
|
+
var host:PusherHost = .defaultHost
|
|
51
|
+
if args["host"] is String {
|
|
52
|
+
host = .host(args["host"] as! String)
|
|
53
|
+
} else if args["cluster"] != nil {
|
|
54
|
+
host = .cluster(args["cluster"] as! String)
|
|
55
|
+
}
|
|
56
|
+
var useTLS:Bool = true
|
|
57
|
+
if args["useTLS"] is Bool {
|
|
58
|
+
useTLS = args["useTLS"] as! Bool
|
|
59
|
+
}
|
|
60
|
+
var port:Int
|
|
61
|
+
if useTLS {
|
|
62
|
+
port = 443
|
|
63
|
+
if args["wssPort"] is Int {
|
|
64
|
+
port = args["wssPort"] as! Int
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
port = 80
|
|
68
|
+
if args["wsPort"] is Int {
|
|
69
|
+
port = args["wsPort"] as! Int
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
var activityTimeout:TimeInterval? = nil
|
|
73
|
+
if args["activityTimeout"] is TimeInterval {
|
|
74
|
+
activityTimeout = args["activityTimeout"] as! Double / 1000.0
|
|
75
|
+
}
|
|
76
|
+
var path:String? = nil
|
|
77
|
+
if args["path"] is String {
|
|
78
|
+
path = (args["path"] as! String)
|
|
79
|
+
}
|
|
80
|
+
let options = PusherClientOptions(
|
|
81
|
+
authMethod: authMethod,
|
|
82
|
+
host: host,
|
|
83
|
+
port: port,
|
|
84
|
+
path: path,
|
|
85
|
+
useTLS: useTLS,
|
|
86
|
+
activityTimeout: activityTimeout
|
|
87
|
+
)
|
|
88
|
+
SocketReactNative.pusher = Pusher(key: args["apiKey"] as! String, options: options)
|
|
89
|
+
if args["maxReconnectionAttempts"] is Int {
|
|
90
|
+
SocketReactNative.pusher.connection.reconnectAttemptsMax = (args["maxReconnectionAttempts"] as! Int)
|
|
91
|
+
}
|
|
92
|
+
if args["maxReconnectGapInSeconds"] is TimeInterval {
|
|
93
|
+
SocketReactNative.pusher.connection.maxReconnectGapInSeconds = (args["maxReconnectGapInSeconds"] as! TimeInterval)
|
|
94
|
+
}
|
|
95
|
+
if args["pongTimeout"] is Int {
|
|
96
|
+
SocketReactNative.pusher.connection.pongResponseTimeoutInterval = args["pongTimeout"] as! TimeInterval / 1000.0
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if let authorizerTimeoutInSeconds = args["authorizerTimeoutInSeconds"] as? Int {
|
|
100
|
+
SocketReactNative.shared.authorizerCompletionHandlerTimeout = authorizerTimeoutInSeconds
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
SocketReactNative.pusher.connection.delegate = SocketReactNative.shared
|
|
104
|
+
SocketReactNative.pusher.bind(eventCallback: onEvent)
|
|
105
|
+
resolve(nil)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
override static func requiresMainQueueSetup() -> Bool {
|
|
109
|
+
return false
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public func fetchAuthValue(socketID: String, channelName: String, completionHandler: @escaping (PusherAuth?) -> Void) {
|
|
113
|
+
SocketReactNative.shared.callback(name:"onAuthorizer", body: [
|
|
114
|
+
"socketId": socketID,
|
|
115
|
+
"channelName": channelName
|
|
116
|
+
])
|
|
117
|
+
|
|
118
|
+
let key = channelName + socketID
|
|
119
|
+
let authCallback = { (authParams:[String:String]) in
|
|
120
|
+
if let authParam = authParams["auth"] {
|
|
121
|
+
completionHandler(PusherAuth(auth: authParam, channelData: authParams["channel_data"], sharedSecret: authParams["shared_secret"]))
|
|
122
|
+
} else {
|
|
123
|
+
completionHandler(PusherAuth(auth: "<missing_auth_param>:error", channelData: authParams["channel_data"], sharedSecret: authParams["shared_secret"]))
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
authorizerCompletionHandlers[key] = authCallback
|
|
127
|
+
|
|
128
|
+
// the JS thread might not call onAuthorizer – we need to cleanup the completion handler after timeout
|
|
129
|
+
let timeout = DispatchTimeInterval.seconds(SocketReactNative.shared.authorizerCompletionHandlerTimeout)
|
|
130
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + timeout) {
|
|
131
|
+
if let storedAuthHandler = SocketReactNative.shared.authorizerCompletionHandlers.removeValue(forKey: key) {
|
|
132
|
+
storedAuthHandler(["auth": "<authorizer_timeout>:error"])
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public func onAuthorizer(_ channelName: String, socketID: String, data:[String:String], resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
|
|
138
|
+
let key = channelName + socketID
|
|
139
|
+
if let storedAuthHandler = authorizerCompletionHandlers.removeValue(forKey: key) {
|
|
140
|
+
storedAuthHandler(data)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public func changedConnectionState(from old: ConnectionState, to new: ConnectionState) {
|
|
145
|
+
SocketReactNative.shared.callback(name:"onConnectionStateChange", body:[
|
|
146
|
+
"previousState": old.stringValue(),
|
|
147
|
+
"currentState": new.stringValue()
|
|
148
|
+
])
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public func debugLog(message: String) {
|
|
152
|
+
//print("DEBUG:", message)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public func subscribedToChannel(name: String) {
|
|
156
|
+
// Handled by global handler
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
public func failedToSubscribeToChannel(name: String, response: URLResponse?, data: String?, error: NSError?) {
|
|
160
|
+
var code = ""
|
|
161
|
+
var type = subscriptionErrorType
|
|
162
|
+
if let httpResponse = response as? HTTPURLResponse {
|
|
163
|
+
code = String(httpResponse.statusCode)
|
|
164
|
+
type = authErrorType
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
SocketReactNative.shared.callback(name:"onSubscriptionError", body:[
|
|
168
|
+
"message": (error != nil) ? error!.localizedDescription : ((data != nil) ? data! : error.debugDescription),
|
|
169
|
+
"type": type,
|
|
170
|
+
"code": code,
|
|
171
|
+
"channelName": name
|
|
172
|
+
])
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
public func receivedError(error: PusherError) {
|
|
176
|
+
SocketReactNative.shared.callback(
|
|
177
|
+
name:"onError", body:[
|
|
178
|
+
"message": error.message,
|
|
179
|
+
"code": error.code ?? -1,
|
|
180
|
+
"error": error.debugDescription
|
|
181
|
+
]
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
public func failedToDecryptEvent(eventName: String, channelName: String, data: String?) {
|
|
186
|
+
SocketReactNative.shared.callback(
|
|
187
|
+
name:"onDecryptionFailure", body:[
|
|
188
|
+
"eventName": eventName,
|
|
189
|
+
"reason": data
|
|
190
|
+
]
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public func connect(_ resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
|
|
195
|
+
SocketReactNative.pusher.connect()
|
|
196
|
+
resolve(nil)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
public func disconnect(_ resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
|
|
200
|
+
SocketReactNative.pusher.disconnect()
|
|
201
|
+
resolve(nil)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public func getSocketId() -> String? {
|
|
205
|
+
return SocketReactNative.pusher.connection.socketId
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
func onEvent(event:PusherEvent) {
|
|
209
|
+
var userId:String? = nil
|
|
210
|
+
var mappedEventName:String? = nil
|
|
211
|
+
if event.eventName == "pusher:subscription_succeeded" {
|
|
212
|
+
if let channel = SocketReactNative.pusher.connection.channels.findPresence(name: event.channelName!) {
|
|
213
|
+
userId = channel.myId
|
|
214
|
+
}
|
|
215
|
+
mappedEventName = "pusher_internal:subscription_succeeded"
|
|
216
|
+
}
|
|
217
|
+
SocketReactNative.shared.callback(
|
|
218
|
+
name:"onEvent",body:[
|
|
219
|
+
"channelName": event.channelName,
|
|
220
|
+
"eventName": mappedEventName ?? event.eventName,
|
|
221
|
+
"userId": event.userId ?? userId,
|
|
222
|
+
"data": event.data
|
|
223
|
+
]
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
func subscribe(_ channelName:String, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
|
|
228
|
+
if channelName.hasPrefix("presence-") {
|
|
229
|
+
let onMemberAdded:(PusherPresenceChannelMember) -> () = { user in
|
|
230
|
+
SocketReactNative.shared.callback(name:"onMemberAdded", body: [
|
|
231
|
+
"channelName": channelName,
|
|
232
|
+
"user": ["userId": user.userId, "userInfo": user.userInfo ]
|
|
233
|
+
])
|
|
234
|
+
}
|
|
235
|
+
let onMemberRemoved:(PusherPresenceChannelMember) -> () = { user in
|
|
236
|
+
SocketReactNative.shared.callback(name:"onMemberRemoved", body: [
|
|
237
|
+
"channelName": channelName,
|
|
238
|
+
"user": ["userId": user.userId, "userInfo": user.userInfo ]
|
|
239
|
+
])
|
|
240
|
+
}
|
|
241
|
+
SocketReactNative.pusher.subscribeToPresenceChannel(
|
|
242
|
+
channelName: channelName,
|
|
243
|
+
onMemberAdded: onMemberAdded,
|
|
244
|
+
onMemberRemoved: onMemberRemoved
|
|
245
|
+
)
|
|
246
|
+
} else {
|
|
247
|
+
let onSubscriptionCount:(Int) -> () = { subscriptionCount in
|
|
248
|
+
SocketReactNative.shared.callback(
|
|
249
|
+
name:"onEvent",body:[
|
|
250
|
+
"channelName": channelName,
|
|
251
|
+
"eventName": "pusher_internal:subscription_count",
|
|
252
|
+
"userId": nil,
|
|
253
|
+
"data": [
|
|
254
|
+
"subscription_count": subscriptionCount
|
|
255
|
+
]
|
|
256
|
+
]
|
|
257
|
+
)
|
|
258
|
+
}
|
|
259
|
+
SocketReactNative.pusher.subscribe(channelName: channelName,
|
|
260
|
+
onSubscriptionCountChanged: onSubscriptionCount)
|
|
261
|
+
}
|
|
262
|
+
resolve(nil)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
func unsubscribe(_ channelName:String, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
|
|
266
|
+
SocketReactNative.pusher.unsubscribe(channelName)
|
|
267
|
+
resolve(nil)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
func trigger(_ channelName:String, eventName:String, data:Any, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
|
|
271
|
+
if let channel = SocketReactNative.pusher.connection.channels.find(name: channelName) {
|
|
272
|
+
channel.trigger(eventName: eventName, data: data)
|
|
273
|
+
}
|
|
274
|
+
resolve(nil)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
//
|
|
2
|
+
// EventUtils.swift
|
|
3
|
+
// OpenTokReactNative
|
|
4
|
+
//
|
|
5
|
+
// Created by Manik Sachdeva on 11/3/18.
|
|
6
|
+
// Copyright © 2018 TokBox Inc. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
|
|
11
|
+
class EventUtils {
|
|
12
|
+
|
|
13
|
+
static var sessionPreface: String = "session:";
|
|
14
|
+
static var publisherPreface: String = "publisher:";
|
|
15
|
+
static var subscriberPreface: String = "subscriber:";
|
|
16
|
+
|
|
17
|
+
static func prepareJSConnectionEventData(_ connection: OTConnection) -> Dictionary<String, Any> {
|
|
18
|
+
var connectionInfo: Dictionary<String, Any> = [:];
|
|
19
|
+
guard connection != nil else { return connectionInfo }
|
|
20
|
+
connectionInfo["connectionId"] = connection.connectionId;
|
|
21
|
+
connectionInfo["creationTime"] = convertDateToString(connection.creationTime);
|
|
22
|
+
connectionInfo["data"] = connection.data;
|
|
23
|
+
return connectionInfo;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static func prepareJSStreamEventData(_ stream: OTStream) -> Dictionary<String, Any> {
|
|
27
|
+
var streamInfo: Dictionary<String, Any> = [:];
|
|
28
|
+
guard OTRN.sharedState.sessions[stream.session.sessionId] != nil else { return streamInfo }
|
|
29
|
+
streamInfo["streamId"] = stream.streamId;
|
|
30
|
+
streamInfo["name"] = stream.name;
|
|
31
|
+
streamInfo["connectionId"] = stream.connection.connectionId;
|
|
32
|
+
streamInfo["connection"] = prepareJSConnectionEventData(stream.connection);
|
|
33
|
+
streamInfo["hasAudio"] = stream.hasAudio;
|
|
34
|
+
streamInfo["sessionId"] = stream.session.sessionId;
|
|
35
|
+
streamInfo["hasVideo"] = stream.hasVideo;
|
|
36
|
+
streamInfo["creationTime"] = convertDateToString(stream.creationTime);
|
|
37
|
+
streamInfo["height"] = stream.videoDimensions.height;
|
|
38
|
+
streamInfo["width"] = stream.videoDimensions.width;
|
|
39
|
+
streamInfo["videoType"] = stream.videoType == OTStreamVideoType.screen ? "screen" : "camera"
|
|
40
|
+
return streamInfo;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static func prepareJSErrorEventData(_ error: OTError) -> Dictionary<String, Any> {
|
|
44
|
+
var errorInfo: Dictionary<String, Any> = [:];
|
|
45
|
+
errorInfo["code"] = error.code;
|
|
46
|
+
errorInfo["message"] = error.localizedDescription;
|
|
47
|
+
return errorInfo;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static func prepareStreamPropertyChangedEventData(_ changedProperty: String, oldValue: Any, newValue: Any, stream: Dictionary<String, Any>) -> Dictionary<String, Any> {
|
|
51
|
+
var streamPropertyEventData: Dictionary<String, Any> = [:];
|
|
52
|
+
streamPropertyEventData["oldValue"] = oldValue;
|
|
53
|
+
streamPropertyEventData["newValue"] = newValue;
|
|
54
|
+
streamPropertyEventData["stream"] = stream;
|
|
55
|
+
streamPropertyEventData["changedProperty"] = changedProperty;
|
|
56
|
+
return streamPropertyEventData
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static func preparePublisherRtcStats(_ rtcStatsReport: [OTPublisherRtcStats]) -> [Dictionary<String, Any>] {
|
|
60
|
+
var statsArray:[Dictionary<String, Any>] = [];
|
|
61
|
+
for value in rtcStatsReport {
|
|
62
|
+
var stats:Dictionary<String, Any> = [:];
|
|
63
|
+
stats["connectionId"] = value.connectionId;
|
|
64
|
+
stats["jsonArrayOfReports"] = value.jsonArrayOfReports;
|
|
65
|
+
statsArray.append(stats);
|
|
66
|
+
}
|
|
67
|
+
return statsArray;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static func preparePublisherVideoNetworkStats(_ videoStats: [OTPublisherKitVideoNetworkStats]) -> [Dictionary<String, Any>] {
|
|
71
|
+
var statsArray:[Dictionary<String, Any>] = [];
|
|
72
|
+
for value in videoStats {
|
|
73
|
+
var stats: Dictionary<String, Any> = [:];
|
|
74
|
+
stats["connectionId"] = value.connectionId;
|
|
75
|
+
stats["subscriberId"] = value.subscriberId;
|
|
76
|
+
stats["videoPacketsLost"] = value.videoPacketsLost;
|
|
77
|
+
stats["videoBytesSent"] = value.videoBytesSent;
|
|
78
|
+
stats["videoPacketsSent"] = value.videoPacketsSent;
|
|
79
|
+
stats["timestamp"] = value.timestamp;
|
|
80
|
+
statsArray.append(stats);
|
|
81
|
+
}
|
|
82
|
+
return statsArray;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static func preparePublisherAudioNetworkStats(_ audioStats: [OTPublisherKitAudioNetworkStats]) -> [Dictionary<String, Any>] {
|
|
86
|
+
var statsArray:[Dictionary<String, Any>] = [];
|
|
87
|
+
for value in audioStats {
|
|
88
|
+
var stats: Dictionary<String, Any> = [:];
|
|
89
|
+
stats["connectionId"] = value.connectionId;
|
|
90
|
+
stats["subscriberId"] = value.subscriberId;
|
|
91
|
+
stats["audioPacketsLost"] = value.audioPacketsLost;
|
|
92
|
+
stats["audioPacketsSent"] = value.audioPacketsSent;
|
|
93
|
+
stats["audioBytesSent"] = value.audioBytesSent;
|
|
94
|
+
stats["timestamp"] = value.timestamp;
|
|
95
|
+
statsArray.append(stats);
|
|
96
|
+
}
|
|
97
|
+
return statsArray;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static func prepareSubscriberVideoNetworkStatsEventData(_ videoStats: OTSubscriberKitVideoNetworkStats) -> Dictionary<String, Any> {
|
|
101
|
+
var videoStatsEventData: Dictionary<String, Any> = [:];
|
|
102
|
+
videoStatsEventData["videoPacketsLost"] = videoStats.videoPacketsLost;
|
|
103
|
+
videoStatsEventData["videoBytesReceived"] = videoStats.videoBytesReceived;
|
|
104
|
+
videoStatsEventData["videoPacketsReceived"] = videoStats.videoPacketsReceived;
|
|
105
|
+
videoStatsEventData["timestamp"] = videoStats.timestamp;
|
|
106
|
+
return videoStatsEventData;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
static func prepareSubscriberAudioNetworkStatsEventData(_ audioStats: OTSubscriberKitAudioNetworkStats) -> Dictionary<String, Any> {
|
|
110
|
+
var audioStatsEventData: Dictionary<String, Any> = [:];
|
|
111
|
+
audioStatsEventData["audioPacketsLost"] = audioStats.audioPacketsLost;
|
|
112
|
+
audioStatsEventData["audioBytesReceived"] = audioStats.audioBytesReceived;
|
|
113
|
+
audioStatsEventData["audioPacketsReceived"] = audioStats.audioPacketsReceived;
|
|
114
|
+
audioStatsEventData["timestamp"] = audioStats.timestamp;
|
|
115
|
+
return audioStatsEventData;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static func prepareJSSessionEventData(_ session: OTSession) -> Dictionary<String, Any> {
|
|
119
|
+
var sessionInfo: Dictionary<String, Any> = [:];
|
|
120
|
+
sessionInfo["sessionId"] = session.sessionId;
|
|
121
|
+
guard let connection = session.connection else { return sessionInfo };
|
|
122
|
+
sessionInfo["connection"] = prepareJSConnectionEventData(connection);
|
|
123
|
+
return sessionInfo;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
static func getSupportedEvents() -> [String] {
|
|
127
|
+
return ["\(sessionPreface)streamCreated", "\(sessionPreface)streamDestroyed", "\(sessionPreface)sessionDidConnect", "\(sessionPreface)sessionDidDisconnect", "\(sessionPreface)connectionCreated", "\(sessionPreface)connectionDestroyed", "\(sessionPreface)didFailWithError", "\(publisherPreface)streamCreated", "\(sessionPreface)signal", "\(publisherPreface)streamDestroyed", "\(publisherPreface)didFailWithError", "\(publisherPreface)audioLevelUpdated", "\(publisherPreface)rtcStatsReport", "\(subscriberPreface)subscriberDidConnect", "\(subscriberPreface)subscriberDidDisconnect", "\(subscriberPreface)didFailWithError", "\(subscriberPreface)videoNetworkStatsUpdated", "\(subscriberPreface)audioNetworkStatsUpdated", "\(subscriberPreface)audioLevelUpdated", "\(subscriberPreface)subscriberVideoEnabled", "\(subscriberPreface)subscriberVideoDisabled", "\(subscriberPreface)subscriberVideoDisableWarning", "\(subscriberPreface)subscriberVideoDisableWarningLifted", "\(subscriberPreface)subscriberVideoDataReceived", "\(sessionPreface)archiveStartedWithId", "\(sessionPreface)archiveStoppedWithId", "\(sessionPreface)sessionDidBeginReconnecting", "\(sessionPreface)sessionDidReconnect", "\(sessionPreface)streamPropertyChanged", "\(subscriberPreface)subscriberDidReconnect", "\(subscriberPreface)subscriberCaptionReceived"];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static func convertDateToString(_ creationTime: Date) -> String {
|
|
131
|
+
let dateFormatter: DateFormatter = DateFormatter();
|
|
132
|
+
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss";
|
|
133
|
+
dateFormatter.timeZone = TimeZone(abbreviation: "UTC");
|
|
134
|
+
return dateFormatter.string(from:creationTime);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static func createErrorMessage(_ message: String) -> Dictionary<String, String> {
|
|
138
|
+
var errorInfo: Dictionary<String, String> = [:]
|
|
139
|
+
errorInfo["message"] = message
|
|
140
|
+
return errorInfo
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Utils.swift
|
|
3
|
+
// OpenTokReactNative
|
|
4
|
+
//
|
|
5
|
+
// Created by Manik Sachdeva on 11/3/18.
|
|
6
|
+
// Copyright © 2018 TokBox Inc. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import Foundation
|
|
10
|
+
|
|
11
|
+
class Utils {
|
|
12
|
+
static func sanitizeCameraResolution(_ resolution: Any) -> OTCameraCaptureResolution {
|
|
13
|
+
guard let cameraResolution = resolution as? String else { return .medium };
|
|
14
|
+
switch cameraResolution {
|
|
15
|
+
case "HIGH_1080P":
|
|
16
|
+
return .high1080p;
|
|
17
|
+
case "HIGH":
|
|
18
|
+
return .high;
|
|
19
|
+
case "LOW":
|
|
20
|
+
return .low;
|
|
21
|
+
default:
|
|
22
|
+
return .medium;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static func sanitizeFrameRate(_ frameRate: Any) -> OTCameraCaptureFrameRate {
|
|
27
|
+
guard let cameraFrameRate = frameRate as? Int else { return OTCameraCaptureFrameRate(rawValue: 30)!; }
|
|
28
|
+
return OTCameraCaptureFrameRate(rawValue: cameraFrameRate)!;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static func sanitizePreferredFrameRate(_ frameRate: Any) -> Float {
|
|
32
|
+
guard let sanitizedFrameRate = frameRate as? Float else { return Float.greatestFiniteMagnitude; }
|
|
33
|
+
return sanitizedFrameRate;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static func sanitizePreferredResolution(_ resolution: Any) -> CGSize {
|
|
37
|
+
guard let preferredRes = resolution as? Dictionary<String, Any> else { return CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude) };
|
|
38
|
+
return CGSize(width: preferredRes["width"] as! CGFloat, height: preferredRes["height"] as! CGFloat);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static func sanitizeBooleanProperty(_ property: Any) -> Bool {
|
|
42
|
+
guard let prop = property as? Bool else { return true; }
|
|
43
|
+
return prop;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static func sanitizeStringProperty(_ property: Any) -> String {
|
|
47
|
+
guard let prop = property as? String else { return ""; }
|
|
48
|
+
return prop;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static func getPublisherId(_ publisher: OTPublisher) -> String {
|
|
52
|
+
let publisherIds = OTRN.sharedState.publishers.filter {$0.value == publisher}
|
|
53
|
+
guard let publisherId = publisherIds.first else { return ""; }
|
|
54
|
+
return publisherId.key;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
static func convertOTSubscriberVideoEventReasonToString(_ reason: OTSubscriberVideoEventReason) -> String {
|
|
59
|
+
switch reason {
|
|
60
|
+
case OTSubscriberVideoEventReason.publisherPropertyChanged:
|
|
61
|
+
return "PublisherPropertyChanged"
|
|
62
|
+
case OTSubscriberVideoEventReason.subscriberPropertyChanged:
|
|
63
|
+
return "SubscriberPropertyChanged"
|
|
64
|
+
case OTSubscriberVideoEventReason.qualityChanged:
|
|
65
|
+
return "QualityChanged"
|
|
66
|
+
case OTSubscriberVideoEventReason.codecNotSupported:
|
|
67
|
+
return "CodecNotSupported"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static func sanitizeIncludeServer(_ value: Any) -> OTSessionICEIncludeServers {
|
|
72
|
+
var includeServers = OTSessionICEIncludeServers.all;
|
|
73
|
+
if let includeServer = value as? String, includeServer == "custom" {
|
|
74
|
+
includeServers = OTSessionICEIncludeServers.custom;
|
|
75
|
+
}
|
|
76
|
+
return includeServers;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static func sanitizeTransportPolicy(_ value: Any) -> OTSessionICETransportPolicy {
|
|
80
|
+
var transportPolicy = OTSessionICETransportPolicy.all;
|
|
81
|
+
if let policy = value as? String, policy == "relay" {
|
|
82
|
+
transportPolicy = OTSessionICETransportPolicy.relay;
|
|
83
|
+
}
|
|
84
|
+
return transportPolicy;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static func sanitiseServerList(_ serverList: Any) -> [(urls: [String], userName: String, credential: String)] {
|
|
88
|
+
var iceServerList: [([String], String, String)] = []
|
|
89
|
+
|
|
90
|
+
if let serverList = serverList as? [[String: Any]] {
|
|
91
|
+
for server in serverList {
|
|
92
|
+
if let urls = server["urls"] as? [String], let username = server["username"] as? String, let credential = server["credential"] as? String {
|
|
93
|
+
iceServerList.append((urls, username, credential))
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return iceServerList
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static func sanitizeIceServer(_ serverList: Any, _ transportPolicy: Any, _ includeServer: Any) -> OTSessionICEConfig {
|
|
101
|
+
let myICEServerConfiguration: OTSessionICEConfig = OTSessionICEConfig();
|
|
102
|
+
myICEServerConfiguration.includeServers = Utils.sanitizeIncludeServer(includeServer);
|
|
103
|
+
myICEServerConfiguration.transportPolicy = Utils.sanitizeTransportPolicy(transportPolicy);
|
|
104
|
+
let serverList = Utils.sanitiseServerList(serverList);
|
|
105
|
+
for server in serverList {
|
|
106
|
+
for url in server.urls {
|
|
107
|
+
myICEServerConfiguration.addICEServer(withURL: url, userName: server.userName, credential: server.credential, error: nil);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return myICEServerConfiguration;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static func convertVideoContentHint(_ videoContentHint: Any) -> OTVideoContentHint {
|
|
114
|
+
guard let contentHint = videoContentHint as? String else { return OTVideoContentHint.none };
|
|
115
|
+
switch contentHint {
|
|
116
|
+
case "motion":
|
|
117
|
+
return OTVideoContentHint.motion
|
|
118
|
+
case "detail":
|
|
119
|
+
return OTVideoContentHint.detail
|
|
120
|
+
case "text":
|
|
121
|
+
return OTVideoContentHint.text
|
|
122
|
+
default:
|
|
123
|
+
return OTVideoContentHint.none
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|