werift 0.23.0 → 0.24.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.
- package/README.md +46 -0
- package/lib/common/src/binary.js +2 -3
- package/lib/common/src/binary.js.map +1 -1
- package/lib/common/src/transport.d.ts +22 -9
- package/lib/common/src/transport.js +152 -25
- package/lib/common/src/transport.js.map +1 -1
- package/lib/ice/src/candidate.d.ts +16 -1
- package/lib/ice/src/candidate.js +99 -15
- package/lib/ice/src/candidate.js.map +1 -1
- package/lib/ice/src/ice.d.ts +2 -0
- package/lib/ice/src/ice.js +175 -50
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/iceBase.d.ts +23 -2
- package/lib/ice/src/iceBase.js +63 -1
- package/lib/ice/src/iceBase.js.map +1 -1
- package/lib/ice/src/index.d.ts +2 -0
- package/lib/ice/src/index.js +2 -0
- package/lib/ice/src/index.js.map +1 -1
- package/lib/ice/src/internal/selectAddresses.d.ts +9 -0
- package/lib/ice/src/internal/selectAddresses.js +40 -0
- package/lib/ice/src/internal/selectAddresses.js.map +1 -0
- package/lib/ice/src/stun/const.d.ts +1 -26
- package/lib/ice/src/stun/const.js +15 -54
- package/lib/ice/src/stun/const.js.map +1 -1
- package/lib/ice/src/stun/message.d.ts +1 -25
- package/lib/ice/src/stun/message.js +15 -149
- package/lib/ice/src/stun/message.js.map +1 -1
- package/lib/ice/src/stun/protocol.d.ts +1 -1
- package/lib/ice/src/stun/protocol.js +2 -2
- package/lib/ice/src/stun/protocol.js.map +1 -1
- package/lib/ice/src/stun/tcpFrame.d.ts +5 -0
- package/lib/ice/src/stun/tcpFrame.js +26 -0
- package/lib/ice/src/stun/tcpFrame.js.map +1 -0
- package/lib/ice/src/stun/tcpProtocol.d.ts +51 -0
- package/lib/ice/src/stun/tcpProtocol.js +326 -0
- package/lib/ice/src/stun/tcpProtocol.js.map +1 -0
- package/lib/ice/src/stun/transaction.d.ts +2 -1
- package/lib/ice/src/stun/transaction.js +9 -3
- package/lib/ice/src/stun/transaction.js.map +1 -1
- package/lib/ice/src/turn/frame.d.ts +1 -0
- package/lib/ice/src/turn/frame.js +18 -0
- package/lib/ice/src/turn/frame.js.map +1 -0
- package/lib/ice/src/turn/protocol.d.ts +9 -7
- package/lib/ice/src/turn/protocol.js +32 -44
- package/lib/ice/src/turn/protocol.js.map +1 -1
- package/lib/ice/src/types/model.d.ts +1 -1
- package/lib/ice/src/types/model.js.map +1 -1
- package/lib/ice/src/utils.js +2 -31
- package/lib/ice/src/utils.js.map +1 -1
- package/lib/{ice → ice-server}/src/stun/attributes.d.ts +12 -5
- package/lib/{ice → ice-server}/src/stun/attributes.js +69 -66
- package/lib/ice-server/src/stun/attributes.js.map +1 -0
- package/lib/ice-server/src/stun/const.d.ts +28 -0
- package/lib/ice-server/src/stun/const.js +88 -0
- package/lib/ice-server/src/stun/const.js.map +1 -0
- package/lib/ice-server/src/stun/ip.d.ts +12 -0
- package/lib/ice-server/src/stun/ip.js +88 -0
- package/lib/ice-server/src/stun/ip.js.map +1 -0
- package/lib/ice-server/src/stun/message.d.ts +37 -0
- package/lib/ice-server/src/stun/message.js +190 -0
- package/lib/ice-server/src/stun/message.js.map +1 -0
- package/lib/ice-server/src/turn/auth.d.ts +1 -0
- package/lib/ice-server/src/turn/auth.js +10 -0
- package/lib/ice-server/src/turn/auth.js.map +1 -0
- package/lib/ice-server/src/turn/frame.d.ts +13 -0
- package/lib/ice-server/src/turn/frame.js +69 -0
- package/lib/ice-server/src/turn/frame.js.map +1 -0
- package/lib/index.mjs +2866 -946
- package/lib/nonstandard/index.mjs +1872 -455
- package/lib/rtp/src/codec/av1.js +11 -5
- package/lib/rtp/src/codec/av1.js.map +1 -1
- package/lib/rtp/src/codec/leb128.d.ts +5 -0
- package/lib/rtp/src/codec/leb128.js +24 -0
- package/lib/rtp/src/codec/leb128.js.map +1 -0
- package/lib/rtp/src/extra/container/mp4/container.d.ts +9 -6
- package/lib/rtp/src/extra/container/mp4/container.js +258 -173
- package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
- package/lib/rtp/src/extra/container/mp4/h264.d.ts +1 -0
- package/lib/rtp/src/extra/container/mp4/h264.js +13 -0
- package/lib/rtp/src/extra/container/mp4/h264.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4.d.ts +11 -7
- package/lib/rtp/src/extra/processor/mp4.js +115 -60
- package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4Callback.d.ts +2 -3
- package/lib/rtp/src/extra/processor/mp4Callback.js +5 -3
- package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
- package/lib/rtp/src/rtp/rtx.js +4 -6
- package/lib/rtp/src/rtp/rtx.js.map +1 -1
- package/lib/rtp/src/srtp/context/context.d.ts +2 -0
- package/lib/rtp/src/srtp/context/context.js +12 -12
- package/lib/rtp/src/srtp/context/context.js.map +1 -1
- package/lib/sctp/src/param.js +31 -15
- package/lib/sctp/src/param.js.map +1 -1
- package/lib/sctp/src/sctp.js +10 -9
- package/lib/sctp/src/sctp.js.map +1 -1
- package/lib/webrtc/src/dataChannel.d.ts +3 -2
- package/lib/webrtc/src/dataChannel.js +9 -2
- package/lib/webrtc/src/dataChannel.js.map +1 -1
- package/lib/webrtc/src/errors.d.ts +3 -0
- package/lib/webrtc/src/errors.js +11 -0
- package/lib/webrtc/src/errors.js.map +1 -0
- package/lib/webrtc/src/helper.d.ts +5 -1
- package/lib/webrtc/src/helper.js +33 -1
- package/lib/webrtc/src/helper.js.map +1 -1
- package/lib/webrtc/src/media/receiver/statistics.d.ts +4 -1
- package/lib/webrtc/src/media/receiver/statistics.js +22 -0
- package/lib/webrtc/src/media/receiver/statistics.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.d.ts +15 -2
- package/lib/webrtc/src/media/rtpReceiver.js +135 -20
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpSender.d.ts +32 -7
- package/lib/webrtc/src/media/rtpSender.js +179 -31
- package/lib/webrtc/src/media/rtpSender.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +13 -4
- package/lib/webrtc/src/media/rtpTransceiver.js +26 -5
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/media/stats.d.ts +15 -1
- package/lib/webrtc/src/media/stats.js +55 -1
- package/lib/webrtc/src/media/stats.js.map +1 -1
- package/lib/webrtc/src/media/track.d.ts +2 -1
- package/lib/webrtc/src/media/track.js +7 -1
- package/lib/webrtc/src/media/track.js.map +1 -1
- package/lib/webrtc/src/nonstandard/dummyMedia.d.ts +19 -0
- package/lib/webrtc/src/nonstandard/dummyMedia.js +157 -0
- package/lib/webrtc/src/nonstandard/dummyMedia.js.map +1 -0
- package/lib/webrtc/src/nonstandard/navigator.d.ts +18 -8
- package/lib/webrtc/src/nonstandard/navigator.js +96 -32
- package/lib/webrtc/src/nonstandard/navigator.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.d.ts +16 -0
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.js +360 -0
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.js.map +1 -0
- package/lib/webrtc/src/nonstandard/userMedia.d.ts +71 -31
- package/lib/webrtc/src/nonstandard/userMedia.js +454 -108
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +183 -50
- package/lib/webrtc/src/peerConnection.js +458 -109
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sctpManager.d.ts +1 -1
- package/lib/webrtc/src/sctpManager.js +27 -7
- package/lib/webrtc/src/sctpManager.js.map +1 -1
- package/lib/webrtc/src/sdp.d.ts +10 -7
- package/lib/webrtc/src/sdp.js +40 -44
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/sdpManager.d.ts +4 -3
- package/lib/webrtc/src/sdpManager.js +50 -27
- package/lib/webrtc/src/sdpManager.js.map +1 -1
- package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
- package/lib/webrtc/src/secureTransportManager.js +100 -22
- package/lib/webrtc/src/secureTransportManager.js.map +1 -1
- package/lib/webrtc/src/transceiverManager.d.ts +5 -4
- package/lib/webrtc/src/transceiverManager.js +61 -62
- package/lib/webrtc/src/transceiverManager.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.d.ts +15 -4
- package/lib/webrtc/src/transport/dtls.js +91 -23
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/lib/webrtc/src/transport/ice.d.ts +21 -3
- package/lib/webrtc/src/transport/ice.js +159 -30
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.d.ts +1 -0
- package/lib/webrtc/src/transport/sctp.js +26 -22
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +12 -4
- package/lib/webrtc/src/utils.js +118 -16
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +7 -10
- package/lib/ice/src/stun/attributes.js.map +0 -1
- package/lib/rtp/src/extra/container/mp4/mp4box.d.ts +0 -5
- package/lib/rtp/src/extra/container/mp4/mp4box.js +0 -32
- package/lib/rtp/src/extra/container/mp4/mp4box.js.map +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defaultPeerConfig = exports.findCodecByMimeType = exports.RTCPeerConnection = void 0;
|
|
3
|
+
exports.RTCTrackEvent = exports.defaultPeerConfig = exports.findCodecByMimeType = exports.RTCPeerConnection = void 0;
|
|
4
4
|
const crypto_1 = require("crypto");
|
|
5
|
+
const errors_1 = require("./errors");
|
|
5
6
|
const helper_1 = require("./helper");
|
|
6
7
|
const common_1 = require("./imports/common");
|
|
7
8
|
const media_1 = require("./media");
|
|
@@ -13,9 +14,92 @@ const secureTransportManager_1 = require("./secureTransportManager");
|
|
|
13
14
|
const sctp_1 = require("./transport/sctp");
|
|
14
15
|
const utils_1 = require("./utils");
|
|
15
16
|
const log = (0, common_1.debug)("werift:packages/webrtc/src/peerConnection.ts");
|
|
17
|
+
/**
|
|
18
|
+
* W3C compatibility notes kept near the public RTCPeerConnection surface so the
|
|
19
|
+
* reviewable diff does not depend on external PR text.
|
|
20
|
+
*
|
|
21
|
+
* - `current/pending*Description`, `canTrickleIceCandidates`, `sctp`,
|
|
22
|
+
* `addIceCandidate(null)`, and `RTCConfiguration` round-trip behavior are
|
|
23
|
+
* implemented here and covered by `tests/wpt/peerConnectionApiCompatibility.test.ts`.
|
|
24
|
+
* - `addIceCandidate()` also validates `sdpMid` / `sdpMLineIndex` /
|
|
25
|
+
* `usernameFragment` against the applied remote description and appends
|
|
26
|
+
* candidates or end-of-candidates markers to the corresponding m-section.
|
|
27
|
+
* The public API keeps werift's historical pre-SRD buffering behavior, while
|
|
28
|
+
* the WPT runner wraps the class to exercise strict spec rejection.
|
|
29
|
+
* - `bundlePolicy: "balanced"` is accepted for input compatibility but is
|
|
30
|
+
* normalized to werift's `"max-compat"` behavior, so `getConfiguration()`
|
|
31
|
+
* returns the normalized value.
|
|
32
|
+
* - `setLocalDescription()` keeps the historical `SessionDescription` return
|
|
33
|
+
* value for non-rollback calls, while `{ type: "rollback" }` resolves `void`
|
|
34
|
+
* to match the actual behavior without pretending to return a description.
|
|
35
|
+
* - API reference markdown is regenerated with `cd packages/webrtc && npm run doc`.
|
|
36
|
+
* The generated output lives under `packages/webrtc/doc/`; compatibility
|
|
37
|
+
* notes remain here and in the package README so review context is visible
|
|
38
|
+
* even when generated docs are not committed in the same change.
|
|
39
|
+
*/
|
|
16
40
|
class RTCPeerConnection extends helper_1.EventTarget {
|
|
41
|
+
get ondatachannel() {
|
|
42
|
+
return this.eventHandlers.ondatachannel ?? null;
|
|
43
|
+
}
|
|
44
|
+
set ondatachannel(value) {
|
|
45
|
+
this.eventHandlers.ondatachannel = value ?? undefined;
|
|
46
|
+
}
|
|
47
|
+
get onicecandidate() {
|
|
48
|
+
return this.eventHandlers.onicecandidate ?? null;
|
|
49
|
+
}
|
|
50
|
+
set onicecandidate(value) {
|
|
51
|
+
this.eventHandlers.onicecandidate = value ?? undefined;
|
|
52
|
+
}
|
|
53
|
+
get onicecandidateerror() {
|
|
54
|
+
return this.eventHandlers.onicecandidateerror ?? null;
|
|
55
|
+
}
|
|
56
|
+
set onicecandidateerror(value) {
|
|
57
|
+
this.eventHandlers.onicecandidateerror = value ?? undefined;
|
|
58
|
+
}
|
|
59
|
+
get onicegatheringstatechange() {
|
|
60
|
+
return this.eventHandlers.onicegatheringstatechange ?? null;
|
|
61
|
+
}
|
|
62
|
+
set onicegatheringstatechange(value) {
|
|
63
|
+
this.eventHandlers.onicegatheringstatechange = value ?? undefined;
|
|
64
|
+
}
|
|
65
|
+
get onnegotiationneeded() {
|
|
66
|
+
return this.eventHandlers.onnegotiationneeded ?? null;
|
|
67
|
+
}
|
|
68
|
+
set onnegotiationneeded(value) {
|
|
69
|
+
this.eventHandlers.onnegotiationneeded = value ?? undefined;
|
|
70
|
+
}
|
|
71
|
+
get onsignalingstatechange() {
|
|
72
|
+
return this.eventHandlers.onsignalingstatechange ?? null;
|
|
73
|
+
}
|
|
74
|
+
set onsignalingstatechange(value) {
|
|
75
|
+
this.eventHandlers.onsignalingstatechange = value ?? undefined;
|
|
76
|
+
}
|
|
77
|
+
get ontrack() {
|
|
78
|
+
return this.eventHandlers.ontrack ?? null;
|
|
79
|
+
}
|
|
80
|
+
set ontrack(value) {
|
|
81
|
+
this.eventHandlers.ontrack = value ?? undefined;
|
|
82
|
+
}
|
|
83
|
+
get onconnectionstatechange() {
|
|
84
|
+
return this.eventHandlers.onconnectionstatechange ?? null;
|
|
85
|
+
}
|
|
86
|
+
set onconnectionstatechange(value) {
|
|
87
|
+
this.eventHandlers.onconnectionstatechange = value ?? undefined;
|
|
88
|
+
}
|
|
89
|
+
get oniceconnectionstatechange() {
|
|
90
|
+
return this.eventHandlers.oniceconnectionstatechange ?? null;
|
|
91
|
+
}
|
|
92
|
+
set oniceconnectionstatechange(value) {
|
|
93
|
+
this.eventHandlers.oniceconnectionstatechange = value ?? undefined;
|
|
94
|
+
}
|
|
17
95
|
constructor(config = {}) {
|
|
18
96
|
super();
|
|
97
|
+
Object.defineProperty(this, "id", {
|
|
98
|
+
enumerable: true,
|
|
99
|
+
configurable: true,
|
|
100
|
+
writable: true,
|
|
101
|
+
value: (0, crypto_1.randomUUID)().toString()
|
|
102
|
+
});
|
|
19
103
|
Object.defineProperty(this, "cname", {
|
|
20
104
|
enumerable: true,
|
|
21
105
|
configurable: true,
|
|
@@ -88,11 +172,23 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
88
172
|
writable: true,
|
|
89
173
|
value: false
|
|
90
174
|
});
|
|
91
|
-
Object.defineProperty(this, "
|
|
175
|
+
Object.defineProperty(this, "lastCreatedAnswer", {
|
|
92
176
|
enumerable: true,
|
|
93
177
|
configurable: true,
|
|
94
178
|
writable: true,
|
|
95
|
-
value:
|
|
179
|
+
value: void 0
|
|
180
|
+
});
|
|
181
|
+
Object.defineProperty(this, "lastCreatedOffer", {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
configurable: true,
|
|
184
|
+
writable: true,
|
|
185
|
+
value: void 0
|
|
186
|
+
});
|
|
187
|
+
Object.defineProperty(this, "pendingRemoteCandidates", {
|
|
188
|
+
enumerable: true,
|
|
189
|
+
configurable: true,
|
|
190
|
+
writable: true,
|
|
191
|
+
value: []
|
|
96
192
|
});
|
|
97
193
|
Object.defineProperty(this, "iceGatheringStateChange", {
|
|
98
194
|
enumerable: true,
|
|
@@ -154,65 +250,18 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
154
250
|
writable: true,
|
|
155
251
|
value: new common_1.Event()
|
|
156
252
|
});
|
|
157
|
-
Object.defineProperty(this, "
|
|
253
|
+
Object.defineProperty(this, "eventHandlers", {
|
|
158
254
|
enumerable: true,
|
|
159
255
|
configurable: true,
|
|
160
256
|
writable: true,
|
|
161
|
-
value:
|
|
162
|
-
});
|
|
163
|
-
Object.defineProperty(this, "onicecandidate", {
|
|
164
|
-
enumerable: true,
|
|
165
|
-
configurable: true,
|
|
166
|
-
writable: true,
|
|
167
|
-
value: void 0
|
|
168
|
-
});
|
|
169
|
-
Object.defineProperty(this, "onicecandidateerror", {
|
|
170
|
-
enumerable: true,
|
|
171
|
-
configurable: true,
|
|
172
|
-
writable: true,
|
|
173
|
-
value: void 0
|
|
174
|
-
});
|
|
175
|
-
Object.defineProperty(this, "onicegatheringstatechange", {
|
|
176
|
-
enumerable: true,
|
|
177
|
-
configurable: true,
|
|
178
|
-
writable: true,
|
|
179
|
-
value: void 0
|
|
180
|
-
});
|
|
181
|
-
Object.defineProperty(this, "onnegotiationneeded", {
|
|
182
|
-
enumerable: true,
|
|
183
|
-
configurable: true,
|
|
184
|
-
writable: true,
|
|
185
|
-
value: void 0
|
|
186
|
-
});
|
|
187
|
-
Object.defineProperty(this, "onsignalingstatechange", {
|
|
188
|
-
enumerable: true,
|
|
189
|
-
configurable: true,
|
|
190
|
-
writable: true,
|
|
191
|
-
value: void 0
|
|
192
|
-
});
|
|
193
|
-
Object.defineProperty(this, "ontrack", {
|
|
194
|
-
enumerable: true,
|
|
195
|
-
configurable: true,
|
|
196
|
-
writable: true,
|
|
197
|
-
value: void 0
|
|
198
|
-
});
|
|
199
|
-
Object.defineProperty(this, "onconnectionstatechange", {
|
|
200
|
-
enumerable: true,
|
|
201
|
-
configurable: true,
|
|
202
|
-
writable: true,
|
|
203
|
-
value: void 0
|
|
204
|
-
});
|
|
205
|
-
Object.defineProperty(this, "oniceconnectionstatechange", {
|
|
206
|
-
enumerable: true,
|
|
207
|
-
configurable: true,
|
|
208
|
-
writable: true,
|
|
209
|
-
value: void 0
|
|
257
|
+
value: {}
|
|
210
258
|
});
|
|
211
259
|
Object.defineProperty(this, "needNegotiation", {
|
|
212
260
|
enumerable: true,
|
|
213
261
|
configurable: true,
|
|
214
262
|
writable: true,
|
|
215
263
|
value: async () => {
|
|
264
|
+
this.invalidateLastCreatedDescriptions();
|
|
216
265
|
this.shouldNegotiationneeded = true;
|
|
217
266
|
if (this.negotiationneeded || this.signalingState !== "stable") {
|
|
218
267
|
return;
|
|
@@ -221,8 +270,10 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
221
270
|
setImmediate(() => {
|
|
222
271
|
this.negotiationneeded = true;
|
|
223
272
|
this.onNegotiationneeded.execute();
|
|
224
|
-
if (this.onnegotiationneeded)
|
|
225
|
-
this.onnegotiationneeded(
|
|
273
|
+
if (this.onnegotiationneeded) {
|
|
274
|
+
this.onnegotiationneeded(new globalThis.Event("negotiationneeded"));
|
|
275
|
+
}
|
|
276
|
+
this.emit("negotiationneeded");
|
|
226
277
|
});
|
|
227
278
|
}
|
|
228
279
|
});
|
|
@@ -234,13 +285,13 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
234
285
|
this.transceiverManager = new media_1.TransceiverManager(this.cname, this.config, this.router);
|
|
235
286
|
this.transceiverManager.onTransceiverAdded.pipe(this.onTransceiverAdded);
|
|
236
287
|
this.transceiverManager.onRemoteTransceiverAdded.pipe(this.onRemoteTransceiverAdded);
|
|
237
|
-
this.transceiverManager.onTrack.subscribe(({ track,
|
|
238
|
-
const event = {
|
|
288
|
+
this.transceiverManager.onTrack.subscribe(({ track, streams, transceiver }) => {
|
|
289
|
+
const event = new RTCTrackEvent({
|
|
239
290
|
track,
|
|
240
|
-
streams
|
|
291
|
+
streams,
|
|
241
292
|
transceiver,
|
|
242
293
|
receiver: transceiver.receiver,
|
|
243
|
-
};
|
|
294
|
+
});
|
|
244
295
|
this.onTrack.execute(track);
|
|
245
296
|
this.emit("track", event);
|
|
246
297
|
if (this.ontrack) {
|
|
@@ -251,7 +302,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
251
302
|
this.sctpManager = new sctpManager_1.SctpTransportManager();
|
|
252
303
|
this.sctpManager.onDataChannel.subscribe((channel) => {
|
|
253
304
|
this.onDataChannel.execute(channel);
|
|
254
|
-
const event = { channel };
|
|
305
|
+
const event = { type: "datachannel", channel };
|
|
255
306
|
this.ondatachannel?.(event);
|
|
256
307
|
this.emit("datachannel", event);
|
|
257
308
|
});
|
|
@@ -260,12 +311,18 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
260
311
|
sctpManager: this.sctpManager,
|
|
261
312
|
transceiverManager: this.transceiverManager,
|
|
262
313
|
});
|
|
263
|
-
this.secureManager.iceGatheringStateChange.
|
|
314
|
+
this.secureManager.iceGatheringStateChange.subscribe((state) => {
|
|
315
|
+
this.iceGatheringStateChange.execute(state);
|
|
316
|
+
this.onicegatheringstatechange?.(new globalThis.Event("icegatheringstatechange"));
|
|
317
|
+
this.emit("icegatheringstatechange");
|
|
318
|
+
});
|
|
264
319
|
this.secureManager.iceConnectionStateChange.subscribe((state) => {
|
|
265
320
|
if (state === "closed") {
|
|
266
321
|
this.close();
|
|
267
322
|
}
|
|
268
323
|
this.iceConnectionStateChange.execute(state);
|
|
324
|
+
this.oniceconnectionstatechange?.();
|
|
325
|
+
this.emit("iceconnectionstatechange");
|
|
269
326
|
});
|
|
270
327
|
this.secureManager.connectionStateChange.subscribe((state) => {
|
|
271
328
|
this.connectionStateChange.execute(state);
|
|
@@ -275,8 +332,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
275
332
|
this.secureManager.onIceCandidate.subscribe((candidate) => {
|
|
276
333
|
const iceCandidate = candidate ? candidate.toJSON() : undefined;
|
|
277
334
|
this.onIceCandidate.execute(iceCandidate);
|
|
278
|
-
|
|
279
|
-
|
|
335
|
+
const event = {
|
|
336
|
+
type: "icecandidate",
|
|
337
|
+
candidate: iceCandidate,
|
|
338
|
+
};
|
|
339
|
+
this.onicecandidate?.(event);
|
|
340
|
+
this.emit("icecandidate", event);
|
|
280
341
|
});
|
|
281
342
|
}
|
|
282
343
|
get connectionState() {
|
|
@@ -297,6 +358,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
297
358
|
get sctpTransport() {
|
|
298
359
|
return this.sctpManager.sctpTransport;
|
|
299
360
|
}
|
|
361
|
+
get sctp() {
|
|
362
|
+
return this.sctpTransport ?? null;
|
|
363
|
+
}
|
|
300
364
|
get sctpRemotePort() {
|
|
301
365
|
return this.sctpManager.sctpRemotePort;
|
|
302
366
|
}
|
|
@@ -310,10 +374,35 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
310
374
|
return this.iceTransports[0].connection.generation;
|
|
311
375
|
}
|
|
312
376
|
get localDescription() {
|
|
313
|
-
return this.sdpManager.localDescription;
|
|
377
|
+
return this.sdpManager.localDescription ?? null;
|
|
378
|
+
}
|
|
379
|
+
get currentLocalDescription() {
|
|
380
|
+
return this.sdpManager.currentLocalDescription?.toJSON() ?? null;
|
|
381
|
+
}
|
|
382
|
+
get pendingLocalDescription() {
|
|
383
|
+
return this.sdpManager.pendingLocalDescription?.toJSON() ?? null;
|
|
314
384
|
}
|
|
315
385
|
get remoteDescription() {
|
|
316
|
-
return this.sdpManager.remoteDescription;
|
|
386
|
+
return this.sdpManager.remoteDescription ?? null;
|
|
387
|
+
}
|
|
388
|
+
get currentRemoteDescription() {
|
|
389
|
+
return this.sdpManager.currentRemoteDescription?.toJSON() ?? null;
|
|
390
|
+
}
|
|
391
|
+
get pendingRemoteDescription() {
|
|
392
|
+
return this.sdpManager.pendingRemoteDescription?.toJSON() ?? null;
|
|
393
|
+
}
|
|
394
|
+
get canTrickleIceCandidates() {
|
|
395
|
+
const remoteDescription = this.sdpManager._remoteDescription;
|
|
396
|
+
if (!remoteDescription) {
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
const iceOptions = [
|
|
400
|
+
remoteDescription.iceOptions,
|
|
401
|
+
...remoteDescription.media.map((media) => media.iceOptions),
|
|
402
|
+
]
|
|
403
|
+
.filter((value) => !!value)
|
|
404
|
+
.join(" ");
|
|
405
|
+
return iceOptions.split(/\s+/).includes("trickle");
|
|
317
406
|
}
|
|
318
407
|
get remoteIsBundled() {
|
|
319
408
|
return this.sdpManager.remoteIsBundled;
|
|
@@ -336,7 +425,42 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
336
425
|
return this.transceiverManager.getReceivers();
|
|
337
426
|
}
|
|
338
427
|
setConfiguration(config) {
|
|
339
|
-
|
|
428
|
+
const normalizedConfig = normalizePeerConfiguration(config);
|
|
429
|
+
const isReconfiguration = !!this.sdpManager;
|
|
430
|
+
if (normalizedConfig.rtcpMuxPolicy &&
|
|
431
|
+
normalizedConfig.rtcpMuxPolicy !== "require") {
|
|
432
|
+
throw new Error("rtcpMuxPolicy must be require");
|
|
433
|
+
}
|
|
434
|
+
if (normalizedConfig.iceCandidatePoolSize !== undefined &&
|
|
435
|
+
(!Number.isInteger(normalizedConfig.iceCandidatePoolSize) ||
|
|
436
|
+
normalizedConfig.iceCandidatePoolSize < 0)) {
|
|
437
|
+
throw new Error("iceCandidatePoolSize must be a non-negative integer");
|
|
438
|
+
}
|
|
439
|
+
if (isReconfiguration &&
|
|
440
|
+
normalizedConfig.bundlePolicy !== undefined &&
|
|
441
|
+
normalizedConfig.bundlePolicy !== this.config.bundlePolicy) {
|
|
442
|
+
throw new Error("bundlePolicy cannot be changed");
|
|
443
|
+
}
|
|
444
|
+
if (isReconfiguration &&
|
|
445
|
+
normalizedConfig.rtcpMuxPolicy !== undefined &&
|
|
446
|
+
normalizedConfig.rtcpMuxPolicy !== this.config.rtcpMuxPolicy) {
|
|
447
|
+
throw new Error("rtcpMuxPolicy cannot be changed");
|
|
448
|
+
}
|
|
449
|
+
if (isReconfiguration &&
|
|
450
|
+
normalizedConfig.certificates !== undefined &&
|
|
451
|
+
!hasSameCertificates(normalizedConfig.certificates, this.config.certificates)) {
|
|
452
|
+
throw new Error("certificates cannot be changed");
|
|
453
|
+
}
|
|
454
|
+
if (isReconfiguration &&
|
|
455
|
+
normalizedConfig.iceCandidatePoolSize !== undefined &&
|
|
456
|
+
this.localDescription &&
|
|
457
|
+
normalizedConfig.iceCandidatePoolSize !== this.config.iceCandidatePoolSize) {
|
|
458
|
+
throw new Error("iceCandidatePoolSize cannot be changed after setLocalDescription");
|
|
459
|
+
}
|
|
460
|
+
if ((normalizedConfig.iceCandidatePoolSize ?? 0) > 0) {
|
|
461
|
+
throw new Error("iceCandidatePoolSize > 0 is not supported");
|
|
462
|
+
}
|
|
463
|
+
(0, utils_1.deepMerge)(this.config, normalizedConfig);
|
|
340
464
|
if (this.config.icePortRange) {
|
|
341
465
|
const [min, max] = this.config.icePortRange;
|
|
342
466
|
if (min === max)
|
|
@@ -385,7 +509,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
385
509
|
});
|
|
386
510
|
}
|
|
387
511
|
getConfiguration() {
|
|
388
|
-
return this.config;
|
|
512
|
+
return clonePeerConfiguration(this.config);
|
|
389
513
|
}
|
|
390
514
|
async createOffer({ iceRestart } = {}) {
|
|
391
515
|
if (iceRestart || this.needRestart) {
|
|
@@ -403,7 +527,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
403
527
|
}
|
|
404
528
|
}
|
|
405
529
|
const description = this.sdpManager.buildOfferSdp(this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
406
|
-
|
|
530
|
+
const createdOffer = description.toJSON();
|
|
531
|
+
this.lastCreatedOffer = createdOffer;
|
|
532
|
+
return createdOffer;
|
|
407
533
|
}
|
|
408
534
|
createSctpTransport() {
|
|
409
535
|
const sctp = this.sctpManager.createSctpTransport(this.config.maxMessageSize);
|
|
@@ -425,19 +551,29 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
425
551
|
}
|
|
426
552
|
removeTrack(sender) {
|
|
427
553
|
if (this.isClosed) {
|
|
428
|
-
throw
|
|
554
|
+
throw (0, errors_1.createWebRtcDomException)("InvalidStateError", "peer closed");
|
|
429
555
|
}
|
|
430
556
|
this.transceiverManager.removeTrack(sender);
|
|
431
557
|
this.needNegotiation();
|
|
432
558
|
}
|
|
559
|
+
invalidateLastCreatedDescriptions() {
|
|
560
|
+
this.lastCreatedAnswer = undefined;
|
|
561
|
+
this.lastCreatedOffer = undefined;
|
|
562
|
+
}
|
|
563
|
+
async waitForPendingDescriptionTask() {
|
|
564
|
+
this.assertNotClosed();
|
|
565
|
+
await Promise.resolve();
|
|
566
|
+
if (this.isClosed) {
|
|
567
|
+
await new Promise(() => undefined);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
433
570
|
findOrCreateTransport() {
|
|
434
571
|
const existingDtlsTransport = this.dtlsTransports.find((transport) => transport.state !== "closed");
|
|
435
572
|
const existing = existingDtlsTransport?.iceTransport;
|
|
436
573
|
// Gather ICE candidates for only one track. If the remote endpoint is not bundle-aware, negotiate only one media track.
|
|
437
574
|
// https://w3c.github.io/webrtc-pc/#rtcbundlepolicy-enum
|
|
438
575
|
if (this.sdpManager.bundlePolicy === "max-bundle" ||
|
|
439
|
-
(this.sdpManager.bundlePolicy !== "disable" &&
|
|
440
|
-
(this.remoteIsBundled || this.remoteBundleNegotiated))) {
|
|
576
|
+
(this.sdpManager.bundlePolicy !== "disable" && this.remoteIsBundled)) {
|
|
441
577
|
if (existingDtlsTransport) {
|
|
442
578
|
return existingDtlsTransport;
|
|
443
579
|
}
|
|
@@ -493,17 +629,48 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
493
629
|
"have-local-offer",
|
|
494
630
|
"have-remote-pranswer",
|
|
495
631
|
];
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
632
|
+
await this.waitForPendingDescriptionTask();
|
|
633
|
+
if (sessionDescription?.type === "rollback") {
|
|
634
|
+
this.sdpManager.rollbackLocalDescription(this.signalingState);
|
|
635
|
+
this.setSignalingState("stable");
|
|
636
|
+
if (this.shouldNegotiationneeded) {
|
|
637
|
+
this.needNegotiation();
|
|
638
|
+
}
|
|
639
|
+
this.invalidateLastCreatedDescriptions();
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
const needsGeneratedDescription = !sessionDescription?.type ||
|
|
643
|
+
!sessionDescription.sdp ||
|
|
644
|
+
sessionDescription.sdp.length === 0;
|
|
645
|
+
const generatedDescription = needsGeneratedDescription
|
|
646
|
+
? sessionDescription?.type === "offer"
|
|
647
|
+
? (this.lastCreatedOffer ?? (await this.createOffer()))
|
|
648
|
+
: sessionDescription?.type === "answer" ||
|
|
649
|
+
sessionDescription?.type === "pranswer"
|
|
650
|
+
? (this.lastCreatedAnswer ?? (await this.createAnswer()))
|
|
651
|
+
: implicitOfferState.includes(this.signalingState)
|
|
652
|
+
? (this.lastCreatedOffer ?? (await this.createOffer()))
|
|
653
|
+
: (this.lastCreatedAnswer ?? (await this.createAnswer()))
|
|
654
|
+
: undefined;
|
|
655
|
+
sessionDescription = {
|
|
656
|
+
type: sessionDescription?.type ?? generatedDescription.type,
|
|
657
|
+
sdp: sessionDescription?.sdp && sessionDescription.sdp.length > 0
|
|
658
|
+
? sessionDescription.sdp
|
|
659
|
+
: generatedDescription.sdp,
|
|
660
|
+
};
|
|
661
|
+
if (sessionDescription.type === "offer" &&
|
|
662
|
+
this.lastCreatedOffer &&
|
|
663
|
+
sessionDescription.sdp !== this.lastCreatedOffer.sdp) {
|
|
664
|
+
throw (0, errors_1.createWebRtcDomException)("InvalidModificationError", "setLocalDescription must use the latest created offer");
|
|
665
|
+
}
|
|
501
666
|
// # parse and validate description
|
|
667
|
+
const descriptionType = sessionDescription.type;
|
|
668
|
+
const descriptionSdp = sessionDescription.sdp;
|
|
502
669
|
const description = this.sdpManager.parseSdp({
|
|
503
|
-
sdp:
|
|
670
|
+
sdp: descriptionSdp,
|
|
504
671
|
isLocal: true,
|
|
505
672
|
signalingState: this.signalingState,
|
|
506
|
-
type:
|
|
673
|
+
type: descriptionType,
|
|
507
674
|
});
|
|
508
675
|
// # update signaling state
|
|
509
676
|
if (description.type === "offer") {
|
|
@@ -512,6 +679,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
512
679
|
else if (description.type === "answer") {
|
|
513
680
|
this.setSignalingState("stable");
|
|
514
681
|
}
|
|
682
|
+
else if (description.type === "pranswer") {
|
|
683
|
+
this.setSignalingState("have-local-pranswer");
|
|
684
|
+
}
|
|
515
685
|
// # assign MID
|
|
516
686
|
for (const [i, media] of (0, helper_1.enumerate)(description.media)) {
|
|
517
687
|
const mid = media.rtp.muxId;
|
|
@@ -530,7 +700,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
530
700
|
const role = description.media.find((media) => media.dtlsParams)?.dtlsParams
|
|
531
701
|
?.role;
|
|
532
702
|
this.secureManager.setLocalRole({
|
|
533
|
-
type: description.type,
|
|
703
|
+
type: description.type === "offer" ? "offer" : "answer",
|
|
534
704
|
role,
|
|
535
705
|
});
|
|
536
706
|
// # configure direction
|
|
@@ -556,14 +726,56 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
556
726
|
if (this.shouldNegotiationneeded) {
|
|
557
727
|
this.needNegotiation();
|
|
558
728
|
}
|
|
729
|
+
this.invalidateLastCreatedDescriptions();
|
|
559
730
|
return description;
|
|
560
731
|
}
|
|
561
732
|
async gatherCandidates() {
|
|
562
733
|
await this.secureManager.gatherCandidates(!!this.sdpManager.remoteIsBundled);
|
|
563
734
|
}
|
|
564
|
-
async addIceCandidate(candidateMessage) {
|
|
565
|
-
|
|
566
|
-
|
|
735
|
+
async addIceCandidate(candidateMessage = {}) {
|
|
736
|
+
if (this.isClosed) {
|
|
737
|
+
throw (0, errors_1.createWebRtcDomException)("InvalidStateError", "is closed");
|
|
738
|
+
}
|
|
739
|
+
if (!this.remoteDescription || !this.sdpManager._remoteDescription) {
|
|
740
|
+
this.pendingRemoteCandidates.push(candidateMessage);
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
await this.applyRemoteIceCandidate(candidateMessage);
|
|
744
|
+
}
|
|
745
|
+
async applyRemoteIceCandidate(candidateMessage) {
|
|
746
|
+
const sdp = this.sdpManager._remoteDescription;
|
|
747
|
+
if (!sdp) {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
const appliedCandidate = await this.secureManager.addIceCandidate(sdp, candidateMessage);
|
|
751
|
+
const remoteDescription = this.sdpManager._remoteDescription;
|
|
752
|
+
if (!remoteDescription || !appliedCandidate) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
if (appliedCandidate.kind === "end-of-candidates") {
|
|
756
|
+
for (const mediaIndex of appliedCandidate.mediaIndices) {
|
|
757
|
+
const media = remoteDescription.media[mediaIndex];
|
|
758
|
+
if (media) {
|
|
759
|
+
media.iceCandidatesComplete = true;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
for (const mediaIndex of appliedCandidate.mediaIndices) {
|
|
765
|
+
const media = remoteDescription.media[mediaIndex];
|
|
766
|
+
if (!media) {
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
769
|
+
media.iceCandidates.push(appliedCandidate.candidate);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
async flushPendingRemoteCandidates() {
|
|
773
|
+
while (this.pendingRemoteCandidates.length > 0 &&
|
|
774
|
+
this.remoteDescription &&
|
|
775
|
+
this.sdpManager._remoteDescription) {
|
|
776
|
+
const candidate = this.pendingRemoteCandidates.shift();
|
|
777
|
+
await this.applyRemoteIceCandidate(candidate ?? null);
|
|
778
|
+
}
|
|
567
779
|
}
|
|
568
780
|
async connect() {
|
|
569
781
|
log("start connect");
|
|
@@ -608,15 +820,29 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
608
820
|
if (sessionDescription instanceof sdp_1.SessionDescription) {
|
|
609
821
|
sessionDescription = sessionDescription.toSdp();
|
|
610
822
|
}
|
|
823
|
+
await this.waitForPendingDescriptionTask();
|
|
824
|
+
const needsImplicitLocalRollback = sessionDescription.type === "offer" &&
|
|
825
|
+
["have-local-offer", "have-local-pranswer"].includes(this.signalingState);
|
|
826
|
+
if (needsImplicitLocalRollback) {
|
|
827
|
+
this.sdpManager.rollbackLocalDescription(this.signalingState);
|
|
828
|
+
this.shouldNegotiationneeded = true;
|
|
829
|
+
this.setSignalingState("stable");
|
|
830
|
+
await Promise.resolve();
|
|
831
|
+
}
|
|
611
832
|
// # parse and validate description
|
|
612
833
|
const remoteSdp = this.sdpManager.setRemoteDescription(sessionDescription, this.signalingState);
|
|
613
|
-
if (remoteSdp
|
|
614
|
-
this.
|
|
834
|
+
if (!remoteSdp) {
|
|
835
|
+
this.setSignalingState("stable");
|
|
836
|
+
if (this.shouldNegotiationneeded) {
|
|
837
|
+
this.needNegotiation();
|
|
838
|
+
}
|
|
839
|
+
this.invalidateLastCreatedDescriptions();
|
|
840
|
+
return;
|
|
615
841
|
}
|
|
616
842
|
let bundleTransport;
|
|
617
843
|
// # apply description
|
|
618
844
|
const matchTransceiverWithMedia = (transceiver, media) => transceiver.kind === media.kind &&
|
|
619
|
-
[
|
|
845
|
+
[null, media.rtp.muxId].includes(transceiver.mid);
|
|
620
846
|
let transports = remoteSdp.media.map((remoteMedia, i) => {
|
|
621
847
|
let dtlsTransport;
|
|
622
848
|
if (["audio", "video"].includes(remoteMedia.kind)) {
|
|
@@ -628,7 +854,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
628
854
|
transceiver = this.addTransceiver(remoteMedia.kind, {
|
|
629
855
|
direction: "recvonly",
|
|
630
856
|
});
|
|
631
|
-
transceiver.mid = remoteMedia.rtp.muxId;
|
|
857
|
+
transceiver.mid = remoteMedia.rtp.muxId ?? null;
|
|
632
858
|
this.onRemoteTransceiverAdded.execute(transceiver);
|
|
633
859
|
}
|
|
634
860
|
else {
|
|
@@ -677,7 +903,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
677
903
|
iceTransport.setRemoteParams(remoteMedia.iceParams, renomination);
|
|
678
904
|
// One agent full, one lite: The full agent MUST take the controlling role, and the lite agent MUST take the controlled role
|
|
679
905
|
// RFC 8445 S6.1.1
|
|
680
|
-
if (remoteMedia.iceParams
|
|
906
|
+
if (remoteMedia.iceParams.iceLite && !iceTransport.connection.iceLite) {
|
|
681
907
|
iceTransport.connection.iceControlling = true;
|
|
682
908
|
}
|
|
683
909
|
}
|
|
@@ -716,6 +942,10 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
716
942
|
else if (remoteSdp.type === "answer") {
|
|
717
943
|
this.setSignalingState("stable");
|
|
718
944
|
}
|
|
945
|
+
else if (remoteSdp.type === "pranswer") {
|
|
946
|
+
this.setSignalingState("have-remote-pranswer");
|
|
947
|
+
}
|
|
948
|
+
await this.flushPendingRemoteCandidates();
|
|
719
949
|
// connect transports
|
|
720
950
|
if (remoteSdp.type === "answer") {
|
|
721
951
|
log("caller start connect");
|
|
@@ -728,6 +958,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
728
958
|
if (this.shouldNegotiationneeded) {
|
|
729
959
|
this.needNegotiation();
|
|
730
960
|
}
|
|
961
|
+
this.invalidateLastCreatedDescriptions();
|
|
731
962
|
}
|
|
732
963
|
addTransceiver(trackOrKind, options = {}) {
|
|
733
964
|
const dtlsTransport = this.findOrCreateTransport();
|
|
@@ -737,13 +968,11 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
737
968
|
return transceiver;
|
|
738
969
|
}
|
|
739
970
|
// todo fix
|
|
740
|
-
addTrack(track,
|
|
741
|
-
/**todo impl */
|
|
742
|
-
ms) {
|
|
971
|
+
addTrack(track, ...streams) {
|
|
743
972
|
if (this.isClosed) {
|
|
744
|
-
throw
|
|
973
|
+
throw (0, errors_1.createWebRtcDomException)("InvalidStateError", "is closed");
|
|
745
974
|
}
|
|
746
|
-
const transceiver = this.transceiverManager.addTrack(track,
|
|
975
|
+
const transceiver = this.transceiverManager.addTrack(track, streams);
|
|
747
976
|
if (!transceiver.dtlsTransport) {
|
|
748
977
|
const dtlsTransport = this.findOrCreateTransport();
|
|
749
978
|
transceiver.setDtlsTransport(dtlsTransport);
|
|
@@ -759,54 +988,61 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
759
988
|
sctpTransport: this.sctpTransport,
|
|
760
989
|
signalingState: this.signalingState,
|
|
761
990
|
});
|
|
762
|
-
|
|
991
|
+
const createdAnswer = description.toJSON();
|
|
992
|
+
this.lastCreatedAnswer = createdAnswer;
|
|
993
|
+
return createdAnswer;
|
|
763
994
|
}
|
|
764
995
|
assertNotClosed() {
|
|
765
996
|
if (this.isClosed) {
|
|
766
|
-
throw
|
|
997
|
+
throw (0, errors_1.createWebRtcDomException)("InvalidStateError", "RTCPeerConnection is closed");
|
|
767
998
|
}
|
|
768
999
|
}
|
|
769
1000
|
setSignalingState(state) {
|
|
1001
|
+
if (this.signalingState === state) {
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
770
1004
|
log("signalingStateChange", state);
|
|
771
1005
|
this.signalingState = state;
|
|
772
1006
|
this.signalingStateChange.execute(state);
|
|
773
1007
|
if (this.onsignalingstatechange) {
|
|
774
|
-
this.onsignalingstatechange(
|
|
1008
|
+
this.onsignalingstatechange(new globalThis.Event("signalingstatechange"));
|
|
775
1009
|
}
|
|
1010
|
+
this.emit("signalingstatechange");
|
|
776
1011
|
}
|
|
777
|
-
createPeerConnectionStats() {
|
|
778
|
-
const timestamp = (0, stats_1.getStatsTimestamp)();
|
|
1012
|
+
createPeerConnectionStats(timestamp) {
|
|
779
1013
|
return {
|
|
780
1014
|
type: "peer-connection",
|
|
781
|
-
id: (0, stats_1.generateStatsId)("peer-connection"),
|
|
1015
|
+
id: (0, stats_1.generateStatsId)("peer-connection", this.id),
|
|
782
1016
|
timestamp,
|
|
783
1017
|
dataChannelsOpened: this.sctpManager.dataChannelsOpened,
|
|
784
1018
|
dataChannelsClosed: this.sctpManager.dataChannelsClosed,
|
|
785
1019
|
};
|
|
786
1020
|
}
|
|
787
1021
|
async getStats(selector) {
|
|
1022
|
+
const timestamp = (0, stats_1.getStatsTimestamp)();
|
|
788
1023
|
const stats = [];
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
// Get transport stats - always included regardless of selector
|
|
795
|
-
const transportStats = await this.secureManager.getStats();
|
|
1024
|
+
if (!selector) {
|
|
1025
|
+
stats.push(this.createPeerConnectionStats(timestamp));
|
|
1026
|
+
}
|
|
1027
|
+
stats.push(...this.transceiverManager.collectStats(timestamp));
|
|
1028
|
+
const transportStats = await this.secureManager.getStats(timestamp);
|
|
796
1029
|
stats.push(...transportStats);
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
const dataChannelStats = await this.sctpManager.getStats();
|
|
1030
|
+
if (!selector && this.sctpTransport) {
|
|
1031
|
+
const dataChannelStats = await this.sctpManager.getStats(timestamp);
|
|
800
1032
|
if (dataChannelStats) {
|
|
801
1033
|
stats.push(...dataChannelStats);
|
|
802
1034
|
}
|
|
803
1035
|
}
|
|
804
|
-
|
|
1036
|
+
if (!selector) {
|
|
1037
|
+
return (0, stats_1.buildStatsReport)(stats);
|
|
1038
|
+
}
|
|
1039
|
+
return (0, stats_1.buildStatsReport)(stats, this.transceiverManager.getStatsRootIds(selector));
|
|
805
1040
|
}
|
|
806
1041
|
async close() {
|
|
807
1042
|
if (this.isClosed)
|
|
808
1043
|
return;
|
|
809
1044
|
this.isClosed = true;
|
|
1045
|
+
this.pendingRemoteCandidates.length = 0;
|
|
810
1046
|
this.setSignalingState("closed");
|
|
811
1047
|
this.transceiverManager.close();
|
|
812
1048
|
await this.secureManager.close();
|
|
@@ -837,18 +1073,25 @@ function generateDefaultPeerConfig() {
|
|
|
837
1073
|
video: [],
|
|
838
1074
|
},
|
|
839
1075
|
iceTransportPolicy: "all",
|
|
1076
|
+
iceLite: false,
|
|
840
1077
|
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
|
|
841
1078
|
icePortRange: undefined,
|
|
842
1079
|
iceInterfaceAddresses: undefined,
|
|
843
1080
|
iceAdditionalHostAddresses: undefined,
|
|
844
1081
|
iceUseIpv4: true,
|
|
845
1082
|
iceUseIpv6: true,
|
|
1083
|
+
iceUseTcp: false,
|
|
1084
|
+
turnTransport: undefined,
|
|
1085
|
+
turnTlsOptions: undefined,
|
|
846
1086
|
iceFilterStunResponse: undefined,
|
|
847
1087
|
iceFilterCandidatePair: undefined,
|
|
848
1088
|
icePasswordPrefix: undefined,
|
|
849
1089
|
iceUseLinkLocalAddress: undefined,
|
|
850
1090
|
dtls: {},
|
|
851
1091
|
bundlePolicy: "max-compat",
|
|
1092
|
+
rtcpMuxPolicy: "require",
|
|
1093
|
+
iceCandidatePoolSize: 0,
|
|
1094
|
+
certificates: [],
|
|
852
1095
|
debug: {},
|
|
853
1096
|
midSuffix: false,
|
|
854
1097
|
forceTurnTCP: false,
|
|
@@ -856,4 +1099,110 @@ function generateDefaultPeerConfig() {
|
|
|
856
1099
|
};
|
|
857
1100
|
}
|
|
858
1101
|
exports.defaultPeerConfig = generateDefaultPeerConfig();
|
|
1102
|
+
function normalizePeerConfiguration(config) {
|
|
1103
|
+
const input = Object(config ?? {});
|
|
1104
|
+
const normalizedConfig = { ...input };
|
|
1105
|
+
if (input.bundlePolicy === "balanced") {
|
|
1106
|
+
normalizedConfig.bundlePolicy = "max-compat";
|
|
1107
|
+
}
|
|
1108
|
+
if ("certificates" in input) {
|
|
1109
|
+
if (input.certificates === undefined) {
|
|
1110
|
+
normalizedConfig.certificates = undefined;
|
|
1111
|
+
}
|
|
1112
|
+
else if (!Array.isArray(input.certificates) ||
|
|
1113
|
+
input.certificates.some((certificate) => certificate == null)) {
|
|
1114
|
+
throw (0, errors_1.createWebRtcTypeError)("certificates must be an array of RTCCertificate");
|
|
1115
|
+
}
|
|
1116
|
+
else {
|
|
1117
|
+
normalizedConfig.certificates = [...input.certificates];
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
if ("iceCandidatePoolSize" in input) {
|
|
1121
|
+
normalizedConfig.iceCandidatePoolSize = coerceUnsignedShort(input.iceCandidatePoolSize, "iceCandidatePoolSize");
|
|
1122
|
+
}
|
|
1123
|
+
return normalizedConfig;
|
|
1124
|
+
}
|
|
1125
|
+
function coerceUnsignedShort(value, name) {
|
|
1126
|
+
const coerced = Number(value);
|
|
1127
|
+
if (!Number.isFinite(coerced) ||
|
|
1128
|
+
!Number.isInteger(coerced) ||
|
|
1129
|
+
coerced < 0 ||
|
|
1130
|
+
coerced > 65535) {
|
|
1131
|
+
throw (0, errors_1.createWebRtcTypeError)(`${name} must be an unsigned short`);
|
|
1132
|
+
}
|
|
1133
|
+
return coerced;
|
|
1134
|
+
}
|
|
1135
|
+
function hasSameCertificates(left, right) {
|
|
1136
|
+
return (left.length === right.length &&
|
|
1137
|
+
left.every((certificate, index) => certificate === right[index]));
|
|
1138
|
+
}
|
|
1139
|
+
function clonePeerConfiguration(config) {
|
|
1140
|
+
return {
|
|
1141
|
+
...config,
|
|
1142
|
+
codecs: {
|
|
1143
|
+
audio: config.codecs.audio ? [...config.codecs.audio] : undefined,
|
|
1144
|
+
video: config.codecs.video ? [...config.codecs.video] : undefined,
|
|
1145
|
+
},
|
|
1146
|
+
headerExtensions: {
|
|
1147
|
+
audio: config.headerExtensions.audio
|
|
1148
|
+
? [...config.headerExtensions.audio]
|
|
1149
|
+
: undefined,
|
|
1150
|
+
video: config.headerExtensions.video
|
|
1151
|
+
? [...config.headerExtensions.video]
|
|
1152
|
+
: undefined,
|
|
1153
|
+
},
|
|
1154
|
+
iceServers: config.iceServers.map((server) => ({
|
|
1155
|
+
...server,
|
|
1156
|
+
urls: Array.isArray(server.urls) ? [...server.urls] : server.urls,
|
|
1157
|
+
})),
|
|
1158
|
+
icePortRange: config.icePortRange
|
|
1159
|
+
? [...config.icePortRange]
|
|
1160
|
+
: undefined,
|
|
1161
|
+
iceAdditionalHostAddresses: config.iceAdditionalHostAddresses
|
|
1162
|
+
? [...config.iceAdditionalHostAddresses]
|
|
1163
|
+
: undefined,
|
|
1164
|
+
dtls: { ...config.dtls },
|
|
1165
|
+
certificates: [...config.certificates],
|
|
1166
|
+
debug: { ...config.debug },
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
class RTCTrackEvent {
|
|
1170
|
+
constructor(init) {
|
|
1171
|
+
Object.defineProperty(this, "type", {
|
|
1172
|
+
enumerable: true,
|
|
1173
|
+
configurable: true,
|
|
1174
|
+
writable: true,
|
|
1175
|
+
value: "track"
|
|
1176
|
+
});
|
|
1177
|
+
Object.defineProperty(this, "track", {
|
|
1178
|
+
enumerable: true,
|
|
1179
|
+
configurable: true,
|
|
1180
|
+
writable: true,
|
|
1181
|
+
value: void 0
|
|
1182
|
+
});
|
|
1183
|
+
Object.defineProperty(this, "streams", {
|
|
1184
|
+
enumerable: true,
|
|
1185
|
+
configurable: true,
|
|
1186
|
+
writable: true,
|
|
1187
|
+
value: void 0
|
|
1188
|
+
});
|
|
1189
|
+
Object.defineProperty(this, "transceiver", {
|
|
1190
|
+
enumerable: true,
|
|
1191
|
+
configurable: true,
|
|
1192
|
+
writable: true,
|
|
1193
|
+
value: void 0
|
|
1194
|
+
});
|
|
1195
|
+
Object.defineProperty(this, "receiver", {
|
|
1196
|
+
enumerable: true,
|
|
1197
|
+
configurable: true,
|
|
1198
|
+
writable: true,
|
|
1199
|
+
value: void 0
|
|
1200
|
+
});
|
|
1201
|
+
this.track = init.track;
|
|
1202
|
+
this.streams = [...init.streams];
|
|
1203
|
+
this.transceiver = init.transceiver;
|
|
1204
|
+
this.receiver = init.receiver;
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
exports.RTCTrackEvent = RTCTrackEvent;
|
|
859
1208
|
//# sourceMappingURL=peerConnection.js.map
|