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.
Files changed (150) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +190 -0
  3. package/android/build.gradle +104 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/AndroidManifest.xml +3 -0
  6. package/android/src/main/AndroidManifestNew.xml +2 -0
  7. package/android/src/main/java/com/altibbi/AltibbiModule.kt +18 -0
  8. package/android/src/main/java/com/altibbi/AltibbiPackage.kt +18 -0
  9. package/android/src/main/java/com/altibbi/OTCustomAudioDevice.java +1146 -0
  10. package/android/src/main/java/com/altibbi/OTPublisherLayout.java +61 -0
  11. package/android/src/main/java/com/altibbi/OTPublisherViewManager.java +30 -0
  12. package/android/src/main/java/com/altibbi/OTRN.java +101 -0
  13. package/android/src/main/java/com/altibbi/OTScreenCapturer.java +120 -0
  14. package/android/src/main/java/com/altibbi/OTSessionManager.java +1281 -0
  15. package/android/src/main/java/com/altibbi/OTSubscriberLayout.java +68 -0
  16. package/android/src/main/java/com/altibbi/OTSubscriberViewManager.java +30 -0
  17. package/android/src/main/java/com/altibbi/Socket.kt +294 -0
  18. package/android/src/main/java/com/altibbi/SocketEventEmitter.kt +25 -0
  19. package/android/src/main/java/com/altibbi/utils/EventUtils.java +189 -0
  20. package/android/src/main/java/com/altibbi/utils/Utils.java +135 -0
  21. package/ios/Altibbi-Bridging-Header.h +6 -0
  22. package/ios/Altibbi.mm +10 -0
  23. package/ios/Altibbi.swift +4 -0
  24. package/ios/OTCustomAudioDriver.swift +696 -0
  25. package/ios/OTPublisher.m +16 -0
  26. package/ios/OTPublisherManager.swift +21 -0
  27. package/ios/OTPublisherView.swift +28 -0
  28. package/ios/OTRN.swift +27 -0
  29. package/ios/OTScreenCapture.h +27 -0
  30. package/ios/OTScreenCapture.m +171 -0
  31. package/ios/OTSessionManager.m +127 -0
  32. package/ios/OTSessionManager.swift +866 -0
  33. package/ios/OTSubscriber.m +15 -0
  34. package/ios/OTSubscriberManager.swift +21 -0
  35. package/ios/OTSubscriberView.swift +29 -0
  36. package/ios/OpenTokReactNative.h +13 -0
  37. package/ios/OpenTokReactNative.m +13 -0
  38. package/ios/SocketReactNative.m +38 -0
  39. package/ios/SocketReactNative.swift +276 -0
  40. package/ios/Utils/EventUtils.swift +143 -0
  41. package/ios/Utils/Utils.swift +126 -0
  42. package/lib/commonjs/connection.js +200 -0
  43. package/lib/commonjs/connection.js.map +1 -0
  44. package/lib/commonjs/data.js +12 -0
  45. package/lib/commonjs/data.js.map +1 -0
  46. package/lib/commonjs/index.js +275 -0
  47. package/lib/commonjs/index.js.map +1 -0
  48. package/lib/commonjs/scoket.js +245 -0
  49. package/lib/commonjs/scoket.js.map +1 -0
  50. package/lib/commonjs/service.js +21 -0
  51. package/lib/commonjs/service.js.map +1 -0
  52. package/lib/commonjs/types.js +2 -0
  53. package/lib/commonjs/types.js.map +1 -0
  54. package/lib/commonjs/video/OT.js +57 -0
  55. package/lib/commonjs/video/OT.js.map +1 -0
  56. package/lib/commonjs/video/OTError.js +17 -0
  57. package/lib/commonjs/video/OTError.js.map +1 -0
  58. package/lib/commonjs/video/OTPublisher.js +171 -0
  59. package/lib/commonjs/video/OTPublisher.js.map +1 -0
  60. package/lib/commonjs/video/OTSession.js +205 -0
  61. package/lib/commonjs/video/OTSession.js.map +1 -0
  62. package/lib/commonjs/video/OTSubscriber.js +185 -0
  63. package/lib/commonjs/video/OTSubscriber.js.map +1 -0
  64. package/lib/commonjs/video/contexts/OTContext.js +11 -0
  65. package/lib/commonjs/video/contexts/OTContext.js.map +1 -0
  66. package/lib/commonjs/video/helpers/OTHelper.js +92 -0
  67. package/lib/commonjs/video/helpers/OTHelper.js.map +1 -0
  68. package/lib/commonjs/video/helpers/OTPublisherHelper.js +117 -0
  69. package/lib/commonjs/video/helpers/OTPublisherHelper.js.map +1 -0
  70. package/lib/commonjs/video/helpers/OTSessionHelper.js +206 -0
  71. package/lib/commonjs/video/helpers/OTSessionHelper.js.map +1 -0
  72. package/lib/commonjs/video/helpers/OTSubscriberHelper.js +121 -0
  73. package/lib/commonjs/video/helpers/OTSubscriberHelper.js.map +1 -0
  74. package/lib/commonjs/video/index.js +42 -0
  75. package/lib/commonjs/video/index.js.map +1 -0
  76. package/lib/commonjs/video/views/OTPublisherView.js +26 -0
  77. package/lib/commonjs/video/views/OTPublisherView.js.map +1 -0
  78. package/lib/commonjs/video/views/OTSubscriberView.js +25 -0
  79. package/lib/commonjs/video/views/OTSubscriberView.js.map +1 -0
  80. package/lib/module/connection.js +180 -0
  81. package/lib/module/connection.js.map +1 -0
  82. package/lib/module/data.js +6 -0
  83. package/lib/module/data.js.map +1 -0
  84. package/lib/module/index.js +12 -0
  85. package/lib/module/index.js.map +1 -0
  86. package/lib/module/scoket.js +235 -0
  87. package/lib/module/scoket.js.map +1 -0
  88. package/lib/module/service.js +14 -0
  89. package/lib/module/service.js.map +1 -0
  90. package/lib/module/types.js +2 -0
  91. package/lib/module/types.js.map +1 -0
  92. package/lib/module/video/OT.js +49 -0
  93. package/lib/module/video/OT.js.map +1 -0
  94. package/lib/module/video/OTError.js +10 -0
  95. package/lib/module/video/OTError.js.map +1 -0
  96. package/lib/module/video/OTPublisher.js +162 -0
  97. package/lib/module/video/OTPublisher.js.map +1 -0
  98. package/lib/module/video/OTSession.js +195 -0
  99. package/lib/module/video/OTSession.js.map +1 -0
  100. package/lib/module/video/OTSubscriber.js +175 -0
  101. package/lib/module/video/OTSubscriber.js.map +1 -0
  102. package/lib/module/video/contexts/OTContext.js +4 -0
  103. package/lib/module/video/contexts/OTContext.js.map +1 -0
  104. package/lib/module/video/helpers/OTHelper.js +82 -0
  105. package/lib/module/video/helpers/OTHelper.js.map +1 -0
  106. package/lib/module/video/helpers/OTPublisherHelper.js +110 -0
  107. package/lib/module/video/helpers/OTPublisherHelper.js.map +1 -0
  108. package/lib/module/video/helpers/OTSessionHelper.js +195 -0
  109. package/lib/module/video/helpers/OTSessionHelper.js.map +1 -0
  110. package/lib/module/video/helpers/OTSubscriberHelper.js +112 -0
  111. package/lib/module/video/helpers/OTSubscriberHelper.js.map +1 -0
  112. package/lib/module/video/index.js +7 -0
  113. package/lib/module/video/index.js.map +1 -0
  114. package/lib/module/video/views/OTPublisherView.js +18 -0
  115. package/lib/module/video/views/OTPublisherView.js.map +1 -0
  116. package/lib/module/video/views/OTSubscriberView.js +17 -0
  117. package/lib/module/video/views/OTSubscriberView.js.map +1 -0
  118. package/lib/typescript/src/connection.d.ts +40 -0
  119. package/lib/typescript/src/connection.d.ts.map +1 -0
  120. package/lib/typescript/src/data.d.ts +7 -0
  121. package/lib/typescript/src/data.d.ts.map +1 -0
  122. package/lib/typescript/src/index.d.ts +12 -0
  123. package/lib/typescript/src/index.d.ts.map +1 -0
  124. package/lib/typescript/src/scoket.d.ts +100 -0
  125. package/lib/typescript/src/scoket.d.ts.map +1 -0
  126. package/lib/typescript/src/service.d.ts +9 -0
  127. package/lib/typescript/src/service.d.ts.map +1 -0
  128. package/lib/typescript/src/types.d.ts +22 -0
  129. package/lib/typescript/src/types.d.ts.map +1 -0
  130. package/package.json +178 -0
  131. package/react-native-altibbi.podspec +46 -0
  132. package/src/connection.ts +255 -0
  133. package/src/data.ts +21 -0
  134. package/src/index.tsx +80 -0
  135. package/src/scoket.ts +365 -0
  136. package/src/service.ts +20 -0
  137. package/src/types.ts +22 -0
  138. package/src/video/OT.js +65 -0
  139. package/src/video/OTError.js +14 -0
  140. package/src/video/OTPublisher.js +193 -0
  141. package/src/video/OTSession.js +168 -0
  142. package/src/video/OTSubscriber.js +148 -0
  143. package/src/video/contexts/OTContext.js +5 -0
  144. package/src/video/helpers/OTHelper.js +91 -0
  145. package/src/video/helpers/OTPublisherHelper.js +122 -0
  146. package/src/video/helpers/OTSessionHelper.js +233 -0
  147. package/src/video/helpers/OTSubscriberHelper.js +125 -0
  148. package/src/video/index.js +13 -0
  149. package/src/video/views/OTPublisherView.js +19 -0
  150. package/src/video/views/OTSubscriberView.js +18 -0
