node-rtc-connection 1.0.12 → 1.0.15
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/README.md +355 -289
- package/dist/index.cjs +4357 -3092
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +4357 -3092
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
- package/src/datachannel/RTCDataChannel.js +354 -0
- package/src/dtls/RTCCertificate.js +310 -0
- package/src/dtls/RTCDtlsTransport.js +247 -0
- package/src/foundation/ByteBufferQueue.js +235 -0
- package/src/foundation/RTCError.js +226 -0
- package/src/ice/RTCIceCandidate.js +301 -0
- package/src/ice/RTCIceTransport.js +998 -0
- package/src/index.d.ts +316 -145
- package/src/index.js +78 -45
- package/src/network/network-transport.js +478 -0
- package/src/peerconnection/RTCPeerConnection.js +847 -0
- package/src/sctp/RTCSctpTransport.js +253 -0
- package/src/sdp/RTCSessionDescription.js +102 -0
- package/src/sdp/sdp-utils.js +224 -0
- package/src/stun/stun-client.js +643 -0
- package/src/ICEGatherer.js +0 -341
- package/src/NativePeerConnectionFactory.js +0 -1044
- package/src/RTCDataChannel.js +0 -346
- package/src/RTCDataChannelEvent.js +0 -50
- package/src/RTCError.js +0 -66
- package/src/RTCIceCandidate.js +0 -184
- package/src/RTCPeerConnection.js +0 -505
- package/src/RTCPeerConnectionIceEvent.js +0 -58
- package/src/RTCSessionDescription.js +0 -62
- package/src/STUNClient.js +0 -222
- package/src/SecureConnection.js +0 -298
- package/src/TURNClient.js +0 -561
- package/src/UDPTransport.js +0 -236
package/src/RTCPeerConnection.js
DELETED
|
@@ -1,505 +0,0 @@
|
|
|
1
|
-
const EventEmitter = require('events');
|
|
2
|
-
const RTCDataChannel = require('./RTCDataChannel');
|
|
3
|
-
const RTCSessionDescription = require('./RTCSessionDescription');
|
|
4
|
-
const RTCIceCandidate = require('./RTCIceCandidate');
|
|
5
|
-
|
|
6
|
-
// Lazy-load factory to avoid circular dependency
|
|
7
|
-
let _defaultFactory = null;
|
|
8
|
-
function getDefaultFactory() {
|
|
9
|
-
if (!_defaultFactory) {
|
|
10
|
-
const NativePeerConnectionFactory = require('./NativePeerConnectionFactory');
|
|
11
|
-
_defaultFactory = new NativePeerConnectionFactory();
|
|
12
|
-
}
|
|
13
|
-
return _defaultFactory;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* RTCPeerConnection represents a WebRTC connection between the local computer and a remote peer.
|
|
18
|
-
* This is a DataChannel-only implementation ported from Chromium.
|
|
19
|
-
*/
|
|
20
|
-
class RTCPeerConnection extends EventEmitter {
|
|
21
|
-
constructor(configuration, nativePeerConnectionFactory) {
|
|
22
|
-
super();
|
|
23
|
-
|
|
24
|
-
this._configuration = this._parseConfiguration(configuration || {});
|
|
25
|
-
this._signalingState = 'stable';
|
|
26
|
-
this._iceGatheringState = 'new';
|
|
27
|
-
this._iceConnectionState = 'new';
|
|
28
|
-
this._connectionState = 'new';
|
|
29
|
-
this._pendingLocalDescription = null;
|
|
30
|
-
this._currentLocalDescription = null;
|
|
31
|
-
this._pendingRemoteDescription = null;
|
|
32
|
-
this._currentRemoteDescription = null;
|
|
33
|
-
this._dataChannels = new Map();
|
|
34
|
-
this._closed = false;
|
|
35
|
-
|
|
36
|
-
// Native peer connection (would be native WebRTC binding)
|
|
37
|
-
this._nativePeerConnection = null;
|
|
38
|
-
// Use provided factory or default factory
|
|
39
|
-
this._nativePeerConnectionFactory = nativePeerConnectionFactory || getDefaultFactory();
|
|
40
|
-
|
|
41
|
-
// Initialize native peer connection
|
|
42
|
-
this._initializeNativePeerConnection();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Parse and validate configuration
|
|
47
|
-
* @private
|
|
48
|
-
*/
|
|
49
|
-
_parseConfiguration(config) {
|
|
50
|
-
const configuration = {
|
|
51
|
-
iceServers: [],
|
|
52
|
-
iceTransportPolicy: 'all',
|
|
53
|
-
bundlePolicy: 'balanced',
|
|
54
|
-
rtcpMuxPolicy: 'require',
|
|
55
|
-
iceCandidatePoolSize: 0
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
if (config.iceServers) {
|
|
59
|
-
configuration.iceServers = config.iceServers.map(server => ({
|
|
60
|
-
urls: Array.isArray(server.urls) ? server.urls : [server.urls],
|
|
61
|
-
username: server.username || '',
|
|
62
|
-
credential: server.credential || ''
|
|
63
|
-
}));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (config.iceTransportPolicy) {
|
|
67
|
-
configuration.iceTransportPolicy = config.iceTransportPolicy;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (config.bundlePolicy) {
|
|
71
|
-
configuration.bundlePolicy = config.bundlePolicy;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (config.rtcpMuxPolicy) {
|
|
75
|
-
configuration.rtcpMuxPolicy = config.rtcpMuxPolicy;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (config.iceCandidatePoolSize !== undefined) {
|
|
79
|
-
configuration.iceCandidatePoolSize = config.iceCandidatePoolSize;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return configuration;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Initialize native peer connection with factory
|
|
87
|
-
* @private
|
|
88
|
-
*/
|
|
89
|
-
_initializeNativePeerConnection() {
|
|
90
|
-
if (!this._nativePeerConnectionFactory) {
|
|
91
|
-
throw new Error('Native PeerConnection factory not provided');
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Create native peer connection
|
|
95
|
-
this._nativePeerConnection = this._nativePeerConnectionFactory.createPeerConnection(
|
|
96
|
-
this._configuration
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
if (!this._nativePeerConnection) {
|
|
100
|
-
throw new Error('Failed to create native peer connection');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Setup observers
|
|
104
|
-
this._setupObservers();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Setup observers for native peer connection events
|
|
109
|
-
* @private
|
|
110
|
-
*/
|
|
111
|
-
_setupObservers() {
|
|
112
|
-
if (!this._nativePeerConnection) {
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Signaling state change
|
|
117
|
-
this._nativePeerConnection.on('signalingstatechange', (state) => {
|
|
118
|
-
this._signalingState = this._convertSignalingState(state);
|
|
119
|
-
this.emit('signalingstatechange');
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// ICE connection state change
|
|
123
|
-
this._nativePeerConnection.on('iceconnectionstatechange', (state) => {
|
|
124
|
-
this._iceConnectionState = this._convertIceConnectionState(state);
|
|
125
|
-
this.emit('iceconnectionstatechange');
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
// ICE gathering state change
|
|
129
|
-
this._nativePeerConnection.on('icegatheringstatechange', (state) => {
|
|
130
|
-
this._iceGatheringState = this._convertIceGatheringState(state);
|
|
131
|
-
this.emit('icegatheringstatechange');
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
// Connection state change
|
|
135
|
-
this._nativePeerConnection.on('connectionstatechange', (state) => {
|
|
136
|
-
this._connectionState = this._convertConnectionState(state);
|
|
137
|
-
this.emit('connectionstatechange');
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// ICE candidate
|
|
141
|
-
this._nativePeerConnection.on('icecandidate', (candidate) => {
|
|
142
|
-
const iceCandidate = candidate ? new RTCIceCandidate(candidate) : null;
|
|
143
|
-
this.emit('icecandidate', { candidate: iceCandidate });
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// Data channel (remote)
|
|
147
|
-
this._nativePeerConnection.on('datachannel', (nativeChannel) => {
|
|
148
|
-
const dataChannel = new RTCDataChannel(nativeChannel, this);
|
|
149
|
-
this._dataChannels.set(dataChannel.label, dataChannel);
|
|
150
|
-
this.emit('datachannel', { channel: dataChannel });
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// Negotiation needed
|
|
154
|
-
this._nativePeerConnection.on('negotiationneeded', () => {
|
|
155
|
-
this.emit('negotiationneeded');
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* The current signaling state
|
|
161
|
-
*/
|
|
162
|
-
get signalingState() {
|
|
163
|
-
return this._signalingState;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* The current ICE gathering state
|
|
168
|
-
*/
|
|
169
|
-
get iceGatheringState() {
|
|
170
|
-
return this._iceGatheringState;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* The current ICE connection state
|
|
175
|
-
*/
|
|
176
|
-
get iceConnectionState() {
|
|
177
|
-
return this._iceConnectionState;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* The current connection state
|
|
182
|
-
*/
|
|
183
|
-
get connectionState() {
|
|
184
|
-
return this._connectionState;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* The local description
|
|
189
|
-
*/
|
|
190
|
-
get localDescription() {
|
|
191
|
-
return this._currentLocalDescription || this._pendingLocalDescription;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* The remote description
|
|
196
|
-
*/
|
|
197
|
-
get remoteDescription() {
|
|
198
|
-
return this._currentRemoteDescription || this._pendingRemoteDescription;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* The pending local description
|
|
203
|
-
*/
|
|
204
|
-
get pendingLocalDescription() {
|
|
205
|
-
return this._pendingLocalDescription;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* The pending remote description
|
|
210
|
-
*/
|
|
211
|
-
get pendingRemoteDescription() {
|
|
212
|
-
return this._pendingRemoteDescription;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* The current local description
|
|
217
|
-
*/
|
|
218
|
-
get currentLocalDescription() {
|
|
219
|
-
return this._currentLocalDescription;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* The current remote description
|
|
224
|
-
*/
|
|
225
|
-
get currentRemoteDescription() {
|
|
226
|
-
return this._currentRemoteDescription;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Create an offer
|
|
231
|
-
* @param {Object} options - Offer options
|
|
232
|
-
* @returns {Promise<RTCSessionDescriptionInit>}
|
|
233
|
-
*/
|
|
234
|
-
async createOffer(options = {}) {
|
|
235
|
-
this._checkClosed();
|
|
236
|
-
|
|
237
|
-
if (!this._nativePeerConnection) {
|
|
238
|
-
throw new Error('Native peer connection not available');
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
try {
|
|
242
|
-
const nativeDescription = await this._nativePeerConnection.createOffer(options);
|
|
243
|
-
return new RTCSessionDescription({
|
|
244
|
-
type: nativeDescription.type,
|
|
245
|
-
sdp: nativeDescription.sdp
|
|
246
|
-
});
|
|
247
|
-
} catch (error) {
|
|
248
|
-
throw new Error(`Failed to create offer: ${error.message}`);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Create an answer
|
|
254
|
-
* @param {Object} options - Answer options
|
|
255
|
-
* @returns {Promise<RTCSessionDescriptionInit>}
|
|
256
|
-
*/
|
|
257
|
-
async createAnswer(options = {}) {
|
|
258
|
-
this._checkClosed();
|
|
259
|
-
|
|
260
|
-
if (!this._nativePeerConnection) {
|
|
261
|
-
throw new Error('Native peer connection not available');
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
try {
|
|
265
|
-
const nativeDescription = await this._nativePeerConnection.createAnswer(options);
|
|
266
|
-
return new RTCSessionDescription({
|
|
267
|
-
type: nativeDescription.type,
|
|
268
|
-
sdp: nativeDescription.sdp
|
|
269
|
-
});
|
|
270
|
-
} catch (error) {
|
|
271
|
-
throw new Error(`Failed to create answer: ${error.message}`);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Set the local description
|
|
277
|
-
* @param {RTCSessionDescriptionInit} description
|
|
278
|
-
* @returns {Promise<void>}
|
|
279
|
-
*/
|
|
280
|
-
async setLocalDescription(description) {
|
|
281
|
-
this._checkClosed();
|
|
282
|
-
|
|
283
|
-
if (!this._nativePeerConnection) {
|
|
284
|
-
throw new Error('Native peer connection not available');
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
try {
|
|
288
|
-
await this._nativePeerConnection.setLocalDescription(description);
|
|
289
|
-
|
|
290
|
-
if (description.type === 'offer') {
|
|
291
|
-
this._pendingLocalDescription = new RTCSessionDescription(description);
|
|
292
|
-
} else if (description.type === 'answer') {
|
|
293
|
-
this._currentLocalDescription = new RTCSessionDescription(description);
|
|
294
|
-
this._pendingLocalDescription = null;
|
|
295
|
-
} else if (description.type === 'rollback') {
|
|
296
|
-
this._pendingLocalDescription = null;
|
|
297
|
-
}
|
|
298
|
-
} catch (error) {
|
|
299
|
-
throw new Error(`Failed to set local description: ${error.message}`);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Set the remote description
|
|
305
|
-
* @param {RTCSessionDescriptionInit} description
|
|
306
|
-
* @returns {Promise<void>}
|
|
307
|
-
*/
|
|
308
|
-
async setRemoteDescription(description) {
|
|
309
|
-
this._checkClosed();
|
|
310
|
-
|
|
311
|
-
if (!this._nativePeerConnection) {
|
|
312
|
-
throw new Error('Native peer connection not available');
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
try {
|
|
316
|
-
await this._nativePeerConnection.setRemoteDescription(description);
|
|
317
|
-
|
|
318
|
-
if (description.type === 'offer') {
|
|
319
|
-
this._pendingRemoteDescription = new RTCSessionDescription(description);
|
|
320
|
-
} else if (description.type === 'answer') {
|
|
321
|
-
this._currentRemoteDescription = new RTCSessionDescription(description);
|
|
322
|
-
this._pendingRemoteDescription = null;
|
|
323
|
-
} else if (description.type === 'rollback') {
|
|
324
|
-
this._pendingRemoteDescription = null;
|
|
325
|
-
}
|
|
326
|
-
} catch (error) {
|
|
327
|
-
throw new Error(`Failed to set remote description: ${error.message}`);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Add an ICE candidate
|
|
333
|
-
* @param {RTCIceCandidateInit} candidate
|
|
334
|
-
* @returns {Promise<void>}
|
|
335
|
-
*/
|
|
336
|
-
async addIceCandidate(candidate) {
|
|
337
|
-
this._checkClosed();
|
|
338
|
-
|
|
339
|
-
if (!this._nativePeerConnection) {
|
|
340
|
-
throw new Error('Native peer connection not available');
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (!candidate) {
|
|
344
|
-
// End of candidates
|
|
345
|
-
return;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
try {
|
|
349
|
-
await this._nativePeerConnection.addIceCandidate(candidate);
|
|
350
|
-
} catch (error) {
|
|
351
|
-
throw new Error(`Failed to add ICE candidate: ${error.message}`);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Create a data channel
|
|
357
|
-
* @param {string} label - Channel label
|
|
358
|
-
* @param {Object} dataChannelDict - Channel options
|
|
359
|
-
* @returns {RTCDataChannel}
|
|
360
|
-
*/
|
|
361
|
-
createDataChannel(label, dataChannelDict = {}) {
|
|
362
|
-
this._checkClosed();
|
|
363
|
-
|
|
364
|
-
if (!this._nativePeerConnection) {
|
|
365
|
-
throw new Error('Native peer connection not available');
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
const options = {
|
|
369
|
-
ordered: dataChannelDict.ordered !== undefined ? dataChannelDict.ordered : true,
|
|
370
|
-
maxPacketLifeTime: dataChannelDict.maxPacketLifeTime,
|
|
371
|
-
maxRetransmits: dataChannelDict.maxRetransmits,
|
|
372
|
-
protocol: dataChannelDict.protocol || '',
|
|
373
|
-
negotiated: dataChannelDict.negotiated || false,
|
|
374
|
-
id: dataChannelDict.id
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
try {
|
|
378
|
-
const nativeChannel = this._nativePeerConnection.createDataChannel(label, options);
|
|
379
|
-
const dataChannel = new RTCDataChannel(nativeChannel, this);
|
|
380
|
-
this._dataChannels.set(label, dataChannel);
|
|
381
|
-
return dataChannel;
|
|
382
|
-
} catch (error) {
|
|
383
|
-
throw new Error(`Failed to create data channel: ${error.message}`);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* Get configuration
|
|
389
|
-
* @returns {Object}
|
|
390
|
-
*/
|
|
391
|
-
getConfiguration() {
|
|
392
|
-
return { ...this._configuration };
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Set configuration
|
|
397
|
-
* @param {Object} configuration
|
|
398
|
-
*/
|
|
399
|
-
setConfiguration(configuration) {
|
|
400
|
-
this._checkClosed();
|
|
401
|
-
this._configuration = this._parseConfiguration(configuration);
|
|
402
|
-
|
|
403
|
-
if (this._nativePeerConnection) {
|
|
404
|
-
this._nativePeerConnection.setConfiguration(this._configuration);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
/**
|
|
409
|
-
* Close the peer connection
|
|
410
|
-
*/
|
|
411
|
-
close() {
|
|
412
|
-
if (this._closed) {
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
this._closed = true;
|
|
417
|
-
this._signalingState = 'closed';
|
|
418
|
-
|
|
419
|
-
// Close all data channels
|
|
420
|
-
for (const [label, channel] of this._dataChannels) {
|
|
421
|
-
channel.close();
|
|
422
|
-
channel.dispose();
|
|
423
|
-
}
|
|
424
|
-
this._dataChannels.clear();
|
|
425
|
-
|
|
426
|
-
// Close native peer connection
|
|
427
|
-
if (this._nativePeerConnection) {
|
|
428
|
-
this._nativePeerConnection.close();
|
|
429
|
-
this._nativePeerConnection.removeAllListeners();
|
|
430
|
-
this._nativePeerConnection = null;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
this.emit('signalingstatechange');
|
|
434
|
-
this.removeAllListeners();
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* Get stats
|
|
439
|
-
* @returns {Promise<Object>}
|
|
440
|
-
*/
|
|
441
|
-
async getStats() {
|
|
442
|
-
this._checkClosed();
|
|
443
|
-
|
|
444
|
-
if (!this._nativePeerConnection) {
|
|
445
|
-
throw new Error('Native peer connection not available');
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
try {
|
|
449
|
-
return await this._nativePeerConnection.getStats();
|
|
450
|
-
} catch (error) {
|
|
451
|
-
throw new Error(`Failed to get stats: ${error.message}`);
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
/**
|
|
456
|
-
* Check if connection is closed
|
|
457
|
-
* @private
|
|
458
|
-
*/
|
|
459
|
-
_checkClosed() {
|
|
460
|
-
if (this._closed || this._signalingState === 'closed') {
|
|
461
|
-
throw new Error("The RTCPeerConnection's signalingState is 'closed'");
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* Convert native signaling state to string
|
|
467
|
-
* @private
|
|
468
|
-
*/
|
|
469
|
-
_convertSignalingState(state) {
|
|
470
|
-
const states = ['stable', 'have-local-offer', 'have-remote-offer',
|
|
471
|
-
'have-local-pranswer', 'have-remote-pranswer', 'closed'];
|
|
472
|
-
return states[state] || 'stable';
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* Convert native ICE connection state to string
|
|
477
|
-
* @private
|
|
478
|
-
*/
|
|
479
|
-
_convertIceConnectionState(state) {
|
|
480
|
-
const states = ['new', 'checking', 'connected', 'completed',
|
|
481
|
-
'failed', 'disconnected', 'closed'];
|
|
482
|
-
return states[state] || 'new';
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* Convert native ICE gathering state to string
|
|
487
|
-
* @private
|
|
488
|
-
*/
|
|
489
|
-
_convertIceGatheringState(state) {
|
|
490
|
-
const states = ['new', 'gathering', 'complete'];
|
|
491
|
-
return states[state] || 'new';
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
/**
|
|
495
|
-
* Convert native connection state to string
|
|
496
|
-
* @private
|
|
497
|
-
*/
|
|
498
|
-
_convertConnectionState(state) {
|
|
499
|
-
const states = ['new', 'connecting', 'connected', 'disconnected',
|
|
500
|
-
'failed', 'closed'];
|
|
501
|
-
return states[state] || 'new';
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
module.exports = RTCPeerConnection;
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RTCPeerConnectionIceEvent is fired when an ICE candidate is available.
|
|
3
|
-
* Ported from Chromium's implementation.
|
|
4
|
-
*/
|
|
5
|
-
class RTCPeerConnectionIceEvent {
|
|
6
|
-
constructor(type, eventInitDict = {}) {
|
|
7
|
-
this._type = type;
|
|
8
|
-
this._candidate = eventInitDict.candidate || null;
|
|
9
|
-
this._url = eventInitDict.url || null;
|
|
10
|
-
this._bubbles = eventInitDict.bubbles || false;
|
|
11
|
-
this._cancelable = eventInitDict.cancelable || false;
|
|
12
|
-
this._timestamp = Date.now();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* The event type
|
|
17
|
-
*/
|
|
18
|
-
get type() {
|
|
19
|
-
return this._type;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* The RTCIceCandidate associated with the event
|
|
24
|
-
*/
|
|
25
|
-
get candidate() {
|
|
26
|
-
return this._candidate;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* The URL of the TURN or STUN server
|
|
31
|
-
*/
|
|
32
|
-
get url() {
|
|
33
|
-
return this._url;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Whether the event bubbles
|
|
38
|
-
*/
|
|
39
|
-
get bubbles() {
|
|
40
|
-
return this._bubbles;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Whether the event is cancelable
|
|
45
|
-
*/
|
|
46
|
-
get cancelable() {
|
|
47
|
-
return this._cancelable;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* The timestamp when the event was created
|
|
52
|
-
*/
|
|
53
|
-
get timeStamp() {
|
|
54
|
-
return this._timestamp;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
module.exports = RTCPeerConnectionIceEvent;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RTCSessionDescription represents a session description.
|
|
3
|
-
* Ported from Chromium's implementation.
|
|
4
|
-
*/
|
|
5
|
-
class RTCSessionDescription {
|
|
6
|
-
constructor(descriptionInitDict = {}) {
|
|
7
|
-
this._type = descriptionInitDict.type || '';
|
|
8
|
-
this._sdp = descriptionInitDict.sdp || '';
|
|
9
|
-
|
|
10
|
-
// Validate type
|
|
11
|
-
const validTypes = ['offer', 'answer', 'pranswer', 'rollback'];
|
|
12
|
-
if (this._type && !validTypes.includes(this._type)) {
|
|
13
|
-
throw new Error(`Invalid type: ${this._type}`);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* The type of session description
|
|
19
|
-
* Values: 'offer', 'answer', 'pranswer', 'rollback'
|
|
20
|
-
*/
|
|
21
|
-
get type() {
|
|
22
|
-
return this._type;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
set type(value) {
|
|
26
|
-
const validTypes = ['offer', 'answer', 'pranswer', 'rollback'];
|
|
27
|
-
if (value && !validTypes.includes(value)) {
|
|
28
|
-
throw new Error(`Invalid type: ${value}`);
|
|
29
|
-
}
|
|
30
|
-
this._type = value;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The SDP string
|
|
35
|
-
*/
|
|
36
|
-
get sdp() {
|
|
37
|
-
return this._sdp;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
set sdp(value) {
|
|
41
|
-
this._sdp = value || '';
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Convert to JSON
|
|
46
|
-
*/
|
|
47
|
-
toJSON() {
|
|
48
|
-
return {
|
|
49
|
-
type: this._type,
|
|
50
|
-
sdp: this._sdp
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Convert to string
|
|
56
|
-
*/
|
|
57
|
-
toString() {
|
|
58
|
-
return `RTCSessionDescription { type: "${this._type}", sdp: "${this._sdp.substring(0, 50)}..." }`;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
module.exports = RTCSessionDescription;
|