werift 0.22.9 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- 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/dtls/src/flight/server/flight6.js +12 -2
- package/lib/dtls/src/flight/server/flight6.js.map +1 -1
- package/lib/dtls/src/server.js +6 -1
- package/lib/dtls/src/server.js.map +1 -1
- package/lib/dtls/src/socket.d.ts +1 -0
- package/lib/dtls/src/socket.js +3 -0
- package/lib/dtls/src/socket.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 +171 -41
- 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/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 → ice-server}/src/stun/attributes.d.ts +12 -5
- package/lib/{ice → ice-server}/src/stun/attributes.js +60 -19
- 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/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 +3075 -883
- package/lib/nonstandard/index.mjs +1964 -447
- 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/index.d.ts +1 -0
- package/lib/rtp/src/index.js +1 -0
- package/lib/rtp/src/index.js.map +1 -1
- package/lib/rtp/src/srtp/cipher/ctr.d.ts +3 -3
- package/lib/rtp/src/srtp/cipher/ctr.js +25 -14
- package/lib/rtp/src/srtp/cipher/ctr.js.map +1 -1
- package/lib/rtp/src/srtp/cipher/gcm.d.ts +3 -3
- package/lib/rtp/src/srtp/cipher/gcm.js +57 -20
- package/lib/rtp/src/srtp/cipher/gcm.js.map +1 -1
- package/lib/rtp/src/srtp/cipher/index.d.ts +1 -1
- package/lib/rtp/src/srtp/cipher/index.js +1 -1
- package/lib/rtp/src/srtp/cipher/index.js.map +1 -1
- package/lib/rtp/src/srtp/context/srtp.d.ts +2 -1
- package/lib/rtp/src/srtp/context/srtp.js +22 -5
- package/lib/rtp/src/srtp/context/srtp.js.map +1 -1
- package/lib/rtp/src/srtp/error.d.ts +3 -0
- package/lib/rtp/src/srtp/error.js +11 -0
- package/lib/rtp/src/srtp/error.js.map +1 -0
- package/lib/rtp/src/srtp/packet.d.ts +5 -0
- package/lib/rtp/src/srtp/packet.js +48 -0
- package/lib/rtp/src/srtp/packet.js.map +1 -0
- package/lib/webrtc/src/dataChannel.d.ts +4 -2
- package/lib/webrtc/src/dataChannel.js +14 -4
- 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 +177 -28
- 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 +185 -49
- package/lib/webrtc/src/peerConnection.js +477 -107
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sctpManager.d.ts +2 -2
- package/lib/webrtc/src/sctpManager.js +30 -9
- package/lib/webrtc/src/sctpManager.js.map +1 -1
- package/lib/webrtc/src/sdp.d.ts +10 -7
- package/lib/webrtc/src/sdp.js +39 -9
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/sdpManager.d.ts +5 -4
- package/lib/webrtc/src/sdpManager.js +53 -31
- package/lib/webrtc/src/sdpManager.js.map +1 -1
- package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
- package/lib/webrtc/src/secureTransportManager.js +101 -23
- package/lib/webrtc/src/secureTransportManager.js.map +1 -1
- package/lib/webrtc/src/transceiverManager.d.ts +5 -4
- package/lib/webrtc/src/transceiverManager.js +64 -64
- package/lib/webrtc/src/transceiverManager.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.d.ts +16 -4
- package/lib/webrtc/src/transport/dtls.js +208 -35
- 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 +10 -3
- package/lib/webrtc/src/transport/sctp.js +44 -13
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +14 -4
- package/lib/webrtc/src/utils.js +138 -16
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +7 -4
- 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");
|
|
@@ -10,11 +11,95 @@ const sctpManager_1 = require("./sctpManager");
|
|
|
10
11
|
const sdp_1 = require("./sdp");
|
|
11
12
|
const sdpManager_1 = require("./sdpManager");
|
|
12
13
|
const secureTransportManager_1 = require("./secureTransportManager");
|
|
14
|
+
const sctp_1 = require("./transport/sctp");
|
|
13
15
|
const utils_1 = require("./utils");
|
|
14
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
|
+
*/
|
|
15
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
|
+
}
|
|
16
95
|
constructor(config = {}) {
|
|
17
96
|
super();
|
|
97
|
+
Object.defineProperty(this, "id", {
|
|
98
|
+
enumerable: true,
|
|
99
|
+
configurable: true,
|
|
100
|
+
writable: true,
|
|
101
|
+
value: (0, crypto_1.randomUUID)().toString()
|
|
102
|
+
});
|
|
18
103
|
Object.defineProperty(this, "cname", {
|
|
19
104
|
enumerable: true,
|
|
20
105
|
configurable: true,
|
|
@@ -87,6 +172,24 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
87
172
|
writable: true,
|
|
88
173
|
value: false
|
|
89
174
|
});
|
|
175
|
+
Object.defineProperty(this, "lastCreatedAnswer", {
|
|
176
|
+
enumerable: true,
|
|
177
|
+
configurable: true,
|
|
178
|
+
writable: true,
|
|
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: []
|
|
192
|
+
});
|
|
90
193
|
Object.defineProperty(this, "iceGatheringStateChange", {
|
|
91
194
|
enumerable: true,
|
|
92
195
|
configurable: true,
|
|
@@ -147,65 +250,18 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
147
250
|
writable: true,
|
|
148
251
|
value: new common_1.Event()
|
|
149
252
|
});
|
|
150
|
-
Object.defineProperty(this, "
|
|
151
|
-
enumerable: true,
|
|
152
|
-
configurable: true,
|
|
153
|
-
writable: true,
|
|
154
|
-
value: void 0
|
|
155
|
-
});
|
|
156
|
-
Object.defineProperty(this, "onicecandidate", {
|
|
157
|
-
enumerable: true,
|
|
158
|
-
configurable: true,
|
|
159
|
-
writable: true,
|
|
160
|
-
value: void 0
|
|
161
|
-
});
|
|
162
|
-
Object.defineProperty(this, "onicecandidateerror", {
|
|
253
|
+
Object.defineProperty(this, "eventHandlers", {
|
|
163
254
|
enumerable: true,
|
|
164
255
|
configurable: true,
|
|
165
256
|
writable: true,
|
|
166
|
-
value:
|
|
167
|
-
});
|
|
168
|
-
Object.defineProperty(this, "onicegatheringstatechange", {
|
|
169
|
-
enumerable: true,
|
|
170
|
-
configurable: true,
|
|
171
|
-
writable: true,
|
|
172
|
-
value: void 0
|
|
173
|
-
});
|
|
174
|
-
Object.defineProperty(this, "onnegotiationneeded", {
|
|
175
|
-
enumerable: true,
|
|
176
|
-
configurable: true,
|
|
177
|
-
writable: true,
|
|
178
|
-
value: void 0
|
|
179
|
-
});
|
|
180
|
-
Object.defineProperty(this, "onsignalingstatechange", {
|
|
181
|
-
enumerable: true,
|
|
182
|
-
configurable: true,
|
|
183
|
-
writable: true,
|
|
184
|
-
value: void 0
|
|
185
|
-
});
|
|
186
|
-
Object.defineProperty(this, "ontrack", {
|
|
187
|
-
enumerable: true,
|
|
188
|
-
configurable: true,
|
|
189
|
-
writable: true,
|
|
190
|
-
value: void 0
|
|
191
|
-
});
|
|
192
|
-
Object.defineProperty(this, "onconnectionstatechange", {
|
|
193
|
-
enumerable: true,
|
|
194
|
-
configurable: true,
|
|
195
|
-
writable: true,
|
|
196
|
-
value: void 0
|
|
197
|
-
});
|
|
198
|
-
Object.defineProperty(this, "oniceconnectionstatechange", {
|
|
199
|
-
enumerable: true,
|
|
200
|
-
configurable: true,
|
|
201
|
-
writable: true,
|
|
202
|
-
value: void 0
|
|
257
|
+
value: {}
|
|
203
258
|
});
|
|
204
259
|
Object.defineProperty(this, "needNegotiation", {
|
|
205
260
|
enumerable: true,
|
|
206
261
|
configurable: true,
|
|
207
262
|
writable: true,
|
|
208
263
|
value: async () => {
|
|
264
|
+
this.invalidateLastCreatedDescriptions();
|
|
209
265
|
this.shouldNegotiationneeded = true;
|
|
210
266
|
if (this.negotiationneeded || this.signalingState !== "stable") {
|
|
211
267
|
return;
|
|
@@ -214,8 +270,10 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
214
270
|
setImmediate(() => {
|
|
215
271
|
this.negotiationneeded = true;
|
|
216
272
|
this.onNegotiationneeded.execute();
|
|
217
|
-
if (this.onnegotiationneeded)
|
|
218
|
-
this.onnegotiationneeded(
|
|
273
|
+
if (this.onnegotiationneeded) {
|
|
274
|
+
this.onnegotiationneeded(new globalThis.Event("negotiationneeded"));
|
|
275
|
+
}
|
|
276
|
+
this.emit("negotiationneeded");
|
|
219
277
|
});
|
|
220
278
|
}
|
|
221
279
|
});
|
|
@@ -227,13 +285,13 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
227
285
|
this.transceiverManager = new media_1.TransceiverManager(this.cname, this.config, this.router);
|
|
228
286
|
this.transceiverManager.onTransceiverAdded.pipe(this.onTransceiverAdded);
|
|
229
287
|
this.transceiverManager.onRemoteTransceiverAdded.pipe(this.onRemoteTransceiverAdded);
|
|
230
|
-
this.transceiverManager.onTrack.subscribe(({ track,
|
|
231
|
-
const event = {
|
|
288
|
+
this.transceiverManager.onTrack.subscribe(({ track, streams, transceiver }) => {
|
|
289
|
+
const event = new RTCTrackEvent({
|
|
232
290
|
track,
|
|
233
|
-
streams
|
|
291
|
+
streams,
|
|
234
292
|
transceiver,
|
|
235
293
|
receiver: transceiver.receiver,
|
|
236
|
-
};
|
|
294
|
+
});
|
|
237
295
|
this.onTrack.execute(track);
|
|
238
296
|
this.emit("track", event);
|
|
239
297
|
if (this.ontrack) {
|
|
@@ -244,7 +302,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
244
302
|
this.sctpManager = new sctpManager_1.SctpTransportManager();
|
|
245
303
|
this.sctpManager.onDataChannel.subscribe((channel) => {
|
|
246
304
|
this.onDataChannel.execute(channel);
|
|
247
|
-
const event = { channel };
|
|
305
|
+
const event = { type: "datachannel", channel };
|
|
248
306
|
this.ondatachannel?.(event);
|
|
249
307
|
this.emit("datachannel", event);
|
|
250
308
|
});
|
|
@@ -253,12 +311,18 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
253
311
|
sctpManager: this.sctpManager,
|
|
254
312
|
transceiverManager: this.transceiverManager,
|
|
255
313
|
});
|
|
256
|
-
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
|
+
});
|
|
257
319
|
this.secureManager.iceConnectionStateChange.subscribe((state) => {
|
|
258
320
|
if (state === "closed") {
|
|
259
321
|
this.close();
|
|
260
322
|
}
|
|
261
323
|
this.iceConnectionStateChange.execute(state);
|
|
324
|
+
this.oniceconnectionstatechange?.();
|
|
325
|
+
this.emit("iceconnectionstatechange");
|
|
262
326
|
});
|
|
263
327
|
this.secureManager.connectionStateChange.subscribe((state) => {
|
|
264
328
|
this.connectionStateChange.execute(state);
|
|
@@ -268,8 +332,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
268
332
|
this.secureManager.onIceCandidate.subscribe((candidate) => {
|
|
269
333
|
const iceCandidate = candidate ? candidate.toJSON() : undefined;
|
|
270
334
|
this.onIceCandidate.execute(iceCandidate);
|
|
271
|
-
|
|
272
|
-
|
|
335
|
+
const event = {
|
|
336
|
+
type: "icecandidate",
|
|
337
|
+
candidate: iceCandidate,
|
|
338
|
+
};
|
|
339
|
+
this.onicecandidate?.(event);
|
|
340
|
+
this.emit("icecandidate", event);
|
|
273
341
|
});
|
|
274
342
|
}
|
|
275
343
|
get connectionState() {
|
|
@@ -290,6 +358,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
290
358
|
get sctpTransport() {
|
|
291
359
|
return this.sctpManager.sctpTransport;
|
|
292
360
|
}
|
|
361
|
+
get sctp() {
|
|
362
|
+
return this.sctpTransport ?? null;
|
|
363
|
+
}
|
|
293
364
|
get sctpRemotePort() {
|
|
294
365
|
return this.sctpManager.sctpRemotePort;
|
|
295
366
|
}
|
|
@@ -303,10 +374,35 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
303
374
|
return this.iceTransports[0].connection.generation;
|
|
304
375
|
}
|
|
305
376
|
get localDescription() {
|
|
306
|
-
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;
|
|
307
384
|
}
|
|
308
385
|
get remoteDescription() {
|
|
309
|
-
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");
|
|
310
406
|
}
|
|
311
407
|
get remoteIsBundled() {
|
|
312
408
|
return this.sdpManager.remoteIsBundled;
|
|
@@ -329,7 +425,42 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
329
425
|
return this.transceiverManager.getReceivers();
|
|
330
426
|
}
|
|
331
427
|
setConfiguration(config) {
|
|
332
|
-
|
|
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);
|
|
333
464
|
if (this.config.icePortRange) {
|
|
334
465
|
const [min, max] = this.config.icePortRange;
|
|
335
466
|
if (min === max)
|
|
@@ -337,6 +468,14 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
337
468
|
if (min >= max)
|
|
338
469
|
throw new Error("The min must be less than max");
|
|
339
470
|
}
|
|
471
|
+
if (!Number.isInteger(this.config.maxMessageSize) ||
|
|
472
|
+
this.config.maxMessageSize < 0) {
|
|
473
|
+
throw new Error("maxMessageSize must be a non-negative integer");
|
|
474
|
+
}
|
|
475
|
+
if (this.sctpManager?.sctpTransport) {
|
|
476
|
+
this.sctpManager.sctpTransport.maxMessageSize =
|
|
477
|
+
this.config.maxMessageSize;
|
|
478
|
+
}
|
|
340
479
|
for (const [i, codecParams] of (0, helper_1.enumerate)([
|
|
341
480
|
...(this.config.codecs.audio || []),
|
|
342
481
|
...(this.config.codecs.video || []),
|
|
@@ -370,7 +509,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
370
509
|
});
|
|
371
510
|
}
|
|
372
511
|
getConfiguration() {
|
|
373
|
-
return this.config;
|
|
512
|
+
return clonePeerConfiguration(this.config);
|
|
374
513
|
}
|
|
375
514
|
async createOffer({ iceRestart } = {}) {
|
|
376
515
|
if (iceRestart || this.needRestart) {
|
|
@@ -388,10 +527,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
388
527
|
}
|
|
389
528
|
}
|
|
390
529
|
const description = this.sdpManager.buildOfferSdp(this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
391
|
-
|
|
530
|
+
const createdOffer = description.toJSON();
|
|
531
|
+
this.lastCreatedOffer = createdOffer;
|
|
532
|
+
return createdOffer;
|
|
392
533
|
}
|
|
393
534
|
createSctpTransport() {
|
|
394
|
-
const sctp = this.sctpManager.createSctpTransport();
|
|
535
|
+
const sctp = this.sctpManager.createSctpTransport(this.config.maxMessageSize);
|
|
395
536
|
const dtlsTransport = this.findOrCreateTransport();
|
|
396
537
|
sctp.setDtlsTransport(dtlsTransport);
|
|
397
538
|
return sctp;
|
|
@@ -410,19 +551,31 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
410
551
|
}
|
|
411
552
|
removeTrack(sender) {
|
|
412
553
|
if (this.isClosed) {
|
|
413
|
-
throw
|
|
554
|
+
throw (0, errors_1.createWebRtcDomException)("InvalidStateError", "peer closed");
|
|
414
555
|
}
|
|
415
556
|
this.transceiverManager.removeTrack(sender);
|
|
416
557
|
this.needNegotiation();
|
|
417
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
|
+
}
|
|
418
570
|
findOrCreateTransport() {
|
|
419
|
-
const
|
|
571
|
+
const existingDtlsTransport = this.dtlsTransports.find((transport) => transport.state !== "closed");
|
|
572
|
+
const existing = existingDtlsTransport?.iceTransport;
|
|
420
573
|
// Gather ICE candidates for only one track. If the remote endpoint is not bundle-aware, negotiate only one media track.
|
|
421
574
|
// https://w3c.github.io/webrtc-pc/#rtcbundlepolicy-enum
|
|
422
575
|
if (this.sdpManager.bundlePolicy === "max-bundle" ||
|
|
423
576
|
(this.sdpManager.bundlePolicy !== "disable" && this.remoteIsBundled)) {
|
|
424
|
-
if (
|
|
425
|
-
return
|
|
577
|
+
if (existingDtlsTransport) {
|
|
578
|
+
return existingDtlsTransport;
|
|
426
579
|
}
|
|
427
580
|
}
|
|
428
581
|
const dtlsTransport = this.secureManager.createTransport();
|
|
@@ -476,17 +629,48 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
476
629
|
"have-local-offer",
|
|
477
630
|
"have-remote-pranswer",
|
|
478
631
|
];
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
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
|
+
}
|
|
484
666
|
// # parse and validate description
|
|
667
|
+
const descriptionType = sessionDescription.type;
|
|
668
|
+
const descriptionSdp = sessionDescription.sdp;
|
|
485
669
|
const description = this.sdpManager.parseSdp({
|
|
486
|
-
sdp:
|
|
670
|
+
sdp: descriptionSdp,
|
|
487
671
|
isLocal: true,
|
|
488
672
|
signalingState: this.signalingState,
|
|
489
|
-
type:
|
|
673
|
+
type: descriptionType,
|
|
490
674
|
});
|
|
491
675
|
// # update signaling state
|
|
492
676
|
if (description.type === "offer") {
|
|
@@ -495,6 +679,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
495
679
|
else if (description.type === "answer") {
|
|
496
680
|
this.setSignalingState("stable");
|
|
497
681
|
}
|
|
682
|
+
else if (description.type === "pranswer") {
|
|
683
|
+
this.setSignalingState("have-local-pranswer");
|
|
684
|
+
}
|
|
498
685
|
// # assign MID
|
|
499
686
|
for (const [i, media] of (0, helper_1.enumerate)(description.media)) {
|
|
500
687
|
const mid = media.rtp.muxId;
|
|
@@ -513,7 +700,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
513
700
|
const role = description.media.find((media) => media.dtlsParams)?.dtlsParams
|
|
514
701
|
?.role;
|
|
515
702
|
this.secureManager.setLocalRole({
|
|
516
|
-
type: description.type,
|
|
703
|
+
type: description.type === "offer" ? "offer" : "answer",
|
|
517
704
|
role,
|
|
518
705
|
});
|
|
519
706
|
// # configure direction
|
|
@@ -539,14 +726,56 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
539
726
|
if (this.shouldNegotiationneeded) {
|
|
540
727
|
this.needNegotiation();
|
|
541
728
|
}
|
|
729
|
+
this.invalidateLastCreatedDescriptions();
|
|
542
730
|
return description;
|
|
543
731
|
}
|
|
544
732
|
async gatherCandidates() {
|
|
545
733
|
await this.secureManager.gatherCandidates(!!this.sdpManager.remoteIsBundled);
|
|
546
734
|
}
|
|
547
|
-
async addIceCandidate(candidateMessage) {
|
|
548
|
-
|
|
549
|
-
|
|
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
|
+
}
|
|
550
779
|
}
|
|
551
780
|
async connect() {
|
|
552
781
|
log("start connect");
|
|
@@ -591,12 +820,29 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
591
820
|
if (sessionDescription instanceof sdp_1.SessionDescription) {
|
|
592
821
|
sessionDescription = sessionDescription.toSdp();
|
|
593
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
|
+
}
|
|
594
832
|
// # parse and validate description
|
|
595
833
|
const remoteSdp = this.sdpManager.setRemoteDescription(sessionDescription, this.signalingState);
|
|
834
|
+
if (!remoteSdp) {
|
|
835
|
+
this.setSignalingState("stable");
|
|
836
|
+
if (this.shouldNegotiationneeded) {
|
|
837
|
+
this.needNegotiation();
|
|
838
|
+
}
|
|
839
|
+
this.invalidateLastCreatedDescriptions();
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
596
842
|
let bundleTransport;
|
|
597
843
|
// # apply description
|
|
598
844
|
const matchTransceiverWithMedia = (transceiver, media) => transceiver.kind === media.kind &&
|
|
599
|
-
[
|
|
845
|
+
[null, media.rtp.muxId].includes(transceiver.mid);
|
|
600
846
|
let transports = remoteSdp.media.map((remoteMedia, i) => {
|
|
601
847
|
let dtlsTransport;
|
|
602
848
|
if (["audio", "video"].includes(remoteMedia.kind)) {
|
|
@@ -608,7 +854,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
608
854
|
transceiver = this.addTransceiver(remoteMedia.kind, {
|
|
609
855
|
direction: "recvonly",
|
|
610
856
|
});
|
|
611
|
-
transceiver.mid = remoteMedia.rtp.muxId;
|
|
857
|
+
transceiver.mid = remoteMedia.rtp.muxId ?? null;
|
|
612
858
|
this.onRemoteTransceiverAdded.execute(transceiver);
|
|
613
859
|
}
|
|
614
860
|
else {
|
|
@@ -657,7 +903,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
657
903
|
iceTransport.setRemoteParams(remoteMedia.iceParams, renomination);
|
|
658
904
|
// One agent full, one lite: The full agent MUST take the controlling role, and the lite agent MUST take the controlled role
|
|
659
905
|
// RFC 8445 S6.1.1
|
|
660
|
-
if (remoteMedia.iceParams
|
|
906
|
+
if (remoteMedia.iceParams.iceLite && !iceTransport.connection.iceLite) {
|
|
661
907
|
iceTransport.connection.iceControlling = true;
|
|
662
908
|
}
|
|
663
909
|
}
|
|
@@ -696,6 +942,10 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
696
942
|
else if (remoteSdp.type === "answer") {
|
|
697
943
|
this.setSignalingState("stable");
|
|
698
944
|
}
|
|
945
|
+
else if (remoteSdp.type === "pranswer") {
|
|
946
|
+
this.setSignalingState("have-remote-pranswer");
|
|
947
|
+
}
|
|
948
|
+
await this.flushPendingRemoteCandidates();
|
|
699
949
|
// connect transports
|
|
700
950
|
if (remoteSdp.type === "answer") {
|
|
701
951
|
log("caller start connect");
|
|
@@ -708,6 +958,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
708
958
|
if (this.shouldNegotiationneeded) {
|
|
709
959
|
this.needNegotiation();
|
|
710
960
|
}
|
|
961
|
+
this.invalidateLastCreatedDescriptions();
|
|
711
962
|
}
|
|
712
963
|
addTransceiver(trackOrKind, options = {}) {
|
|
713
964
|
const dtlsTransport = this.findOrCreateTransport();
|
|
@@ -717,13 +968,11 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
717
968
|
return transceiver;
|
|
718
969
|
}
|
|
719
970
|
// todo fix
|
|
720
|
-
addTrack(track,
|
|
721
|
-
/**todo impl */
|
|
722
|
-
ms) {
|
|
971
|
+
addTrack(track, ...streams) {
|
|
723
972
|
if (this.isClosed) {
|
|
724
|
-
throw
|
|
973
|
+
throw (0, errors_1.createWebRtcDomException)("InvalidStateError", "is closed");
|
|
725
974
|
}
|
|
726
|
-
const transceiver = this.transceiverManager.addTrack(track,
|
|
975
|
+
const transceiver = this.transceiverManager.addTrack(track, streams);
|
|
727
976
|
if (!transceiver.dtlsTransport) {
|
|
728
977
|
const dtlsTransport = this.findOrCreateTransport();
|
|
729
978
|
transceiver.setDtlsTransport(dtlsTransport);
|
|
@@ -739,54 +988,61 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
739
988
|
sctpTransport: this.sctpTransport,
|
|
740
989
|
signalingState: this.signalingState,
|
|
741
990
|
});
|
|
742
|
-
|
|
991
|
+
const createdAnswer = description.toJSON();
|
|
992
|
+
this.lastCreatedAnswer = createdAnswer;
|
|
993
|
+
return createdAnswer;
|
|
743
994
|
}
|
|
744
995
|
assertNotClosed() {
|
|
745
996
|
if (this.isClosed) {
|
|
746
|
-
throw
|
|
997
|
+
throw (0, errors_1.createWebRtcDomException)("InvalidStateError", "RTCPeerConnection is closed");
|
|
747
998
|
}
|
|
748
999
|
}
|
|
749
1000
|
setSignalingState(state) {
|
|
1001
|
+
if (this.signalingState === state) {
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
750
1004
|
log("signalingStateChange", state);
|
|
751
1005
|
this.signalingState = state;
|
|
752
1006
|
this.signalingStateChange.execute(state);
|
|
753
1007
|
if (this.onsignalingstatechange) {
|
|
754
|
-
this.onsignalingstatechange(
|
|
1008
|
+
this.onsignalingstatechange(new globalThis.Event("signalingstatechange"));
|
|
755
1009
|
}
|
|
1010
|
+
this.emit("signalingstatechange");
|
|
756
1011
|
}
|
|
757
|
-
createPeerConnectionStats() {
|
|
758
|
-
const timestamp = (0, stats_1.getStatsTimestamp)();
|
|
1012
|
+
createPeerConnectionStats(timestamp) {
|
|
759
1013
|
return {
|
|
760
1014
|
type: "peer-connection",
|
|
761
|
-
id: (0, stats_1.generateStatsId)("peer-connection"),
|
|
1015
|
+
id: (0, stats_1.generateStatsId)("peer-connection", this.id),
|
|
762
1016
|
timestamp,
|
|
763
1017
|
dataChannelsOpened: this.sctpManager.dataChannelsOpened,
|
|
764
1018
|
dataChannelsClosed: this.sctpManager.dataChannelsClosed,
|
|
765
1019
|
};
|
|
766
1020
|
}
|
|
767
1021
|
async getStats(selector) {
|
|
1022
|
+
const timestamp = (0, stats_1.getStatsTimestamp)();
|
|
768
1023
|
const stats = [];
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
// Get transport stats - always included regardless of selector
|
|
775
|
-
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);
|
|
776
1029
|
stats.push(...transportStats);
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
const dataChannelStats = await this.sctpManager.getStats();
|
|
1030
|
+
if (!selector && this.sctpTransport) {
|
|
1031
|
+
const dataChannelStats = await this.sctpManager.getStats(timestamp);
|
|
780
1032
|
if (dataChannelStats) {
|
|
781
1033
|
stats.push(...dataChannelStats);
|
|
782
1034
|
}
|
|
783
1035
|
}
|
|
784
|
-
|
|
1036
|
+
if (!selector) {
|
|
1037
|
+
return (0, stats_1.buildStatsReport)(stats);
|
|
1038
|
+
}
|
|
1039
|
+
return (0, stats_1.buildStatsReport)(stats, this.transceiverManager.getStatsRootIds(selector));
|
|
785
1040
|
}
|
|
786
1041
|
async close() {
|
|
787
1042
|
if (this.isClosed)
|
|
788
1043
|
return;
|
|
789
1044
|
this.isClosed = true;
|
|
1045
|
+
this.pendingRemoteCandidates.length = 0;
|
|
790
1046
|
this.setSignalingState("closed");
|
|
791
1047
|
this.transceiverManager.close();
|
|
792
1048
|
await this.secureManager.close();
|
|
@@ -817,22 +1073,136 @@ function generateDefaultPeerConfig() {
|
|
|
817
1073
|
video: [],
|
|
818
1074
|
},
|
|
819
1075
|
iceTransportPolicy: "all",
|
|
1076
|
+
iceLite: false,
|
|
820
1077
|
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
|
|
821
1078
|
icePortRange: undefined,
|
|
822
1079
|
iceInterfaceAddresses: undefined,
|
|
823
1080
|
iceAdditionalHostAddresses: undefined,
|
|
824
1081
|
iceUseIpv4: true,
|
|
825
1082
|
iceUseIpv6: true,
|
|
1083
|
+
iceUseTcp: false,
|
|
1084
|
+
turnTransport: undefined,
|
|
1085
|
+
turnTlsOptions: undefined,
|
|
826
1086
|
iceFilterStunResponse: undefined,
|
|
827
1087
|
iceFilterCandidatePair: undefined,
|
|
828
1088
|
icePasswordPrefix: undefined,
|
|
829
1089
|
iceUseLinkLocalAddress: undefined,
|
|
830
1090
|
dtls: {},
|
|
831
1091
|
bundlePolicy: "max-compat",
|
|
1092
|
+
rtcpMuxPolicy: "require",
|
|
1093
|
+
iceCandidatePoolSize: 0,
|
|
1094
|
+
certificates: [],
|
|
832
1095
|
debug: {},
|
|
833
1096
|
midSuffix: false,
|
|
834
1097
|
forceTurnTCP: false,
|
|
1098
|
+
maxMessageSize: sctp_1.DEFAULT_MAX_MESSAGE_SIZE,
|
|
835
1099
|
};
|
|
836
1100
|
}
|
|
837
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;
|
|
838
1208
|
//# sourceMappingURL=peerConnection.js.map
|