@woosh/meep-engine 2.138.0 → 2.138.1

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 (199) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/build/bundle-worker-terrain.js +1 -1
  3. package/package.json +1 -1
  4. package/src/core/assert.d.ts +6 -0
  5. package/src/core/assert.d.ts.map +1 -1
  6. package/src/core/assert.js +16 -3
  7. package/src/core/binary/half_to_float_uint16.js +1 -1
  8. package/src/core/binary/to_half_float_uint16.d.ts.map +1 -1
  9. package/src/core/binary/to_half_float_uint16.js +9 -4
  10. package/src/core/collection/table/RowFirstTableSpec.js +1 -1
  11. package/src/core/events/signal/Signal.d.ts.map +1 -1
  12. package/src/core/events/signal/Signal.js +53 -0
  13. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +3 -3
  14. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +3 -3
  15. package/src/engine/Clock.d.ts +2 -2
  16. package/src/engine/Clock.js +2 -2
  17. package/src/engine/graphics/ecs/highlight/system/RenderableHighlightSystem.d.ts.map +1 -1
  18. package/src/engine/graphics/ecs/highlight/system/RenderableHighlightSystem.js +17 -29
  19. package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.d.ts.map +1 -1
  20. package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.js +18 -31
  21. package/src/engine/network/NetworkSession.d.ts +386 -0
  22. package/src/engine/network/NetworkSession.d.ts.map +1 -0
  23. package/src/engine/network/NetworkSession.js +1841 -0
  24. package/src/engine/network/PriorityFetch.d.ts.map +1 -1
  25. package/src/engine/network/PriorityFetch.js +3 -2
  26. package/src/engine/network/adapters/QuaternionInterpolationAdapter.d.ts +14 -0
  27. package/src/engine/network/adapters/QuaternionInterpolationAdapter.d.ts.map +1 -0
  28. package/src/engine/network/adapters/QuaternionInterpolationAdapter.js +44 -0
  29. package/src/engine/network/adapters/TransformInterpolationAdapter.d.ts +18 -0
  30. package/src/engine/network/adapters/TransformInterpolationAdapter.d.ts.map +1 -0
  31. package/src/engine/network/adapters/TransformInterpolationAdapter.js +79 -0
  32. package/src/engine/network/adapters/TransformReplicationAdapter.d.ts +37 -0
  33. package/src/engine/network/adapters/TransformReplicationAdapter.d.ts.map +1 -0
  34. package/src/engine/network/adapters/TransformReplicationAdapter.js +87 -0
  35. package/src/engine/network/adapters/Vector3InterpolationAdapter.d.ts +18 -0
  36. package/src/engine/network/adapters/Vector3InterpolationAdapter.d.ts.map +1 -0
  37. package/src/engine/network/adapters/Vector3InterpolationAdapter.js +46 -0
  38. package/src/engine/network/convertPathToURL.js +107 -107
  39. package/src/engine/network/core/quantize/quantize_float.d.ts +54 -0
  40. package/src/engine/network/core/quantize/quantize_float.d.ts.map +1 -0
  41. package/src/engine/network/core/quantize/quantize_float.js +66 -0
  42. package/src/engine/network/core/quantize/quantize_position.d.ts +44 -0
  43. package/src/engine/network/core/quantize/quantize_position.d.ts.map +1 -0
  44. package/src/engine/network/core/quantize/quantize_position.js +54 -0
  45. package/src/engine/network/core/sequence/ack_bitfield.d.ts +47 -0
  46. package/src/engine/network/core/sequence/ack_bitfield.d.ts.map +1 -0
  47. package/src/engine/network/core/sequence/ack_bitfield.js +77 -0
  48. package/src/engine/network/core/sequence/seq16.d.ts +53 -0
  49. package/src/engine/network/core/sequence/seq16.d.ts.map +1 -0
  50. package/src/engine/network/core/sequence/seq16.js +69 -0
  51. package/src/engine/network/core/sequence/seq32.d.ts +55 -0
  52. package/src/engine/network/core/sequence/seq32.d.ts.map +1 -0
  53. package/src/engine/network/core/sequence/seq32.js +73 -0
  54. package/src/engine/network/diagnostics/BandwidthMeter.d.ts +76 -0
  55. package/src/engine/network/diagnostics/BandwidthMeter.d.ts.map +1 -0
  56. package/src/engine/network/diagnostics/BandwidthMeter.js +155 -0
  57. package/src/engine/network/diagnostics/ReplayLog.d.ts +74 -0
  58. package/src/engine/network/diagnostics/ReplayLog.d.ts.map +1 -0
  59. package/src/engine/network/diagnostics/ReplayLog.js +137 -0
  60. package/src/engine/network/diagnostics/SyncTest.d.ts +74 -0
  61. package/src/engine/network/diagnostics/SyncTest.d.ts.map +1 -0
  62. package/src/engine/network/diagnostics/SyncTest.js +151 -0
  63. package/src/engine/network/ecs/NetworkSystem.d.ts +57 -0
  64. package/src/engine/network/ecs/NetworkSystem.d.ts.map +1 -0
  65. package/src/engine/network/ecs/NetworkSystem.js +84 -0
  66. package/src/engine/network/ecs/components/NetworkIdentity.d.ts +58 -0
  67. package/src/engine/network/ecs/components/NetworkIdentity.d.ts.map +1 -0
  68. package/src/engine/network/ecs/components/NetworkIdentity.js +73 -0
  69. package/src/engine/network/ecs/serialization/NetworkIdentitySerializationAdapter.d.ts +40 -0
  70. package/src/engine/network/ecs/serialization/NetworkIdentitySerializationAdapter.d.ts.map +1 -0
  71. package/src/engine/network/ecs/serialization/NetworkIdentitySerializationAdapter.js +64 -0
  72. package/src/engine/network/orchestrator/NetworkPeer.d.ts +389 -0
  73. package/src/engine/network/orchestrator/NetworkPeer.d.ts.map +1 -0
  74. package/src/engine/network/orchestrator/NetworkPeer.js +1107 -0
  75. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +260 -0
  76. package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts.map +1 -0
  77. package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +425 -0
  78. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts +217 -0
  79. package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts.map +1 -0
  80. package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +562 -0
  81. package/src/engine/network/replication/Replicator.d.ts +134 -0
  82. package/src/engine/network/replication/Replicator.d.ts.map +1 -0
  83. package/src/engine/network/replication/Replicator.js +334 -0
  84. package/src/engine/network/replication/ScopeFilter.d.ts +64 -0
  85. package/src/engine/network/replication/ScopeFilter.d.ts.map +1 -0
  86. package/src/engine/network/replication/ScopeFilter.js +71 -0
  87. package/src/engine/network/sim/ActionLog.d.ts +94 -0
  88. package/src/engine/network/sim/ActionLog.d.ts.map +1 -0
  89. package/src/engine/network/sim/ActionLog.js +189 -0
  90. package/src/engine/network/sim/BinaryInterpolationAdapter.d.ts +58 -0
  91. package/src/engine/network/sim/BinaryInterpolationAdapter.d.ts.map +1 -0
  92. package/src/engine/network/sim/BinaryInterpolationAdapter.js +56 -0
  93. package/src/engine/network/sim/InterpolationLog.d.ts +165 -0
  94. package/src/engine/network/sim/InterpolationLog.d.ts.map +1 -0
  95. package/src/engine/network/sim/InterpolationLog.js +583 -0
  96. package/src/engine/network/sim/ReplicatedComponentRegistry.d.ts +59 -0
  97. package/src/engine/network/sim/ReplicatedComponentRegistry.d.ts.map +1 -0
  98. package/src/engine/network/sim/ReplicatedComponentRegistry.js +140 -0
  99. package/src/engine/network/sim/RewindEngine.d.ts +66 -0
  100. package/src/engine/network/sim/RewindEngine.d.ts.map +1 -0
  101. package/src/engine/network/sim/RewindEngine.js +182 -0
  102. package/src/engine/network/sim/SimAction.d.ts +133 -0
  103. package/src/engine/network/sim/SimAction.d.ts.map +1 -0
  104. package/src/engine/network/sim/SimAction.js +273 -0
  105. package/src/engine/network/sim/SimActionExecutor.d.ts +109 -0
  106. package/src/engine/network/sim/SimActionExecutor.d.ts.map +1 -0
  107. package/src/engine/network/sim/SimActionExecutor.js +238 -0
  108. package/src/engine/network/sim/SimActionRegistry.d.ts +60 -0
  109. package/src/engine/network/sim/SimActionRegistry.d.ts.map +1 -0
  110. package/src/engine/network/sim/SimActionRegistry.js +128 -0
  111. package/src/engine/network/sim/SmoothingState.d.ts +87 -0
  112. package/src/engine/network/sim/SmoothingState.d.ts.map +1 -0
  113. package/src/engine/network/sim/SmoothingState.js +223 -0
  114. package/src/engine/network/sim/Snapshotter.d.ts +98 -0
  115. package/src/engine/network/sim/Snapshotter.d.ts.map +1 -0
  116. package/src/engine/network/sim/Snapshotter.js +206 -0
  117. package/src/engine/network/sim/SpeculationLog.d.ts +53 -0
  118. package/src/engine/network/sim/SpeculationLog.d.ts.map +1 -0
  119. package/src/engine/network/sim/SpeculationLog.js +84 -0
  120. package/src/engine/network/state/Baseline.d.ts +48 -0
  121. package/src/engine/network/state/Baseline.d.ts.map +1 -0
  122. package/src/engine/network/state/Baseline.js +83 -0
  123. package/src/engine/network/state/ChangedEntitySet.d.ts +94 -0
  124. package/src/engine/network/state/ChangedEntitySet.d.ts.map +1 -0
  125. package/src/engine/network/state/ChangedEntitySet.js +256 -0
  126. package/src/engine/network/state/InputRing.d.ts +90 -0
  127. package/src/engine/network/state/InputRing.d.ts.map +1 -0
  128. package/src/engine/network/state/InputRing.js +173 -0
  129. package/src/engine/network/state/MutationLedger.d.ts +82 -0
  130. package/src/engine/network/state/MutationLedger.d.ts.map +1 -0
  131. package/src/engine/network/state/MutationLedger.js +182 -0
  132. package/src/engine/network/state/PriorityAccumulator.d.ts +104 -0
  133. package/src/engine/network/state/PriorityAccumulator.d.ts.map +1 -0
  134. package/src/engine/network/state/PriorityAccumulator.js +180 -0
  135. package/src/engine/network/state/ReplicationSlotTable.d.ts +78 -0
  136. package/src/engine/network/state/ReplicationSlotTable.d.ts.map +1 -0
  137. package/src/engine/network/state/ReplicationSlotTable.js +211 -0
  138. package/src/engine/network/time/AdaptiveRenderDelay.d.ts +128 -0
  139. package/src/engine/network/time/AdaptiveRenderDelay.d.ts.map +1 -0
  140. package/src/engine/network/time/AdaptiveRenderDelay.js +258 -0
  141. package/src/engine/network/time/JitterBuffer.d.ts +58 -0
  142. package/src/engine/network/time/JitterBuffer.d.ts.map +1 -0
  143. package/src/engine/network/time/JitterBuffer.js +116 -0
  144. package/src/engine/network/time/TimeDilation.d.ts +49 -0
  145. package/src/engine/network/time/TimeDilation.d.ts.map +1 -0
  146. package/src/engine/network/time/TimeDilation.js +62 -0
  147. package/src/engine/network/time/TimeSync.d.ts +68 -0
  148. package/src/engine/network/time/TimeSync.d.ts.map +1 -0
  149. package/src/engine/network/time/TimeSync.js +153 -0
  150. package/src/engine/network/transport/Channel.d.ts +74 -0
  151. package/src/engine/network/transport/Channel.d.ts.map +1 -0
  152. package/src/engine/network/transport/Channel.js +272 -0
  153. package/src/engine/network/transport/LoopbackTransport.d.ts +59 -0
  154. package/src/engine/network/transport/LoopbackTransport.d.ts.map +1 -0
  155. package/src/engine/network/transport/LoopbackTransport.js +194 -0
  156. package/src/engine/network/transport/ReliableCommandPipeline.d.ts +139 -0
  157. package/src/engine/network/transport/ReliableCommandPipeline.d.ts.map +1 -0
  158. package/src/engine/network/transport/ReliableCommandPipeline.js +291 -0
  159. package/src/engine/network/transport/Transport.d.ts +109 -0
  160. package/src/engine/network/transport/Transport.d.ts.map +1 -0
  161. package/src/engine/network/transport/Transport.js +119 -0
  162. package/src/engine/network/transport/adapters/NodeUDPTransport.d.ts +60 -0
  163. package/src/engine/network/transport/adapters/NodeUDPTransport.d.ts.map +1 -0
  164. package/src/engine/network/transport/adapters/NodeUDPTransport.js +206 -0
  165. package/src/engine/network/transport/adapters/SimulatedTransport.d.ts +110 -0
  166. package/src/engine/network/transport/adapters/SimulatedTransport.d.ts.map +1 -0
  167. package/src/engine/network/transport/adapters/SimulatedTransport.js +252 -0
  168. package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.d.ts +33 -0
  169. package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.d.ts.map +1 -0
  170. package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.js +131 -0
  171. package/src/engine/network/transport/adapters/WebSocketTransport.d.ts +49 -0
  172. package/src/engine/network/transport/adapters/WebSocketTransport.d.ts.map +1 -0
  173. package/src/engine/network/transport/adapters/WebSocketTransport.js +180 -0
  174. package/src/engine/network/transport/adapters/WebTransportTransport.d.ts +73 -0
  175. package/src/engine/network/transport/adapters/WebTransportTransport.d.ts.map +1 -0
  176. package/src/engine/network/transport/adapters/WebTransportTransport.js +210 -0
  177. package/src/engine/network/transport/fragments/FragmentAssembler.d.ts +104 -0
  178. package/src/engine/network/transport/fragments/FragmentAssembler.d.ts.map +1 -0
  179. package/src/engine/network/transport/fragments/FragmentAssembler.js +291 -0
  180. package/src/engine/network/transport/fragments/FragmentRetention.d.ts +103 -0
  181. package/src/engine/network/transport/fragments/FragmentRetention.d.ts.map +1 -0
  182. package/src/engine/network/transport/fragments/FragmentRetention.js +194 -0
  183. package/src/engine/network/transport/fragments/fragment_send.d.ts +53 -0
  184. package/src/engine/network/transport/fragments/fragment_send.d.ts.map +1 -0
  185. package/src/engine/network/transport/fragments/fragment_send.js +147 -0
  186. package/src/engine/network/transport/fragments/packet_size.d.ts +93 -0
  187. package/src/engine/network/transport/fragments/packet_size.d.ts.map +1 -0
  188. package/src/engine/network/transport/fragments/packet_size.js +101 -0
  189. package/src/engine/network/xhr.js +23 -23
  190. package/src/engine/simulation/Ticker.d.ts +7 -0
  191. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  192. package/src/engine/simulation/Ticker.js +15 -4
  193. package/src/engine/network/DataChannel.js +0 -1210
  194. package/src/engine/network/RemoteController.d.ts +0 -23
  195. package/src/engine/network/RemoteController.d.ts.map +0 -1
  196. package/src/engine/network/RemoteController.js +0 -114
  197. package/src/engine/network/remoteEditor.d.ts +0 -2
  198. package/src/engine/network/remoteEditor.d.ts.map +0 -1
  199. package/src/engine/network/remoteEditor.js +0 -142