@@ -0,0 +1,168 @@
1
+ import React, { Component, Children, cloneElement } from 'react';
2
+ import { View } from 'react-native';
3
+ import { ViewPropTypes } from 'deprecated-react-native-prop-types';
4
+ import PropTypes from 'prop-types';
5
+ import { pick, isNull } from 'underscore';
6
+ import { setNativeEvents, removeNativeEvents, OT } from './OT';
7
+ import { sanitizeSessionEvents, sanitizeSessionOptions, sanitizeSignalData,
8
+ sanitizeCredentials, getConnectionStatus } from './helpers/OTSessionHelper';
9
+ import { handleError } from './OTError';
10
+ import { logOT, getOtrnErrorEventHandler } from './helpers/OTHelper';
11
+ import OTContext from './contexts/OTContext';
12
+
13
+ export default class OTSession extends Component {
14
+ constructor(props) {
15
+ super(props);
16
+ this.state = {
17
+ sessionInfo: null,
18
+ };
19
+ this.otrnEventHandler = getOtrnErrorEventHandler(this.props.eventHandlers);
20
+ this.initComponent();
21
+ }
22
+ initComponent = () => {
23
+ const credentials = pick(this.props, ['apiKey', 'sessionId', 'token']);
24
+ this.sanitizedCredentials = sanitizeCredentials(credentials);
25
+ if (Object.keys(this.sanitizedCredentials).length === 3) {
26
+ const sessionEvents = sanitizeSessionEvents(this.sanitizedCredentials.sessionId, this.props.eventHandlers);
27
+ setNativeEvents(sessionEvents);
28
+ }
29
+ }
30
+ componentDidMount() {
31
+ const sessionOptions = sanitizeSessionOptions(this.props.options);
32
+ const { apiKey, sessionId, token } = this.sanitizedCredentials;
33
+ if (apiKey && sessionId && token) {
34
+ this.createSession(this.sanitizedCredentials, sessionOptions);
35
+ logOT({ apiKey, sessionId, action: 'rn_initialize', proxyUrl: sessionOptions.proxyUrl });
36
+ } else {
37
+ handleError('Please check your OpenTok credentials.');
38
+ }
39
+ }
40
+ componentDidUpdate(previousProps) {
41
+ const useDefault = (value, defaultValue) => (value === undefined ? defaultValue : value);
42
+ const shouldUpdate = (key, defaultValue) => {
43
+ const previous = useDefault(previousProps[key], defaultValue);
44
+ const current = useDefault(this.props[key], defaultValue);
45
+ return previous !== current;
46
+ };
47
+
48
+ const updateSessionProperty = (key, defaultValue) => {
49
+ if (shouldUpdate(key, defaultValue)) {
50
+ const value = useDefault(this.props[key], defaultValue);
51
+ this.signal(value);
52
+ }
53
+ };
54
+
55
+ updateSessionProperty('signal', {});
56
+ }
57
+ componentWillUnmount() {
58
+ this.disconnectSession();
59
+ }
60
+ createSession(credentials, sessionOptions) {
61
+ const { signal } = this.props;
62
+ const { apiKey, sessionId, token } = credentials;
63
+ OT.initSession(apiKey, sessionId, sessionOptions);
64
+ OT.connect(sessionId, token, (error) => {
65
+ if (error) {
66
+ this.otrnEventHandler(error);
67
+ } else {
68
+ OT.getSessionInfo(sessionId, (session) => {
69
+ if (!isNull(session)) {
70
+ const sessionInfo = { ...session, connectionStatus: getConnectionStatus(session.connectionStatus)};
71
+ this.setState({
72
+ sessionInfo,
73
+ });
74
+ logOT({ apiKey, sessionId, action: 'rn_on_connect', proxyUrl: sessionOptions.proxyUrl, connectionId: session.connection.connectionId });
75
+ if (Object.keys(signal).length > 0) {
76
+ this.signal(signal);
77
+ }
78
+ }
79
+ });
80
+ }
81
+ });
82
+ }
83
+ disconnectSession() {
84
+ OT.disconnectSession(this.props.sessionId, (disconnectError) => {
85
+ if (disconnectError) {
86
+ this.otrnEventHandler(disconnectError);
87
+ } else {
88
+ const events = sanitizeSessionEvents(this.props.sessionId, this.props.eventHandlers);
89
+ removeNativeEvents(events);
90
+ }
91
+ });
92
+ }
93
+ getSessionInfo() {
94
+ return this.state.sessionInfo;
95
+ }
96
+ getCapabilities() {
97
+ return new Promise((resolve, reject ) => {
98
+ OT.getSessionCapabilities(this.props.sessionId, (sessionCapabilities) => {
99
+ if (sessionCapabilities) {
100
+ resolve(sessionCapabilities);
101
+ } else {
102
+ reject(new Error('Not connected to session.'));
103
+ }
104
+ });
105
+ });
106
+ }
107
+ async reportIssue() {
108
+ return new Promise((resolve, reject) => {
109
+ OT.reportIssue(this.props.sessionId, (reportIssueId, error) => {
110
+ if (reportIssueId) {
111
+ resolve(reportIssueId)
112
+ } else {
113
+ reject (new Error(error))
114
+ }
115
+ });
116
+ })
117
+ }
118
+ signal(signal) {
119
+ const signalData = sanitizeSignalData(signal);
120
+ OT.sendSignal(this.props.sessionId, signalData.signal, signalData.errorHandler);
121
+ }
122
+ forceMuteAll(excludedStreamIds) {
123
+ return OT.forceMuteAll(this.props.sessionId, excludedStreamIds || []);
124
+ }
125
+ forceMuteStream(streamId) {
126
+ return OT.forceMuteStream(this.props.sessionId, streamId);
127
+ }
128
+ disableForceMute() {
129
+ return OT.disableForceMute(this.props.sessionId);
130
+ }
131
+ render() {
132
+ const { style, children, sessionId, apiKey, token } = this.props;
133
+ const { sessionInfo } = this.state;
134
+ if (children && sessionId && apiKey && token) {
135
+ return (
136
+ <OTContext.Provider value={{ sessionId, sessionInfo }}>
137
+ <View style={style}>
138
+ { children }
139
+ </View>
140
+ </OTContext.Provider>
141
+ );
142
+ }
143
+ return <View />;
144
+ }
145
+ }
146
+
147
+ OTSession.propTypes = {
148
+ apiKey: PropTypes.string.isRequired,
149
+ sessionId: PropTypes.string.isRequired,
150
+ token: PropTypes.string.isRequired,
151
+ children: PropTypes.oneOfType([
152
+ PropTypes.element,
153
+ PropTypes.arrayOf(PropTypes.element),
154
+ ]),
155
+ style: ViewPropTypes.style,
156
+ eventHandlers: PropTypes.object, // eslint-disable-line react/forbid-prop-types
157
+ options: PropTypes.object, // eslint-disable-line react/forbid-prop-types
158
+ signal: PropTypes.object, // eslint-disable-line react/forbid-prop-types
159
+ };
160
+
161
+ OTSession.defaultProps = {
162
+ eventHandlers: {},
163
+ options: {},
164
+ signal: {},
165
+ style: {
166
+ flex: 1
167
+ },
168
+ };
@@ -0,0 +1,148 @@
1
+ import React, { Component } from 'react';
2
+ import { View, Platform } from 'react-native';
3
+ import PropTypes from 'prop-types';
4
+ import { isNull, isUndefined, each, isEqual, isEmpty } from 'underscore';
5
+ import { OT, nativeEvents, setNativeEvents, removeNativeEvents } from './OT';
6
+ import OTSubscriberView from './views/OTSubscriberView';
7
+ import { sanitizeSubscriberEvents, sanitizeProperties, sanitizeFrameRate, sanitizeResolution, sanitizeAudioVolume } from './helpers/OTSubscriberHelper';
8
+ import { getOtrnErrorEventHandler, sanitizeBooleanProperty } from './helpers/OTHelper';
9
+ import OTContext from './contexts/OTContext';
10
+
11
+ export default class OTSubscriber extends Component {
12
+ constructor(props, context) {
13
+ super(props, context);
14
+ this.state = {
15
+ streams: [],
16
+ subscribeToSelf: props.subscribeToSelf || false
17
+ };
18
+ this.componentEvents = {
19
+ streamDestroyed: Platform.OS === 'android' ? 'session:onStreamDropped' : 'session:streamDestroyed',
20
+ streamCreated: Platform.OS === 'android' ? 'session:onStreamReceived' : 'session:streamCreated',
21
+ captionReceived: Platform.OS === 'android' ? 'session:onCaptionText' : 'subscriber:subscriberCaptionReceived:',
22
+ };
23
+ this.componentEventsArray = Object.values(this.componentEvents);
24
+ this.otrnEventHandler = getOtrnErrorEventHandler(this.props.eventHandlers);
25
+ this.initComponent();
26
+ }
27
+ initComponent = () => {
28
+ const { eventHandlers } = this.props;
29
+ const { sessionId } = this.context;
30
+ if (sessionId) {
31
+ this.streamCreated = nativeEvents.addListener(`${sessionId}:${this.componentEvents.streamCreated}`,
32
+ stream => this.streamCreatedHandler(stream));
33
+ this.streamDestroyed = nativeEvents.addListener(`${sessionId}:${this.componentEvents.streamDestroyed}`,
34
+ stream => this.streamDestroyedHandler(stream));
35
+ const subscriberEvents = sanitizeSubscriberEvents(eventHandlers);
36
+ OT.setJSComponentEvents(this.componentEventsArray);
37
+ setNativeEvents(subscriberEvents);
38
+ }
39
+ }
40
+ componentDidUpdate() {
41
+ const { streamProperties } = this.props;
42
+ if (!isEqual(this.state.streamProperties, streamProperties)) {
43
+ each(streamProperties, (individualStreamProperties, streamId) => {
44
+ const { subscribeToAudio, subscribeToVideo, subscribeToCaptions, preferredResolution, preferredFrameRate, audioVolume } = individualStreamProperties;
45
+ if (subscribeToAudio !== undefined) {
46
+ OT.subscribeToAudio(streamId, sanitizeBooleanProperty(subscribeToAudio));
47
+ }
48
+ if (subscribeToVideo !== undefined) {
49
+ OT.subscribeToVideo(streamId, sanitizeBooleanProperty(subscribeToVideo));
50
+ }
51
+ if (subscribeToCaptions !== undefined) {
52
+ OT.subscribeToCaptions(streamId, sanitizeBooleanProperty(subscribeToCaptions));
53
+ }
54
+ if (preferredResolution !== undefined) {
55
+ OT.setPreferredResolution(streamId, sanitizeResolution(preferredResolution));
56
+ }
57
+ if (preferredFrameRate !== undefined) {
58
+ OT.setPreferredFrameRate(streamId, sanitizeFrameRate(preferredFrameRate));
59
+ }
60
+ if (audioVolume !== undefined) {
61
+ OT.setAudioVolume(streamId, sanitizeAudioVolume(audioVolume));
62
+ }
63
+ });
64
+ this.setState({ streamProperties });
65
+ }
66
+ }
67
+ componentWillUnmount() {
68
+ this.streamCreated.remove();
69
+ this.streamDestroyed.remove();
70
+ OT.removeJSComponentEvents(this.componentEventsArray);
71
+ const events = sanitizeSubscriberEvents(this.props.eventHandlers);
72
+ removeNativeEvents(events);
73
+ }
74
+ streamCreatedHandler = (stream) => {
75
+ const { subscribeToSelf } = this.state;
76
+ const { streamProperties, properties } = this.props;
77
+ const { sessionId, sessionInfo } = this.context;
78
+ const subscriberProperties = streamProperties[stream.streamId] ?
79
+ sanitizeProperties(streamProperties[stream.streamId]) :
80
+ sanitizeProperties(properties);
81
+ // Subscribe to streams. If subscribeToSelf is true, subscribe also to his own stream
82
+ const sessionInfoConnectionId = sessionInfo && sessionInfo.connection ? sessionInfo.connection.connectionId : null;
83
+ if (subscribeToSelf || (sessionInfoConnectionId !== stream.connectionId)) {
84
+ OT.subscribeToStream(stream.streamId, sessionId, subscriberProperties, (error) => {
85
+ if (error) {
86
+ this.otrnEventHandler(error);
87
+ } else {
88
+ this.setState({
89
+ streams: [...this.state.streams, stream.streamId],
90
+ });
91
+ }
92
+ });
93
+ }
94
+ }
95
+ streamDestroyedHandler = (stream) => {
96
+ OT.removeSubscriber(stream.streamId, (error) => {
97
+ if (error) {
98
+ this.otrnEventHandler(error);
99
+ } else {
100
+ const indexOfStream = this.state.streams.indexOf(stream.streamId);
101
+ const newState = this.state.streams.slice();
102
+ newState.splice(indexOfStream, 1);
103
+ this.setState({
104
+ streams: newState,
105
+ });
106
+ }
107
+ });
108
+ }
109
+ getRtcStatsReport(streamId) {
110
+ OT.getSubscriberRtcStatsReport(streamId);
111
+ }
112
+ render() {
113
+ if (!this.props.children) {
114
+ const containerStyle = this.props.containerStyle;
115
+ const childrenWithStreams = this.state.streams.map((streamId) => {
116
+ const streamProperties = this.props.streamProperties[streamId];
117
+ const style = isEmpty(streamProperties) ? this.props.style : (isUndefined(streamProperties.style) || isNull(streamProperties.style)) ? this.props.style : streamProperties.style;
118
+ return <OTSubscriberView key={streamId} streamId={streamId} style={style} />
119
+ });
120
+ return <View style={containerStyle}>{childrenWithStreams}</View>;
121
+ }
122
+ return this.props.children(this.state.streams) || null;
123
+ }
124
+ }
125
+
126
+ const viewPropTypes = View.propTypes;
127
+ OTSubscriber.propTypes = {
128
+ ...viewPropTypes,
129
+ children: PropTypes.func,
130
+ properties: PropTypes.object, // eslint-disable-line react/forbid-prop-types
131
+ eventHandlers: PropTypes.object, // eslint-disable-line react/forbid-prop-types
132
+ streamProperties: PropTypes.object, // eslint-disable-line react/forbid-prop-types
133
+ containerStyle: PropTypes.object, // eslint-disable-line react/forbid-prop-types
134
+ getRtcStatsReport: PropTypes.object, // eslint-disable-line react/forbid-prop-types
135
+ subscribeToSelf: PropTypes.bool
136
+ };
137
+
138
+ OTSubscriber.defaultProps = {
139
+ properties: {},
140
+ eventHandlers: {},
141
+ streamProperties: {},
142
+ containerStyle: {},
143
+ subscribeToSelf: false,
144
+ getRtcStatsReport: {},
145
+ subscribeToCaptions: false,
146
+ };
147
+
148
+ OTSubscriber.contextType = OTContext;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ const OTContext = React.createContext({});
4
+
5
+ export default OTContext;
@@ -0,0 +1,91 @@
1
+ import { Platform } from 'react-native';
2
+ import { handleError } from '../OTError';
3
+ import { each } from 'underscore';
4
+ import axios from 'axios';
5
+
6
+ const reassignEvents = (type, customEvents, events, eventKey) => {
7
+ const newEvents = {};
8
+ const preface = `${type}:`;
9
+ const platform = Platform.OS;
10
+
11
+ each(events, (eventHandler, eventType) => {
12
+ if (customEvents[platform][eventType] !== undefined && eventKey !== undefined) {
13
+ newEvents[`${eventKey}:${preface}${customEvents[platform][eventType]}`] = eventHandler;
14
+ } else if (customEvents[platform][eventType] !== undefined) {
15
+ newEvents[`${preface}${customEvents[platform][eventType]}`] = eventHandler;
16
+ } else if (events['otrnError']) {
17
+ // ignore otrnError event because it's for the js layer
18
+ } else {
19
+ handleError(`${eventType} is not a supported event`);
20
+ }
21
+ });
22
+
23
+ // Set a default handler
24
+ each(customEvents[platform], (event) => {
25
+ if (eventKey !== undefined && !newEvents[`${eventKey}:${preface}${event}`]) {
26
+ newEvents[`${eventKey}:${preface}${event}`] = () => { };
27
+ }
28
+ });
29
+
30
+ return newEvents;
31
+ };
32
+
33
+ const sanitizeBooleanProperty = property => (property || property === undefined ? true : property);
34
+
35
+ const getOtrnErrorEventHandler = (events) => {
36
+ let otrnEventHandler = event => {
37
+ handleError(event);
38
+ }
39
+ if (typeof events !== 'object') {
40
+ return otrnEventHandler;
41
+ } else if (events['otrnError']) {
42
+ otrnEventHandler = events['otrnError'];
43
+ }
44
+ return otrnEventHandler;
45
+ };
46
+
47
+ const getLog = (apiKey, sessionId, action, connectionId) => {
48
+ const body = {
49
+ payload: {
50
+ platform: Platform.OS,
51
+ otrn_version: require('../../../package.json').version,
52
+ platform_version: Platform.Version,
53
+ },
54
+ payload_type: 'info',
55
+ action,
56
+ partner_id: apiKey,
57
+ session_id: sessionId,
58
+ source: require('../../../package.json').repository.url,
59
+ };
60
+ if (connectionId) {
61
+ body.connectionId = connectionId;
62
+ }
63
+ return body;
64
+ };
65
+
66
+ const logRequest = (body, proxyUrl) => {
67
+ const hlgUrl = 'hlg.tokbox.com/prod/logging/ClientEvent';
68
+ const url = proxyUrl ? `${proxyUrl}/${hlgUrl}` : `https://${hlgUrl}`;
69
+ axios({
70
+ url,
71
+ method: 'post',
72
+ data: JSON.stringify(body),
73
+ })
74
+ .then(() => {
75
+ // response complete
76
+ })
77
+ .catch(() => {
78
+ handleError('logging');
79
+ });
80
+ };
81
+
82
+ const logOT = ({ apiKey, sessionId, action, connectionId, proxyUrl }) => {
83
+ logRequest(getLog(apiKey, sessionId, action, connectionId), proxyUrl);
84
+ };
85
+
86
+ export {
87
+ sanitizeBooleanProperty,
88
+ reassignEvents,
89
+ logOT,
90
+ getOtrnErrorEventHandler,
91
+ };
@@ -0,0 +1,122 @@
1
+ import { sanitizeBooleanProperty, reassignEvents } from './OTHelper';
2
+
3
+ const sanitizeResolution = (resolution) => {
4
+ switch (resolution) {
5
+ case '352x288':
6
+ return 'LOW';
7
+ case '640x480':
8
+ return 'MEDIUM';
9
+ case '1280x720':
10
+ return 'HIGH';
11
+ case '1920x1080':
12
+ return 'HIGH_1080P';
13
+ default:
14
+ return 'MEDIUM';
15
+ }
16
+ };
17
+
18
+ const sanitizeFrameRate = (frameRate) => {
19
+ switch (frameRate) {
20
+ case 1:
21
+ return 1;
22
+ case 7:
23
+ return 7;
24
+ case 15:
25
+ return 15;
26
+ default:
27
+ return 30;
28
+ }
29
+ };
30
+
31
+ const sanitizeCameraPosition = (cameraPosition = 'front') => (cameraPosition === 'front' ? 'front' : cameraPosition);
32
+
33
+ const sanitizeVideoSource = (videoSource = 'camera') => (videoSource === 'camera' ? 'camera' : 'screen');
34
+
35
+ const sanitizeAudioBitrate = (audioBitrate = 40000) =>
36
+ (audioBitrate < 6000 || audioBitrate > 510000 ? 40000 : audioBitrate);
37
+
38
+ const sanitizeVideoContentHint = (sanitizeVideoContentHint = '') => {
39
+ switch (sanitizeVideoContentHint) {
40
+ case 'motion':
41
+ return 'motion';
42
+ case 'detail':
43
+ return 'detail';
44
+ case 'text':
45
+ return 'text';
46
+ default:
47
+ return '';
48
+ }
49
+ };
50
+
51
+ const sanitizeProperties = (properties) => {
52
+ if (typeof properties !== 'object') {
53
+ return {
54
+ videoTrack: true,
55
+ audioTrack: true,
56
+ publishAudio: true,
57
+ publishVideo: true,
58
+ publishCaptions: false,
59
+ name: '',
60
+ cameraPosition: 'front',
61
+ audioFallbackEnabled: true,
62
+ audioBitrate: 40000,
63
+ enableDtx: false,
64
+ frameRate: 30,
65
+ resolution: sanitizeResolution(),
66
+ videoContentHint: '',
67
+ videoSource: 'camera',
68
+ scalableScreenshare: false,
69
+ };
70
+ }
71
+ return {
72
+ videoTrack: sanitizeBooleanProperty(properties.videoTrack),
73
+ audioTrack: sanitizeBooleanProperty(properties.audioTrack),
74
+ publishAudio: sanitizeBooleanProperty(properties.publishAudio),
75
+ publishVideo: sanitizeBooleanProperty(properties.publishVideo),
76
+ publishCaptions: sanitizeBooleanProperty(properties.publishCaptions),
77
+ name: properties.name ? properties.name : '',
78
+ cameraPosition: sanitizeCameraPosition(properties.cameraPosition),
79
+ audioFallbackEnabled: sanitizeBooleanProperty(properties.audioFallbackEnabled),
80
+ audioBitrate: sanitizeAudioBitrate(properties.audioBitrate),
81
+ enableDtx: sanitizeBooleanProperty(properties.enableDtx ? properties.enableDtx : false),
82
+ frameRate: sanitizeFrameRate(properties.frameRate),
83
+ resolution: sanitizeResolution(properties.resolution),
84
+ videoContentHint: sanitizeVideoContentHint(properties.videoContentHint),
85
+ videoSource: sanitizeVideoSource(properties.videoSource),
86
+ scalableScreenshare: Boolean(properties.scalableScreenshare),
87
+ };
88
+ };
89
+
90
+ const sanitizePublisherEvents = (publisherId, events) => {
91
+ if (typeof events !== 'object') {
92
+ return {};
93
+ }
94
+ const customEvents = {
95
+ ios: {
96
+ streamCreated: 'streamCreated',
97
+ streamDestroyed: 'streamDestroyed',
98
+ error: 'didFailWithError',
99
+ audioLevel: 'audioLevelUpdated',
100
+ audioNetworkStats: 'audioStats',
101
+ rtcStatsReport: 'rtcStatsReport',
102
+ videoNetworkStats: 'videoStats',
103
+ muteForced: 'muteForced',
104
+ },
105
+ android: {
106
+ streamCreated: 'onStreamCreated',
107
+ streamDestroyed: 'onStreamDestroyed',
108
+ error: 'onError',
109
+ audioLevel: 'onAudioLevelUpdated',
110
+ audioNetworkStats: 'onAudioStats',
111
+ rtcStatsReport: 'onRtcStatsReport',
112
+ videoNetworkStats: 'onVideoStats',
113
+ muteForced: 'onMuteForced',
114
+ },
115
+ };
116
+ return reassignEvents('publisher', customEvents, events, publisherId);
117
+ };
118
+
119
+ export {
120
+ sanitizeProperties,
121
+ sanitizePublisherEvents,
122
+ };