@@ -1,1210 +0,0 @@
1
-
2
- const DataChannel = function (channel, extras) {
3
- if (channel) this.automatic = true;
4
- this.channel = channel || location.href.replace(/\/|:|#|%|\.|\[|\]/g, '');
5
-
6
- extras = extras || {};
7
-
8
- const self = this;
9
- let dataConnector, fileReceiver, textReceiver;
10
-
11
- this.onmessage = function (message, userid) {
12
- console.debug(userid, 'sent message:', message);
13
- };
14
-
15
- this.channels = {};
16
- this.onopen = function (userid) {
17
- console.debug(userid, 'is connected with you.');
18
- };
19
-
20
- this.onclose = function (event) {
21
- console.error('data channel closed:', event);
22
- };
23
-
24
- this.onerror = function (event) {
25
- console.error('data channel error:', event);
26
- };
27
-
28
- // by default; received file will be auto-saved to disk
29
- this.autoSaveToDisk = true;
30
- this.onFileReceived = function (fileName) {
31
- console.debug('File <', fileName, '> received successfully.');
32
- };
33
-
34
- this.onFileSent = function (file) {
35
- console.debug('File <', file.name, '> sent successfully.');
36
- };
37
-
38
- this.onFileProgress = function (packets) {
39
- console.debug('<', packets.remaining, '> items remaining.');
40
- };
41
-
42
- function prepareInit(callback) {
43
- for (let extra in extras) {
44
- self[extra] = extras[extra];
45
- }
46
- self.direction = self.direction || 'many-to-many';
47
- if (self.userid) window.userid = self.userid;
48
-
49
- if (!self.openSignalingChannel) {
50
- if (typeof self.transmitRoomOnce === 'undefined') self.transmitRoomOnce = true;
51
-
52
- // socket.io over node.js: https://github.com/muaz-khan/WebRTC-Experiment/blob/master/Signaling.md
53
- self.openSignalingChannel = function (config) {
54
- config = config || {};
55
-
56
- channel = config.channel || self.channel || 'default-channel';
57
- const socket = new window.Firebase('https://' + (self.firebase || 'webrtc-experiment') + '.firebaseIO.com/' + channel);
58
- socket.channel = channel;
59
-
60
- socket.on('child_added', function (data) {
61
- config.onmessage(data.val());
62
- });
63
-
64
- socket.send = function (data) {
65
- this.push(data);
66
- };
67
-
68
- if (!self.socket) self.socket = socket;
69
- if (channel !== self.channel || (self.isInitiator && channel === self.channel))
70
- socket.onDisconnect().remove();
71
-
72
- if (config.onopen) setTimeout(config.onopen, 1);
73
-
74
- return socket;
75
- };
76
-
77
- if (!window.Firebase) {
78
- const script = document.createElement('script');
79
- script.src = 'https://www.webrtc-experiment.com/firebase.js';
80
- script.onload = callback;
81
- document.documentElement.appendChild(script);
82
- } else callback();
83
- } else callback();
84
- }
85
-
86
- function init() {
87
- if (self.config) return;
88
-
89
- self.config = {
90
- ondatachannel: function (room) {
91
- if (!dataConnector) {
92
- self.room = room;
93
- return;
94
- }
95
-
96
- const tempRoom = {
97
- id: room.roomToken,
98
- owner: room.broadcaster
99
- };
100
-
101
- if (self.ondatachannel) return self.ondatachannel(tempRoom);
102
-
103
- if (self.joinedARoom) return;
104
- self.joinedARoom = true;
105
-
106
- self.join(tempRoom);
107
- },
108
- onopen: function (userid, _channel) {
109
- self.onopen(userid, _channel);
110
- self.channels[userid] = {
111
- channel: _channel,
112
- send: function (data) {
113
- self.send(data, this.channel);
114
- }
115
- };
116
- },
117
- onmessage: function (data, userid) {
118
- if (IsDataChannelSupported && !data.size) data = JSON.parse(data);
119
-
120
- if (!IsDataChannelSupported) {
121
- if (data.userid === window.userid) return;
122
- data = data.message;
123
- }
124
-
125
- if (data.type === 'text')
126
- textReceiver.receive(data, self.onmessage, userid);
127
-
128
- else if (typeof data.maxChunks !== 'undefined')
129
- fileReceiver.receive(data, self);
130
-
131
- else self.onmessage(data, userid);
132
- },
133
- onclose: function (event) {
134
- const myChannels = self.channels,
135
- closedChannel = event.currentTarget;
136
-
137
- for (let userid in myChannels) {
138
- if (closedChannel === myChannels[userid].channel) {
139
- delete myChannels[userid];
140
- }
141
- }
142
-
143
- self.onclose(event);
144
- },
145
- openSignalingChannel: self.openSignalingChannel
146
- };
147
-
148
- dataConnector = IsDataChannelSupported ?
149
- new DataConnector(self, self.config) :
150
- new SocketConnector(self.channel, self.config);
151
-
152
- fileReceiver = new FileReceiver(self);
153
- textReceiver = new TextReceiver(self);
154
-
155
- if (self.room) self.config.ondatachannel(self.room);
156
- }
157
-
158
- this.open = function (_channel) {
159
- self.joinedARoom = true;
160
-
161
- if (self.socket) self.socket.onDisconnect().remove();
162
- else self.isInitiator = true;
163
-
164
- if (_channel) self.channel = _channel;
165
-
166
- prepareInit(function () {
167
- init();
168
- if (IsDataChannelSupported) dataConnector.createRoom(_channel);
169
- });
170
- };
171
-
172
- this.connect = function (_channel) {
173
- if (_channel) self.channel = _channel;
174
- prepareInit(init);
175
- };
176
-
177
- // manually join a room
178
- this.join = function (room) {
179
- if (!room.id || !room.owner) {
180
- throw 'Invalid room info passed.';
181
- }
182
-
183
- if (!dataConnector) init();
184
-
185
- if (!dataConnector.joinRoom) {
186
- return;
187
- }
188
-
189
- dataConnector.joinRoom({
190
- roomToken: room.id,
191
- joinUser: room.owner
192
- });
193
- };
194
-
195
- this.send = function (data, _channel) {
196
- if (!data) throw 'No file, data or text message to share.';
197
- if (typeof data.size !== 'undefined' && typeof data.type !== 'undefined') {
198
- FileSender.send({
199
- file: data,
200
- channel: dataConnector,
201
- onFileSent: function (file) {
202
- self.onFileSent(file);
203
- },
204
- onFileProgress: function (packets, uuid) {
205
- self.onFileProgress(packets, uuid);
206
- },
207
-
208
- _channel: _channel,
209
- root: self
210
- });
211
- } else {
212
- TextSender.send({
213
- text: data,
214
- channel: dataConnector,
215
- _channel: _channel,
216
- root: self
217
- });
218
- }
219
- };
220
-
221
- this.onleave = function (userid) {
222
- console.debug(userid, 'left!');
223
- };
224
-
225
- this.leave = this.eject = function (userid) {
226
- dataConnector.leave(userid, self.autoCloseEntireSession);
227
- };
228
-
229
- this.openNewSession = function (isOpenNewSession, isNonFirebaseClient) {
230
- if (isOpenNewSession) {
231
- if (self.isNewSessionOpened) return;
232
- self.isNewSessionOpened = true;
233
-
234
- if (!self.joinedARoom) self.open();
235
- }
236
-
237
- if (!isOpenNewSession || isNonFirebaseClient) self.connect();
238
-
239
- // for non-firebase clients
240
- if (isNonFirebaseClient)
241
- setTimeout(function () {
242
- self.openNewSession(true);
243
- }, 5000);
244
- };
245
-
246
- if (typeof this.preferSCTP === 'undefined') {
247
- this.preferSCTP = isFirefox || chromeVersion >= 32 ? true : false;
248
- }
249
-
250
- if (typeof this.chunkSize === 'undefined') {
251
- this.chunkSize = isFirefox || chromeVersion >= 32 ? 13 * 1000 : 1000; // 1000 chars for RTP and 13000 chars for SCTP
252
- }
253
-
254
- if (typeof this.chunkInterval === 'undefined') {
255
- this.chunkInterval = isFirefox || chromeVersion >= 32 ? 100 : 500; // 500ms for RTP and 100ms for SCTP
256
- }
257
-
258
- if (self.automatic) {
259
- if (window.Firebase) {
260
- console.debug('checking presence of the room..');
261
- new window.Firebase('https://' + (extras.firebase || self.firebase || 'webrtc-experiment') + '.firebaseIO.com/' + self.channel).once('value', function (data) {
262
- console.debug('room is present?', data.val() != null);
263
- self.openNewSession(data.val() == null);
264
- });
265
- } else self.openNewSession(false, true);
266
- }
267
- };
268
-
269
- class DataConnector {
270
- constructor(root, config) {
271
- const self = {};
272
- const that = this;
273
-
274
- self.userToken = root.userid = root.userid || uniqueToken();
275
- self.sockets = [];
276
- self.socketObjects = {};
277
-
278
- let channels = '--';
279
- let isbroadcaster;
280
- let isGetNewRoom = true,
281
- RTCDataChannels = [];
282
-
283
- function newPrivateSocket(_config) {
284
- const socketConfig = {
285
- channel: _config.channel,
286
- onmessage: socketResponse,
287
- onopen: function () {
288
- if (isofferer && !peer) initPeer();
289
-
290
- _config.socketIndex = socket.index = self.sockets.length;
291
- self.socketObjects[socketConfig.channel] = socket;
292
- self.sockets[_config.socketIndex] = socket;
293
- }
294
- };
295
-
296
- socketConfig.callback = function (_socket) {
297
- socket = _socket;
298
- socketConfig.onopen();
299
- };
300
-
301
- let socket = root.openSignalingChannel(socketConfig),
302
- isofferer = _config.isofferer;
303
- let gotstream;
304
- const inner = {};
305
- let peer;
306
-
307
- const peerConfig = {
308
- onICE: function (candidate) {
309
- socket && socket.send({
310
- userToken: self.userToken,
311
- candidate: {
312
- sdpMLineIndex: candidate.sdpMLineIndex,
313
- candidate: JSON.stringify(candidate.candidate)
314
- }
315
- });
316
- },
317
- onopen: onChannelOpened,
318
- onmessage: function (event) {
319
- config.onmessage(event.data, _config.userid);
320
- },
321
- onclose: config.onclose,
322
- onerror: root.onerror,
323
- preferSCTP: root.preferSCTP
324
- };
325
-
326
- function initPeer(offerSDP) {
327
- if (root.direction === 'one-to-one' && window.isFirstConnectionOpened) return;
328
-
329
- if (!offerSDP) peerConfig.onOfferSDP = sendsdp;
330
- else {
331
- peerConfig.offerSDP = offerSDP;
332
- peerConfig.onAnswerSDP = sendsdp;
333
- }
334
-
335
- peer = RTCPeerConnection(peerConfig);
336
- }
337
-
338
- function onChannelOpened(channel) {
339
- channel.peer = peer.peer;
340
- RTCDataChannels.push(channel);
341
-
342
- config.onopen(_config.userid, channel);
343
-
344
- if (root.direction === 'many-to-many' && isbroadcaster && channels.split('--').length > 3) {
345
- defaultSocket && defaultSocket.send({
346
- newParticipant: socket.channel,
347
- userToken: self.userToken
348
- });
349
- }
350
-
351
- window.isFirstConnectionOpened = gotstream = true;
352
- }
353
-
354
- function sendsdp(sdp) {
355
- sdp = JSON.stringify(sdp);
356
- const part = parseInt(sdp.length / 3);
357
-
358
- const firstPart = sdp.slice(0, part);
359
- let secondPart = sdp.slice(part, sdp.length - 1),
360
- thirdPart = '';
361
-
362
- if (sdp.length > part + part) {
363
- secondPart = sdp.slice(part, part + part);
364
- thirdPart = sdp.slice(part + part, sdp.length);
365
- }
366
-
367
- socket.send({
368
- userToken: self.userToken,
369
- firstPart: firstPart
370
- });
371
-
372
- socket.send({
373
- userToken: self.userToken,
374
- secondPart: secondPart
375
- });
376
-
377
- socket.send({
378
- userToken: self.userToken,
379
- thirdPart: thirdPart
380
- });
381
- }
382
-
383
- function socketResponse(response) {
384
- if (response.userToken == self.userToken) return;
385
-
386
- if (response.firstPart || response.secondPart || response.thirdPart) {
387
- if (response.firstPart) {
388
- // sdp sender's user id passed over "onopen" method
389
- _config.userid = response.userToken;
390
-
391
- inner.firstPart = response.firstPart;
392
- if (inner.secondPart && inner.thirdPart) selfInvoker();
393
- }
394
- if (response.secondPart) {
395
- inner.secondPart = response.secondPart;
396
- if (inner.firstPart && inner.thirdPart) selfInvoker();
397
- }
398
-
399
- if (response.thirdPart) {
400
- inner.thirdPart = response.thirdPart;
401
- if (inner.firstPart && inner.secondPart) selfInvoker();
402
- }
403
- }
404
-
405
- if (response.candidate && !gotstream) {
406
- peer && peer.addICE({
407
- sdpMLineIndex: response.candidate.sdpMLineIndex,
408
- candidate: JSON.parse(response.candidate.candidate)
409
- });
410
-
411
- console.debug('ice candidate', response.candidate.candidate);
412
- }
413
-
414
- if (response.left) {
415
- if (peer && peer.peer) {
416
- peer.peer.close();
417
- peer.peer = null;
418
- }
419
-
420
- if (response.closeEntireSession) leaveChannels();
421
- else if (socket) {
422
- socket.send({
423
- left: true,
424
- userToken: self.userToken
425
- });
426
- socket = null;
427
- }
428
-
429
- root.onleave(response.userToken);
430
- }
431
-
432
- if (response.playRoleOfBroadcaster)
433
- setTimeout(function () {
434
- self.roomToken = response.roomToken;
435
- root.open(self.roomToken);
436
- self.sockets = swap(self.sockets);
437
- }, 600);
438
- }
439
-
440
- let invokedOnce = false;
441
-
442
- function selfInvoker() {
443
- if (invokedOnce) return;
444
-
445
- invokedOnce = true;
446
- inner.sdp = JSON.parse(inner.firstPart + inner.secondPart + inner.thirdPart);
447
-
448
- if (isofferer) peer.addAnswerSDP(inner.sdp);
449
- else initPeer(inner.sdp);
450
-
451
- console.debug('sdp', inner.sdp.sdp);
452
- }
453
- }
454
-
455
- function onNewParticipant(channel) {
456
- if (!channel || channels.indexOf(channel) != -1 || channel == self.userToken) return;
457
- channels += channel + '--';
458
-
459
- const new_channel = uniqueToken();
460
-
461
- newPrivateSocket({
462
- channel: new_channel,
463
- closeSocket: true
464
- });
465
-
466
- defaultSocket && defaultSocket.send({
467
- participant: true,
468
- userToken: self.userToken,
469
- joinUser: channel,
470
- channel: new_channel
471
- });
472
- }
473
-
474
- function uniqueToken() {
475
- return Math.round(Math.random() * 60535) + 5000000;
476
- }
477
-
478
- function leaveChannels(channel) {
479
- const alert = {
480
- left: true,
481
- userToken: self.userToken
482
- };
483
-
484
- // if room initiator is leaving the room; close the entire session
485
- if (isbroadcaster) {
486
- if (root.autoCloseEntireSession) alert.closeEntireSession = true;
487
- else
488
- self.sockets[0].send({
489
- playRoleOfBroadcaster: true,
490
- userToken: self.userToken,
491
- roomToken: self.roomToken
492
- });
493
- }
494
-
495
- if (!channel) {
496
- // closing all sockets
497
- const sockets = self.sockets,
498
- length = sockets.length;
499
-
500
- for (let i = 0; i < length; i++) {
501
- const socket = sockets[i];
502
- if (socket) {
503
- socket.send(alert);
504
-
505
- if (self.socketObjects[socket.channel])
506
- delete self.socketObjects[socket.channel];
507
-
508
- delete sockets[i];
509
- }
510
- }
511
-
512
- that.left = true;
513
- }
514
-
515
- // eject a specific user!
516
- if (channel) {
517
- socket = self.socketObjects[channel];
518
- if (socket) {
519
- socket.send(alert);
520
-
521
- if (self.sockets[socket.index])
522
- delete self.sockets[socket.index];
523
-
524
- delete self.socketObjects[channel];
525
- }
526
- }
527
- self.sockets = swap(self.sockets);
528
- }
529
-
530
- window.addEventListener('beforeunload', function () {
531
- leaveChannels();
532
- }, false);
533
-
534
- window.addEventListener('keydown', function (e) {
535
- if (e.keyCode == 116)
536
- leaveChannels();
537
- }, false);
538
-
539
- let defaultSocket = root.openSignalingChannel({
540
- onmessage: function (response) {
541
- if (response.userToken == self.userToken) return;
542
- if (isGetNewRoom && response.roomToken && response.broadcaster) config.ondatachannel(response);
543
-
544
- if (response.newParticipant) onNewParticipant(response.newParticipant);
545
-
546
- if (response.userToken && response.joinUser == self.userToken && response.participant && channels.indexOf(response.userToken) == -1) {
547
- channels += response.userToken + '--';
548
-
549
- console.debug('Data connection is being opened between you and', response.userToken || response.channel);
550
- newPrivateSocket({
551
- isofferer: true,
552
- channel: response.channel || response.userToken,
553
- closeSocket: true
554
- });
555
- }
556
- },
557
- callback: function (socket) {
558
- defaultSocket = socket;
559
- }
560
- });
561
-
562
- return {
563
- createRoom: function (roomToken) {
564
- self.roomToken = roomToken || uniqueToken();
565
-
566
- isbroadcaster = true;
567
- isGetNewRoom = false;
568
-
569
- (function transmit() {
570
- defaultSocket && defaultSocket.send({
571
- roomToken: self.roomToken,
572
- broadcaster: self.userToken
573
- });
574
-
575
- if (!root.transmitRoomOnce && !that.leaving) {
576
- if (root.direction === 'one-to-one') {
577
- if (!window.isFirstConnectionOpened) setTimeout(transmit, 3000);
578
- } else setTimeout(transmit, 3000);
579
- }
580
- })();
581
- },
582
- joinRoom: function (_config) {
583
- self.roomToken = _config.roomToken;
584
- isGetNewRoom = false;
585
-
586
- newPrivateSocket({
587
- channel: self.userToken
588
- });
589
-
590
- defaultSocket.send({
591
- participant: true,
592
- userToken: self.userToken,
593
- joinUser: _config.joinUser
594
- });
595
- },
596
- send: function (message, _channel) {
597
- const _channels = RTCDataChannels;
598
- let data, length = _channels.length;
599
- if (!length) return;
600
-
601
- data = JSON.stringify(message);
602
-
603
- if (_channel) {
604
- if (_channel.readyState == 'open') {
605
- _channel.send(data);
606
- }
607
- } else
608
- for (let i = 0; i < length; i++) {
609
- if (_channels[i].readyState == 'open') {
610
- _channels[i].send(data);
611
- }
612
- }
613
- },
614
- leave: function (userid, autoCloseEntireSession) {
615
- if (autoCloseEntireSession) root.autoCloseEntireSession = true;
616
- leaveChannels(userid);
617
- if (!userid) {
618
- self.joinedARoom = isbroadcaster = false;
619
- isGetNewRoom = true;
620
- }
621
- }
622
- };
623
- }
624
- }
625
-
626
- function SocketConnector(_channel, config) {
627
- let socket = config.openSignalingChannel({
628
- channel: _channel,
629
- onopen: config.onopen,
630
- onmessage: config.onmessage,
631
- callback: function (_socket) {
632
- socket = _socket;
633
- }
634
- });
635
-
636
- return {
637
- send: function (message) {
638
- socket && socket.send({
639
- userid: userid,
640
- message: message
641
- });
642
- }
643
- };
644
- }
645
-
646
- function getRandomString() {
647
- return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, '-');
648
- }
649
-
650
- window.userid = getRandomString();
651
-
652
- const navigator = globalThis.navigator;
653
-
654
- const isMobileDevice = navigator.userAgent.match(/Android|iPhone|iPad|iPod|BlackBerry|IEMobile/i);
655
- const isChrome = !!navigator.webkitGetUserMedia;
656
- const isFirefox = !!navigator.mozGetUserMedia;
657
-
658
- let chromeVersion = 50;
659
- if (isChrome) {
660
- chromeVersion = !!navigator.mozGetUserMedia ? 0 : parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]);
661
- }
662
-
663
- const FileSender = {
664
- send: function (config) {
665
- const root = config.root;
666
- const channel = config.channel;
667
- const privateChannel = config._channel;
668
- const file = config.file;
669
-
670
- if (!config.file) {
671
- console.error('You must attach/select a file.');
672
- return;
673
- }
674
-
675
- // max chunk sending limit on chrome is 64k
676
- // max chunk receiving limit on firefox is 16k
677
- let packetSize = (!!navigator.mozGetUserMedia || root.preferSCTP) ? 15 * 1000 : 1 * 1000;
678
-
679
- if (root.chunkSize) {
680
- packetSize = root.chunkSize;
681
- }
682
-
683
- let textToTransfer = '';
684
- let numberOfPackets = 0;
685
- let packets = 0;
686
-
687
- file.uuid = getRandomString();
688
-
689
- function processInWebWorker() {
690
- const blob = URL.createObjectURL(new Blob(['function readFile(_file) {postMessage(new FileReaderSync().readAsDataURL(_file));};this.onmessage = function (e) {readFile(e.data);}'], {
691
- type: 'application/javascript'
692
- }));
693
-
694
- const worker = new Worker(blob);
695
- URL.revokeObjectURL(blob);
696
- return worker;
697
- }
698
-
699
- if (!!window.Worker && !isMobileDevice) {
700
- const webWorker = processInWebWorker();
701
-
702
- webWorker.onmessage = function (event) {
703
- onReadAsDataURL(event.data);
704
- };
705
-
706
- webWorker.postMessage(file);
707
- } else {
708
- const reader = new FileReader();
709
- reader.onload = function (e) {
710
- onReadAsDataURL(e.target.result);
711
- };
712
- reader.readAsDataURL(file);
713
- }
714
-
715
- function onReadAsDataURL(dataURL, text) {
716
- const data = {
717
- type: 'file',
718
- uuid: file.uuid,
719
- maxChunks: numberOfPackets,
720
- currentPosition: numberOfPackets - packets,
721
- name: file.name,
722
- fileType: file.type,
723
- size: file.size
724
- };
725
-
726
- if (dataURL) {
727
- text = dataURL;
728
- numberOfPackets = packets = data.packets = parseInt(text.length / packetSize);
729
-
730
- file.maxChunks = data.maxChunks = numberOfPackets;
731
- data.currentPosition = numberOfPackets - packets;
732
-
733
- if (root.onFileSent) root.onFileSent(file);
734
- }
735
-
736
- if (root.onFileProgress) root.onFileProgress({
737
- remaining: packets--,
738
- length: numberOfPackets,
739
- sent: numberOfPackets - packets,
740
-
741
- maxChunks: numberOfPackets,
742
- uuid: file.uuid,
743
- currentPosition: numberOfPackets - packets
744
- }, file.uuid);
745
-
746
- if (text.length > packetSize) data.message = text.slice(0, packetSize);
747
- else {
748
- data.message = text;
749
- data.last = true;
750
- data.name = file.name;
751
-
752
- file.url = URL.createObjectURL(file);
753
- root.onFileSent(file, file.uuid);
754
- }
755
-
756
- channel.send(data, privateChannel);
757
-
758
- textToTransfer = text.slice(data.message.length);
759
- if (textToTransfer.length) {
760
- setTimeout(function () {
761
- onReadAsDataURL(null, textToTransfer);
762
- }, root.chunkInterval || 100);
763
- }
764
- }
765
- }
766
- };
767
-
768
- function FileReceiver(root) {
769
- const content = {},
770
- packets = {},
771
- numberOfPackets = {};
772
-
773
- function receive(data) {
774
- const uuid = data.uuid;
775
-
776
- if (typeof data.packets !== 'undefined') {
777
- numberOfPackets[uuid] = packets[uuid] = parseInt(data.packets);
778
- }
779
-
780
- if (root.onFileProgress) root.onFileProgress({
781
- remaining: packets[uuid]--,
782
- length: numberOfPackets[uuid],
783
- received: numberOfPackets[uuid] - packets[uuid],
784
-
785
- maxChunks: numberOfPackets[uuid],
786
- uuid: uuid,
787
- currentPosition: numberOfPackets[uuid] - packets[uuid]
788
- }, uuid);
789
-
790
- if (!content[uuid]) content[uuid] = [];
791
-
792
- content[uuid].push(data.message);
793
-
794
- if (data.last) {
795
- const dataURL = content[uuid].join('');
796
-
797
- FileConverter.DataURLToBlob(dataURL, data.fileType, function (blob) {
798
- blob.uuid = uuid;
799
- blob.name = data.name;
800
- blob.type = data.fileType;
801
- blob.extra = data.extra || {};
802
-
803
- blob.url = (window.URL || window.webkitURL).createObjectURL(blob);
804
-
805
- if (root.autoSaveToDisk) {
806
- FileSaver.SaveToDisk(blob.url, data.name);
807
- }
808
-
809
- if (root.onFileReceived) root.onFileReceived(blob);
810
-
811
- delete content[uuid];
812
- });
813
- }
814
- }
815
-
816
- return {
817
- receive: receive
818
- };
819
- }
820
-
821
- const FileSaver = {
822
- SaveToDisk: function (fileUrl, fileName) {
823
- const hyperlink = document.createElement('a');
824
- hyperlink.href = fileUrl;
825
- hyperlink.target = '_blank';
826
- hyperlink.download = fileName || fileUrl;
827
-
828
- const mouseEvent = new MouseEvent('click', {
829
- view: window,
830
- bubbles: true,
831
- cancelable: true
832
- });
833
-
834
- hyperlink.dispatchEvent(mouseEvent);
835
- (window.URL || window.webkitURL).revokeObjectURL(hyperlink.href);
836
- }
837
- };
838
-
839
- const FileConverter = {
840
- DataURLToBlob: function (dataURL, fileType, callback) {
841
-
842
- function processInWebWorker() {
843
- const blob = URL.createObjectURL(new Blob(['function getBlob(_dataURL, _fileType) {var binary = atob(_dataURL.substr(_dataURL.indexOf(",") + 1)),i = binary.length,view = new Uint8Array(i);while (i--) {view[i] = binary.charCodeAt(i);};postMessage(new Blob([view], {type: _fileType}));};this.onmessage = function (e) {var data = JSON.parse(e.data); getBlob(data.dataURL, data.fileType);}'], {
844
- type: 'application/javascript'
845
- }));
846
-
847
- const worker = new Worker(blob);
848
- URL.revokeObjectURL(blob);
849
- return worker;
850
- }
851
-
852
- if (!!window.Worker && !isMobileDevice) {
853
- const webWorker = processInWebWorker();
854
-
855
- webWorker.onmessage = function (event) {
856
- callback(event.data);
857
- };
858
-
859
- webWorker.postMessage(JSON.stringify({
860
- dataURL: dataURL,
861
- fileType: fileType
862
- }));
863
- } else {
864
- const binary = atob(dataURL.substr(dataURL.indexOf(',') + 1));
865
- let i = binary.length;
866
- const view = new Uint8Array(i);
867
-
868
- while (i--) {
869
- view[i] = binary.charCodeAt(i);
870
- }
871
-
872
- callback(new Blob([view]));
873
- }
874
- }
875
- };
876
-
877
- const TextSender = {
878
- send: function (config) {
879
- const root = config.root;
880
-
881
- const channel = config.channel,
882
- _channel = config._channel;
883
- let initialText = config.text;
884
- const packetSize = root.chunkSize || 1000;
885
- let textToTransfer = '';
886
- let isobject = false;
887
-
888
- if (typeof initialText !== 'string') {
889
- isobject = true;
890
- initialText = JSON.stringify(initialText);
891
- }
892
-
893
- // uuid is used to uniquely identify sending instance
894
- const uuid = getRandomString();
895
- const sendingTime = new Date().getTime();
896
-
897
- sendText(initialText);
898
-
899
- function sendText(textMessage, text) {
900
- const data = {
901
- type: 'text',
902
- uuid: uuid,
903
- sendingTime: sendingTime
904
- };
905
-
906
- if (textMessage) {
907
- text = textMessage;
908
- data.packets = parseInt(text.length / packetSize);
909
- }
910
-
911
- if (text.length > packetSize)
912
- data.message = text.slice(0, packetSize);
913
- else {
914
- data.message = text;
915
- data.last = true;
916
- data.isobject = isobject;
917
- }
918
-
919
- channel.send(data, _channel);
920
-
921
- textToTransfer = text.slice(data.message.length);
922
-
923
- if (textToTransfer.length) {
924
- setTimeout(function () {
925
- sendText(null, textToTransfer);
926
- }, root.chunkInterval || 100);
927
- }
928
- }
929
- }
930
- };
931
-
932
- // _______________
933
- // TextReceiver.js
934
-
935
- function TextReceiver() {
936
- const content = {};
937
-
938
- function receive(data, onmessage, userid) {
939
- // uuid is used to uniquely identify sending instance
940
- const uuid = data.uuid;
941
- if (!content[uuid]) content[uuid] = [];
942
-
943
- content[uuid].push(data.message);
944
- if (data.last) {
945
- let message = content[uuid].join('');
946
- if (data.isobject) message = JSON.parse(message);
947
-
948
- // latency detection
949
- const receivingTime = new Date().getTime();
950
- const latency = receivingTime - data.sendingTime;
951
-
952
- onmessage(message, userid, latency);
953
-
954
- delete content[uuid];
955
- }
956
- }
957
-
958
- return {
959
- receive: receive
960
- };
961
- }
962
-
963
- function swap(arr) {
964
- const swapped = [],
965
- length = arr.length;
966
- for (let i = 0; i < length; i++)
967
- if (arr[i]) swapped.push(arr[i]);
968
- return swapped;
969
- }
970
-
971
- window.moz = !!navigator.mozGetUserMedia;
972
- window.IsDataChannelSupported = !((moz && !navigator.mozGetUserMedia) || (!moz && !navigator.webkitGetUserMedia));
973
-
974
- function RTCPeerConnection(options) {
975
- const w = window,
976
- PeerConnection = w.RTCPeerConnection || w.mozRTCPeerConnection || w.webkitRTCPeerConnection,
977
- SessionDescription = w.RTCSessionDescription || w.mozRTCSessionDescription || w.RTCSessionDescription,
978
- IceCandidate = w.mozRTCIceCandidate || w.RTCIceCandidate;
979
-
980
- let iceServers = [];
981
-
982
- if (isFirefox) {
983
- iceServers.push({
984
- url: 'stun:23.21.150.121'
985
- });
986
-
987
- iceServers.push({
988
- url: 'stun:stun.options.mozilla.com'
989
- });
990
- }
991
-
992
- if (isChrome) {
993
- iceServers.push({
994
- url: 'stun:stun.l.google.com:19302'
995
- });
996
-
997
- iceServers.push({
998
- url: 'stun:stun.anyfirewall.com:3478'
999
- });
1000
- }
1001
-
1002
- if (isChrome && chromeVersion < 28) {
1003
- iceServers.push({
1004
- url: 'turn:homeo@turn.bistri.com:80?transport=udp',
1005
- credential: 'homeo'
1006
- });
1007
-
1008
- iceServers.push({
1009
- url: 'turn:homeo@turn.bistri.com:80?transport=tcp',
1010
- credential: 'homeo'
1011
- });
1012
- }
1013
-
1014
- if (isChrome && chromeVersion >= 28) {
1015
- iceServers.push({
1016
- url: 'turn:turn.bistri.com:80?transport=udp',
1017
- credential: 'homeo',
1018
- username: 'homeo'
1019
- });
1020
-
1021
- iceServers.push({
1022
- url: 'turn:turn.bistri.com:80?transport=tcp',
1023
- credential: 'homeo',
1024
- username: 'homeo'
1025
- });
1026
-
1027
- iceServers.push({
1028
- url: 'turn:turn.anyfirewall.com:443?transport=tcp',
1029
- credential: 'webrtc',
1030
- username: 'webrtc'
1031
- });
1032
- }
1033
-
1034
- if (options.iceServers) iceServers = options.iceServers;
1035
-
1036
- iceServers = {
1037
- iceServers: iceServers
1038
- };
1039
-
1040
- const optional = {
1041
- optional: []
1042
- };
1043
-
1044
- if (!moz && !options.preferSCTP) {
1045
- optional.optional = [{
1046
- RtpDataChannels: true
1047
- }];
1048
- }
1049
-
1050
- if (!navigator.onLine) {
1051
- iceServers = null;
1052
- console.warn('No internet connection detected. No STUN/TURN server is used to make sure local/host candidates are used for peers connection.');
1053
- }
1054
-
1055
- const peerConnection = new PeerConnection(iceServers, optional);
1056
-
1057
- openOffererChannel();
1058
- peerConnection.onicecandidate = onicecandidate;
1059
-
1060
- function onicecandidate(event) {
1061
- if (!event.candidate || !peerConnection) return;
1062
- if (options.onICE) options.onICE(event.candidate);
1063
- }
1064
-
1065
- const constraints = options.constraints || {
1066
- optional: [],
1067
- mandatory: {
1068
- OfferToReceiveAudio: !!moz,
1069
- OfferToReceiveVideo: !!moz
1070
- }
1071
- };
1072
-
1073
- function onSdpError(e) {
1074
- let message = JSON.stringify(e, null, '\t');
1075
-
1076
- if (message.indexOf('RTP/SAVPF Expects at least 4 fields') != -1) {
1077
- message = 'It seems that you are trying to interop RTP-datachannels with SCTP. It is not supported!';
1078
- }
1079
-
1080
- console.error('onSdpError:', message);
1081
- }
1082
-
1083
- function onSdpSuccess() {
1084
- }
1085
-
1086
- function createOffer() {
1087
- if (!options.onOfferSDP) return;
1088
-
1089
- peerConnection.createOffer(function (sessionDescription) {
1090
- sessionDescription.sdp = setBandwidth(sessionDescription.sdp);
1091
- peerConnection.setLocalDescription(sessionDescription);
1092
- options.onOfferSDP(sessionDescription);
1093
- }, onSdpError, constraints);
1094
- }
1095
-
1096
- function createAnswer() {
1097
- if (!options.onAnswerSDP) return;
1098
-
1099
- options.offerSDP = new SessionDescription(options.offerSDP);
1100
- peerConnection.setRemoteDescription(options.offerSDP, onSdpSuccess, onSdpError);
1101
-
1102
- peerConnection.createAnswer(function (sessionDescription) {
1103
- sessionDescription.sdp = setBandwidth(sessionDescription.sdp);
1104
- peerConnection.setLocalDescription(sessionDescription);
1105
- options.onAnswerSDP(sessionDescription);
1106
- }, onSdpError, constraints);
1107
- }
1108
-
1109
- function setBandwidth(sdp) {
1110
- // Firefox has no support of "b=AS"
1111
- if (moz) return sdp;
1112
-
1113
- // remove existing bandwidth lines
1114
- sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, '');
1115
- sdp = sdp.replace(/a=mid:data\r\n/g, 'a=mid:data\r\nb=AS:1638400\r\n');
1116
-
1117
- return sdp;
1118
- }
1119
-
1120
- if (!moz) {
1121
- createOffer();
1122
- createAnswer();
1123
- }
1124
-
1125
- let channel;
1126
-
1127
- function openOffererChannel() {
1128
- if (moz && !options.onOfferSDP) return;
1129
-
1130
- if (!moz && options.preferSCTP && !options.onOfferSDP) return;
1131
-
1132
- _openOffererChannel();
1133
- if (moz) {
1134
- navigator.mozGetUserMedia({
1135
- audio: true,
1136
- fake: true
1137
- }, function (stream) {
1138
- peerConnection.addStream(stream);
1139
- createOffer();
1140
- }, useless);
1141
- }
1142
- }
1143
-
1144
- function _openOffererChannel() {
1145
- // protocol: 'text/chat', preset: true, stream: 16
1146
- // maxRetransmits:0 && ordered:false
1147
- const dataChannelDict = {};
1148
-
1149
- if (!moz && !options.preferSCTP) {
1150
- dataChannelDict.reliable = false; // Deprecated!
1151
- }
1152
-
1153
- console.debug('dataChannelDict', dataChannelDict);
1154
- channel = peerConnection.createDataChannel('channel', dataChannelDict);
1155
- setChannelEvents();
1156
- }
1157
-
1158
- function setChannelEvents() {
1159
- channel.onmessage = options.onmessage;
1160
- channel.onopen = function () {
1161
- options.onopen(channel);
1162
- };
1163
- channel.onclose = options.onclose;
1164
- channel.onerror = options.onerror;
1165
- }
1166
-
1167
- if (options.onAnswerSDP && moz && options.onmessage) openAnswererChannel();
1168
- if (!moz && options.preferSCTP && !options.onOfferSDP) openAnswererChannel();
1169
-
1170
- function openAnswererChannel() {
1171
- peerConnection.ondatachannel = function (event) {
1172
- channel = event.channel;
1173
- setChannelEvents();
1174
- };
1175
-
1176
- if (moz) {
1177
- navigator.mozGetUserMedia({
1178
- audio: true,
1179
- fake: true
1180
- }, function (stream) {
1181
- peerConnection.addStream(stream);
1182
- createAnswer();
1183
- }, useless);
1184
- }
1185
- }
1186
-
1187
- function useless() {
1188
- }
1189
-
1190
- return {
1191
- addAnswerSDP: function (sdp) {
1192
- sdp = new SessionDescription(sdp);
1193
- peerConnection.setRemoteDescription(sdp, onSdpSuccess, onSdpError);
1194
- },
1195
- addICE: function (candidate) {
1196
- peerConnection.addIceCandidate(new IceCandidate({
1197
- sdpMLineIndex: candidate.sdpMLineIndex,
1198
- candidate: candidate.candidate
1199
- }));
1200
- },
1201
-
1202
- peer: peerConnection,
1203
- channel: channel,
1204
- sendData: function (message) {
1205
- channel && channel.send(message);
1206
- }
1207
- };
1208
- }
1209
-
1210
- export default DataChannel;