werift 0.22.1 → 0.22.2
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/lib/common/src/binary.d.ts +6 -6
- package/lib/common/src/event.d.ts +1 -0
- package/lib/common/src/event.js +5 -0
- package/lib/common/src/event.js.map +1 -1
- package/lib/common/src/log.d.ts +1 -2
- package/lib/common/src/transport.d.ts +2 -1
- package/lib/common/src/transport.js +28 -14
- package/lib/common/src/transport.js.map +1 -1
- package/lib/dtls/src/cipher/prf.d.ts +12 -12
- package/lib/dtls/src/cipher/suites/aead.d.ts +3 -2
- package/lib/dtls/src/cipher/suites/aead.js +31 -38
- package/lib/dtls/src/cipher/suites/aead.js.map +1 -1
- package/lib/dtls/src/context/cipher.d.ts +4 -4
- package/lib/dtls/src/context/cipher.js +21 -10
- package/lib/dtls/src/context/cipher.js.map +1 -1
- package/lib/dtls/src/context/srtp.d.ts +3 -3
- package/lib/dtls/src/context/srtp.js.map +1 -1
- package/lib/dtls/src/flight/client/flight5.js.map +1 -1
- package/lib/dtls/src/flight/server/flight2.js.map +1 -1
- package/lib/dtls/src/handshake/extensions/ellipticCurves.d.ts +1 -1
- package/lib/dtls/src/handshake/extensions/renegotiationIndication.d.ts +2 -2
- package/lib/dtls/src/handshake/extensions/signature.d.ts +2 -2
- package/lib/dtls/src/handshake/extensions/useSrtp.d.ts +1 -1
- package/lib/dtls/src/handshake/message/alert.d.ts +1 -1
- package/lib/dtls/src/handshake/message/certificate.d.ts +1 -1
- package/lib/dtls/src/handshake/message/changeCipherSpec.d.ts +1 -1
- package/lib/dtls/src/handshake/message/client/certificateVerify.d.ts +1 -1
- package/lib/dtls/src/handshake/message/client/hello.d.ts +1 -1
- package/lib/dtls/src/handshake/message/client/keyExchange.d.ts +1 -1
- package/lib/dtls/src/handshake/message/finished.d.ts +1 -1
- package/lib/dtls/src/handshake/message/server/certificateRequest.d.ts +1 -1
- package/lib/dtls/src/handshake/message/server/hello.d.ts +1 -1
- package/lib/dtls/src/handshake/message/server/helloDone.d.ts +1 -1
- package/lib/dtls/src/handshake/message/server/helloVerifyRequest.d.ts +1 -1
- package/lib/dtls/src/handshake/message/server/keyExchange.d.ts +1 -1
- package/lib/dtls/src/handshake/random.d.ts +3 -3
- package/lib/dtls/src/record/message/fragment.d.ts +1 -1
- package/lib/dtls/src/record/message/header.d.ts +2 -19
- package/lib/dtls/src/record/message/header.js +1 -60
- package/lib/dtls/src/record/message/header.js.map +1 -1
- package/lib/dtls/src/record/message/plaintext.d.ts +6 -27
- package/lib/dtls/src/record/message/plaintext.js +34 -16
- package/lib/dtls/src/record/message/plaintext.js.map +1 -1
- package/lib/dtls/src/socket.d.ts +4 -4
- package/lib/dtls/src/socket.js.map +1 -1
- package/lib/dtls/src/util/binary.d.ts +1 -1
- package/lib/ice/src/helper.d.ts +1 -1
- package/lib/ice/src/ice.d.ts +4 -3
- package/lib/ice/src/ice.js +89 -68
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/iceBase.d.ts +20 -1
- package/lib/ice/src/iceBase.js +46 -0
- package/lib/ice/src/iceBase.js.map +1 -1
- package/lib/ice/src/stun/attributes.d.ts +2 -2
- package/lib/ice/src/stun/attributes.js +47 -27
- package/lib/ice/src/stun/attributes.js.map +1 -1
- package/lib/ice/src/stun/message.d.ts +2 -2
- package/lib/ice/src/stun/message.js +21 -23
- package/lib/ice/src/stun/message.js.map +1 -1
- package/lib/ice/src/stun/protocol.d.ts +2 -2
- package/lib/ice/src/turn/protocol.d.ts +2 -2
- package/lib/index.mjs +2252 -1474
- package/lib/nonstandard/index.mjs +308 -351
- package/lib/rtp/src/codec/av1.d.ts +2 -2
- package/lib/rtp/src/codec/opus.d.ts +1 -1
- package/lib/rtp/src/extra/container/mp4/container.js +18 -8
- package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
- package/lib/rtp/src/extra/container/mp4/h264.d.ts +2 -2
- package/lib/rtp/src/extra/container/mp4/sps-parser.d.ts +1 -1
- package/lib/rtp/src/extra/container/ogg/parser.d.ts +1 -1
- package/lib/rtp/src/extra/container/webm/container.d.ts +7 -7
- package/lib/rtp/src/extra/container/webm/container.js +17 -7
- package/lib/rtp/src/extra/container/webm/container.js.map +1 -1
- package/lib/rtp/src/extra/container/webm/ebml/ebml.d.ts +1 -1
- package/lib/rtp/src/extra/container/webm/ebml/id.d.ts +222 -222
- package/lib/rtp/src/extra/processor/depacketizerCallback.d.ts +1 -1
- package/lib/rtp/src/extra/processor/depacketizerTransformer.d.ts +6 -1
- package/lib/rtp/src/extra/processor/dtxCallback.d.ts +1 -1
- package/lib/rtp/src/extra/processor/interface.d.ts +1 -1
- package/lib/rtp/src/extra/processor/jitterBufferCallback.d.ts +1 -1
- package/lib/rtp/src/extra/processor/mp4.js +3 -0
- package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
- package/lib/rtp/src/extra/processor/nackHandlerCallback.d.ts +1 -1
- package/lib/rtp/src/extra/processor/ntpTimeCallback.d.ts +1 -1
- package/lib/rtp/src/extra/processor/rtpTimeCallback.d.ts +1 -1
- package/lib/rtp/src/extra/processor/webm.d.ts +1 -1
- package/lib/rtp/src/helper.d.ts +1 -1
- package/lib/rtp/src/rtcp/header.d.ts +1 -1
- package/lib/rtp/src/rtcp/psfb/fullIntraRequest.d.ts +1 -1
- package/lib/rtp/src/rtcp/psfb/index.d.ts +1 -1
- package/lib/rtp/src/rtcp/psfb/pictureLossIndication.d.ts +1 -1
- package/lib/rtp/src/rtcp/psfb/remb.d.ts +1 -1
- package/lib/rtp/src/rtcp/rr.d.ts +2 -2
- package/lib/rtp/src/rtcp/rtcp.d.ts +1 -1
- package/lib/rtp/src/rtcp/rtpfb/index.d.ts +1 -1
- package/lib/rtp/src/rtcp/rtpfb/nack.d.ts +1 -1
- package/lib/rtp/src/rtcp/rtpfb/twcc.d.ts +4 -4
- package/lib/rtp/src/rtcp/sdes.d.ts +3 -3
- package/lib/rtp/src/rtcp/sr.d.ts +2 -2
- package/lib/rtp/src/rtp/headerExtension.d.ts +6 -6
- package/lib/rtp/src/rtp/red/packet.d.ts +2 -2
- package/lib/rtp/src/rtp/rtp.d.ts +2 -2
- package/lib/rtp/src/srtp/cipher/ctr.d.ts +4 -4
- package/lib/rtp/src/srtp/cipher/gcm.d.ts +4 -4
- package/lib/rtp/src/srtp/const.d.ts +3 -3
- package/lib/rtp/src/srtp/const.js.map +1 -1
- package/lib/rtp/src/srtp/context/context.d.ts +7 -7
- package/lib/rtp/src/srtp/context/context.js +10 -4
- package/lib/rtp/src/srtp/context/context.js.map +1 -1
- package/lib/rtp/src/srtp/context/srtcp.d.ts +3 -3
- package/lib/rtp/src/srtp/context/srtcp.js.map +1 -1
- package/lib/rtp/src/srtp/context/srtp.d.ts +3 -3
- package/lib/rtp/src/srtp/context/srtp.js.map +1 -1
- package/lib/rtp/src/srtp/srtcp.d.ts +2 -2
- package/lib/rtp/src/srtp/srtp.d.ts +2 -2
- package/lib/sctp/src/chunk.d.ts +12 -12
- package/lib/sctp/src/chunk.js +87 -66
- package/lib/sctp/src/chunk.js.map +1 -1
- package/lib/sctp/src/param.d.ts +3 -3
- package/lib/sctp/src/sctp.d.ts +3 -1
- package/lib/sctp/src/sctp.js +36 -1
- package/lib/sctp/src/sctp.js.map +1 -1
- package/lib/webrtc/src/dataChannel.d.ts +15 -4
- package/lib/webrtc/src/dataChannel.js +42 -7
- package/lib/webrtc/src/dataChannel.js.map +1 -1
- package/lib/webrtc/src/index.d.ts +1 -0
- package/lib/webrtc/src/index.js +1 -0
- package/lib/webrtc/src/index.js.map +1 -1
- package/lib/webrtc/src/media/index.d.ts +1 -0
- package/lib/webrtc/src/media/index.js +1 -0
- package/lib/webrtc/src/media/index.js.map +1 -1
- package/lib/webrtc/src/media/parameters.d.ts +2 -2
- package/lib/webrtc/src/media/parameters.js.map +1 -1
- package/lib/webrtc/src/media/router.js +2 -1
- package/lib/webrtc/src/media/router.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.d.ts +3 -3
- package/lib/webrtc/src/media/rtpReceiver.js +51 -2
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpSender.d.ts +6 -0
- package/lib/webrtc/src/media/rtpSender.js +78 -7
- package/lib/webrtc/src/media/rtpSender.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +12 -9
- package/lib/webrtc/src/media/rtpTransceiver.js +45 -8
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/media/stats.d.ts +279 -0
- package/lib/webrtc/src/media/stats.js +35 -1
- package/lib/webrtc/src/media/stats.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +34 -64
- package/lib/webrtc/src/peerConnection.js +319 -986
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sctpManager.d.ts +27 -0
- package/lib/webrtc/src/sctpManager.js +147 -0
- package/lib/webrtc/src/sctpManager.js.map +1 -0
- package/lib/webrtc/src/sdp.d.ts +3 -2
- package/lib/webrtc/src/sdp.js +17 -7
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/sdpManager.d.ts +78 -0
- package/lib/webrtc/src/sdpManager.js +391 -0
- package/lib/webrtc/src/sdpManager.js.map +1 -0
- package/lib/webrtc/src/secureTransportManager.d.ts +56 -0
- package/lib/webrtc/src/secureTransportManager.js +345 -0
- package/lib/webrtc/src/secureTransportManager.js.map +1 -0
- package/lib/webrtc/src/transceiverManager.d.ts +40 -0
- package/lib/webrtc/src/transceiverManager.js +355 -0
- package/lib/webrtc/src/transceiverManager.js.map +1 -0
- package/lib/webrtc/src/transport/dtls.d.ts +18 -6
- package/lib/webrtc/src/transport/dtls.js +119 -11
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/lib/webrtc/src/transport/ice.d.ts +24 -0
- package/lib/webrtc/src/transport/ice.js +86 -0
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.js +22 -7
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +3 -3
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +15 -21
|
@@ -15,64 +15,41 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
39
|
exports.defaultPeerConfig = exports.findCodecByMimeType = exports.RTCPeerConnection = void 0;
|
|
30
|
-
exports.createMediaDescriptionForTransceiver = createMediaDescriptionForTransceiver;
|
|
31
|
-
exports.createMediaDescriptionForSctp = createMediaDescriptionForSctp;
|
|
32
|
-
exports.addTransportDescription = addTransportDescription;
|
|
33
|
-
exports.allocateMid = allocateMid;
|
|
34
40
|
const cloneDeep_js_1 = __importDefault(require("lodash/cloneDeep.js"));
|
|
35
|
-
const isEqual_js_1 = __importDefault(require("lodash/isEqual.js"));
|
|
36
41
|
const uuid = __importStar(require("uuid"));
|
|
37
|
-
const const_1 = require("./const");
|
|
38
|
-
const dataChannel_1 = require("./dataChannel");
|
|
39
42
|
const helper_1 = require("./helper");
|
|
40
43
|
const common_1 = require("./imports/common");
|
|
41
44
|
const media_1 = require("./media");
|
|
45
|
+
const stats_1 = require("./media/stats");
|
|
46
|
+
const sctpManager_1 = require("./sctpManager");
|
|
42
47
|
const sdp_1 = require("./sdp");
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
const sctp_1 = require("./transport/sctp");
|
|
48
|
+
const sdpManager_1 = require("./sdpManager");
|
|
49
|
+
const secureTransportManager_1 = require("./secureTransportManager");
|
|
46
50
|
const utils_1 = require("./utils");
|
|
47
51
|
const log = (0, common_1.debug)("werift:packages/webrtc/src/peerConnection.ts");
|
|
48
52
|
class RTCPeerConnection extends helper_1.EventTarget {
|
|
49
|
-
pushTransceiver(t) {
|
|
50
|
-
this.transceivers.push(t);
|
|
51
|
-
}
|
|
52
|
-
replaceTransceiver(t, index) {
|
|
53
|
-
this.transceivers[index] = t;
|
|
54
|
-
}
|
|
55
|
-
get dtlsTransports() {
|
|
56
|
-
const transports = this.transceivers.map((t) => t.dtlsTransport);
|
|
57
|
-
if (this.sctpTransport) {
|
|
58
|
-
transports.push(this.sctpTransport.dtlsTransport);
|
|
59
|
-
}
|
|
60
|
-
return transports.reduce((acc, cur) => {
|
|
61
|
-
if (!acc.map((d) => d.id).includes(cur.id)) {
|
|
62
|
-
acc.push(cur);
|
|
63
|
-
}
|
|
64
|
-
return acc;
|
|
65
|
-
}, []);
|
|
66
|
-
}
|
|
67
|
-
get iceTransports() {
|
|
68
|
-
return this.dtlsTransports.map((d) => d.iceTransport);
|
|
69
|
-
}
|
|
70
|
-
get extIdUriMap() {
|
|
71
|
-
return this.router.extIdUriMap;
|
|
72
|
-
}
|
|
73
|
-
get iceGeneration() {
|
|
74
|
-
return this.iceTransports[0].connection.generation;
|
|
75
|
-
}
|
|
76
53
|
constructor(config = {}) {
|
|
77
54
|
super();
|
|
78
55
|
Object.defineProperty(this, "cname", {
|
|
@@ -81,55 +58,67 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
81
58
|
writable: true,
|
|
82
59
|
value: uuid.v4()
|
|
83
60
|
});
|
|
84
|
-
Object.defineProperty(this, "
|
|
61
|
+
Object.defineProperty(this, "config", {
|
|
85
62
|
enumerable: true,
|
|
86
63
|
configurable: true,
|
|
87
64
|
writable: true,
|
|
88
|
-
value:
|
|
65
|
+
value: (0, cloneDeep_js_1.default)(exports.defaultPeerConfig)
|
|
89
66
|
});
|
|
90
|
-
Object.defineProperty(this, "
|
|
67
|
+
Object.defineProperty(this, "signalingState", {
|
|
91
68
|
enumerable: true,
|
|
92
69
|
configurable: true,
|
|
93
70
|
writable: true,
|
|
94
|
-
value:
|
|
71
|
+
value: "stable"
|
|
95
72
|
});
|
|
96
|
-
Object.defineProperty(this, "
|
|
73
|
+
Object.defineProperty(this, "negotiationneeded", {
|
|
97
74
|
enumerable: true,
|
|
98
75
|
configurable: true,
|
|
99
76
|
writable: true,
|
|
100
|
-
value:
|
|
77
|
+
value: false
|
|
101
78
|
});
|
|
102
|
-
Object.defineProperty(this, "
|
|
79
|
+
Object.defineProperty(this, "needRestart", {
|
|
103
80
|
enumerable: true,
|
|
104
81
|
configurable: true,
|
|
105
82
|
writable: true,
|
|
106
|
-
value:
|
|
83
|
+
value: false
|
|
107
84
|
});
|
|
108
|
-
Object.defineProperty(this, "
|
|
85
|
+
Object.defineProperty(this, "router", {
|
|
109
86
|
enumerable: true,
|
|
110
87
|
configurable: true,
|
|
111
88
|
writable: true,
|
|
112
|
-
value:
|
|
89
|
+
value: new media_1.RtpRouter()
|
|
113
90
|
});
|
|
114
|
-
Object.defineProperty(this, "
|
|
91
|
+
Object.defineProperty(this, "sdpManager", {
|
|
115
92
|
enumerable: true,
|
|
116
93
|
configurable: true,
|
|
117
94
|
writable: true,
|
|
118
|
-
value:
|
|
95
|
+
value: void 0
|
|
119
96
|
});
|
|
120
|
-
Object.defineProperty(this, "
|
|
97
|
+
Object.defineProperty(this, "transceiverManager", {
|
|
121
98
|
enumerable: true,
|
|
122
99
|
configurable: true,
|
|
123
100
|
writable: true,
|
|
124
|
-
value:
|
|
101
|
+
value: void 0
|
|
125
102
|
});
|
|
126
|
-
Object.defineProperty(this, "
|
|
103
|
+
Object.defineProperty(this, "sctpManager", {
|
|
127
104
|
enumerable: true,
|
|
128
105
|
configurable: true,
|
|
129
106
|
writable: true,
|
|
130
|
-
value:
|
|
107
|
+
value: void 0
|
|
131
108
|
});
|
|
132
|
-
Object.defineProperty(this, "
|
|
109
|
+
Object.defineProperty(this, "secureManager", {
|
|
110
|
+
enumerable: true,
|
|
111
|
+
configurable: true,
|
|
112
|
+
writable: true,
|
|
113
|
+
value: void 0
|
|
114
|
+
});
|
|
115
|
+
Object.defineProperty(this, "isClosed", {
|
|
116
|
+
enumerable: true,
|
|
117
|
+
configurable: true,
|
|
118
|
+
writable: true,
|
|
119
|
+
value: false
|
|
120
|
+
});
|
|
121
|
+
Object.defineProperty(this, "shouldNegotiationneeded", {
|
|
133
122
|
enumerable: true,
|
|
134
123
|
configurable: true,
|
|
135
124
|
writable: true,
|
|
@@ -207,96 +196,48 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
207
196
|
writable: true,
|
|
208
197
|
value: void 0
|
|
209
198
|
});
|
|
210
|
-
Object.defineProperty(this, "
|
|
211
|
-
enumerable: true,
|
|
212
|
-
configurable: true,
|
|
213
|
-
writable: true,
|
|
214
|
-
value: void 0
|
|
215
|
-
});
|
|
216
|
-
Object.defineProperty(this, "onsignalingstatechange", {
|
|
217
|
-
enumerable: true,
|
|
218
|
-
configurable: true,
|
|
219
|
-
writable: true,
|
|
220
|
-
value: void 0
|
|
221
|
-
});
|
|
222
|
-
Object.defineProperty(this, "ontrack", {
|
|
199
|
+
Object.defineProperty(this, "onicecandidateerror", {
|
|
223
200
|
enumerable: true,
|
|
224
201
|
configurable: true,
|
|
225
202
|
writable: true,
|
|
226
203
|
value: void 0
|
|
227
204
|
});
|
|
228
|
-
Object.defineProperty(this, "
|
|
205
|
+
Object.defineProperty(this, "onicegatheringstatechange", {
|
|
229
206
|
enumerable: true,
|
|
230
207
|
configurable: true,
|
|
231
208
|
writable: true,
|
|
232
209
|
value: void 0
|
|
233
210
|
});
|
|
234
|
-
Object.defineProperty(this, "
|
|
235
|
-
enumerable: true,
|
|
236
|
-
configurable: true,
|
|
237
|
-
writable: true,
|
|
238
|
-
value: void 0
|
|
239
|
-
});
|
|
240
|
-
Object.defineProperty(this, "router", {
|
|
241
|
-
enumerable: true,
|
|
242
|
-
configurable: true,
|
|
243
|
-
writable: true,
|
|
244
|
-
value: new media_1.RtpRouter()
|
|
245
|
-
});
|
|
246
|
-
Object.defineProperty(this, "certificate", {
|
|
247
|
-
enumerable: true,
|
|
248
|
-
configurable: true,
|
|
249
|
-
writable: true,
|
|
250
|
-
value: void 0
|
|
251
|
-
});
|
|
252
|
-
Object.defineProperty(this, "sctpRemotePort", {
|
|
211
|
+
Object.defineProperty(this, "onnegotiationneeded", {
|
|
253
212
|
enumerable: true,
|
|
254
213
|
configurable: true,
|
|
255
214
|
writable: true,
|
|
256
215
|
value: void 0
|
|
257
216
|
});
|
|
258
|
-
Object.defineProperty(this, "
|
|
259
|
-
enumerable: true,
|
|
260
|
-
configurable: true,
|
|
261
|
-
writable: true,
|
|
262
|
-
value: new Set()
|
|
263
|
-
});
|
|
264
|
-
Object.defineProperty(this, "currentLocalDescription", {
|
|
217
|
+
Object.defineProperty(this, "onsignalingstatechange", {
|
|
265
218
|
enumerable: true,
|
|
266
219
|
configurable: true,
|
|
267
220
|
writable: true,
|
|
268
221
|
value: void 0
|
|
269
222
|
});
|
|
270
|
-
Object.defineProperty(this, "
|
|
223
|
+
Object.defineProperty(this, "ontrack", {
|
|
271
224
|
enumerable: true,
|
|
272
225
|
configurable: true,
|
|
273
226
|
writable: true,
|
|
274
227
|
value: void 0
|
|
275
228
|
});
|
|
276
|
-
Object.defineProperty(this, "
|
|
229
|
+
Object.defineProperty(this, "onconnectionstatechange", {
|
|
277
230
|
enumerable: true,
|
|
278
231
|
configurable: true,
|
|
279
232
|
writable: true,
|
|
280
233
|
value: void 0
|
|
281
234
|
});
|
|
282
|
-
Object.defineProperty(this, "
|
|
235
|
+
Object.defineProperty(this, "oniceconnectionstatechange", {
|
|
283
236
|
enumerable: true,
|
|
284
237
|
configurable: true,
|
|
285
238
|
writable: true,
|
|
286
239
|
value: void 0
|
|
287
240
|
});
|
|
288
|
-
Object.defineProperty(this, "isClosed", {
|
|
289
|
-
enumerable: true,
|
|
290
|
-
configurable: true,
|
|
291
|
-
writable: true,
|
|
292
|
-
value: false
|
|
293
|
-
});
|
|
294
|
-
Object.defineProperty(this, "shouldNegotiationneeded", {
|
|
295
|
-
enumerable: true,
|
|
296
|
-
configurable: true,
|
|
297
|
-
writable: true,
|
|
298
|
-
value: false
|
|
299
|
-
});
|
|
300
241
|
Object.defineProperty(this, "needNegotiation", {
|
|
301
242
|
enumerable: true,
|
|
302
243
|
configurable: true,
|
|
@@ -316,17 +257,111 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
316
257
|
}
|
|
317
258
|
});
|
|
318
259
|
this.setConfiguration(config);
|
|
319
|
-
this.
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
260
|
+
this.sdpManager = new sdpManager_1.SDPManager({
|
|
261
|
+
cname: this.cname,
|
|
262
|
+
bundlePolicy: this.config.bundlePolicy,
|
|
263
|
+
});
|
|
264
|
+
this.transceiverManager = new media_1.TransceiverManager(this.cname, this.config, this.router);
|
|
265
|
+
this.transceiverManager.onTransceiverAdded.pipe(this.onTransceiverAdded);
|
|
266
|
+
this.transceiverManager.onRemoteTransceiverAdded.pipe(this.onRemoteTransceiverAdded);
|
|
267
|
+
this.transceiverManager.onTrack.subscribe(({ track, stream, transceiver }) => {
|
|
268
|
+
const event = {
|
|
269
|
+
track,
|
|
270
|
+
streams: [stream],
|
|
271
|
+
transceiver,
|
|
272
|
+
receiver: transceiver.receiver,
|
|
273
|
+
};
|
|
274
|
+
this.onTrack.execute(track);
|
|
275
|
+
this.emit("track", event);
|
|
276
|
+
if (this.ontrack) {
|
|
277
|
+
this.ontrack(event);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
this.transceiverManager.onNegotiationNeeded.subscribe(() => this.needNegotiation());
|
|
281
|
+
this.sctpManager = new sctpManager_1.SctpTransportManager();
|
|
282
|
+
this.sctpManager.onDataChannel.subscribe((channel) => {
|
|
283
|
+
this.onDataChannel.execute(channel);
|
|
284
|
+
const event = { channel };
|
|
285
|
+
this.ondatachannel?.(event);
|
|
286
|
+
this.emit("datachannel", event);
|
|
287
|
+
});
|
|
288
|
+
this.secureManager = new secureTransportManager_1.SecureTransportManager({
|
|
289
|
+
config: this.config,
|
|
290
|
+
sctpManager: this.sctpManager,
|
|
291
|
+
transceiverManager: this.transceiverManager,
|
|
292
|
+
});
|
|
293
|
+
this.secureManager.iceGatheringStateChange.pipe(this.iceGatheringStateChange);
|
|
294
|
+
this.secureManager.iceConnectionStateChange.subscribe((state) => {
|
|
295
|
+
if (state === "closed") {
|
|
296
|
+
this.close();
|
|
327
297
|
}
|
|
298
|
+
this.iceConnectionStateChange.execute(state);
|
|
299
|
+
});
|
|
300
|
+
this.secureManager.connectionStateChange.subscribe((state) => {
|
|
301
|
+
this.connectionStateChange.execute(state);
|
|
302
|
+
this.onconnectionstatechange?.();
|
|
303
|
+
this.emit("connectionstatechange");
|
|
304
|
+
});
|
|
305
|
+
this.secureManager.onIceCandidate.subscribe((candidate) => {
|
|
306
|
+
const iceCandidate = candidate ? candidate.toJSON() : undefined;
|
|
307
|
+
this.onIceCandidate.execute(iceCandidate);
|
|
308
|
+
this.onicecandidate?.({ candidate: iceCandidate });
|
|
309
|
+
this.emit("icecandidate", { candidate: iceCandidate });
|
|
328
310
|
});
|
|
329
311
|
}
|
|
312
|
+
get connectionState() {
|
|
313
|
+
return this.secureManager.connectionState;
|
|
314
|
+
}
|
|
315
|
+
get iceConnectionState() {
|
|
316
|
+
return this.secureManager.iceConnectionState;
|
|
317
|
+
}
|
|
318
|
+
get iceGathererState() {
|
|
319
|
+
return this.secureManager.iceGatheringState;
|
|
320
|
+
}
|
|
321
|
+
get iceGatheringState() {
|
|
322
|
+
return this.secureManager.iceGatheringState;
|
|
323
|
+
}
|
|
324
|
+
get dtlsTransports() {
|
|
325
|
+
return this.secureManager.dtlsTransports;
|
|
326
|
+
}
|
|
327
|
+
get sctpTransport() {
|
|
328
|
+
return this.sctpManager.sctpTransport;
|
|
329
|
+
}
|
|
330
|
+
get sctpRemotePort() {
|
|
331
|
+
return this.sctpManager.sctpRemotePort;
|
|
332
|
+
}
|
|
333
|
+
get iceTransports() {
|
|
334
|
+
return this.secureManager.iceTransports;
|
|
335
|
+
}
|
|
336
|
+
get extIdUriMap() {
|
|
337
|
+
return this.router.extIdUriMap;
|
|
338
|
+
}
|
|
339
|
+
get iceGeneration() {
|
|
340
|
+
return this.iceTransports[0].connection.generation;
|
|
341
|
+
}
|
|
342
|
+
get localDescription() {
|
|
343
|
+
return this.sdpManager.localDescription;
|
|
344
|
+
}
|
|
345
|
+
get remoteDescription() {
|
|
346
|
+
return this.sdpManager.remoteDescription;
|
|
347
|
+
}
|
|
348
|
+
/**@private */
|
|
349
|
+
get _localDescription() {
|
|
350
|
+
return this.sdpManager._localDescription;
|
|
351
|
+
}
|
|
352
|
+
/**@private */
|
|
353
|
+
get _remoteDescription() {
|
|
354
|
+
return this.sdpManager._remoteDescription;
|
|
355
|
+
}
|
|
356
|
+
getTransceivers() {
|
|
357
|
+
return this.transceiverManager.getTransceivers();
|
|
358
|
+
}
|
|
359
|
+
getSenders() {
|
|
360
|
+
return this.transceiverManager.getSenders();
|
|
361
|
+
}
|
|
362
|
+
getReceivers() {
|
|
363
|
+
return this.transceiverManager.getReceivers();
|
|
364
|
+
}
|
|
330
365
|
setConfiguration(config) {
|
|
331
366
|
(0, utils_1.deepMerge)(this.config, config);
|
|
332
367
|
if (this.config.icePortRange) {
|
|
@@ -367,38 +402,6 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
367
402
|
].forEach((v, i) => {
|
|
368
403
|
v.id = 1 + i;
|
|
369
404
|
});
|
|
370
|
-
if (this.config.dtls) {
|
|
371
|
-
const { keys } = this.config.dtls;
|
|
372
|
-
if (keys) {
|
|
373
|
-
this.certificate = new dtls_1.RTCCertificate(keys.keyPem, keys.certPem, keys.signatureHash);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
get localDescription() {
|
|
378
|
-
if (!this._localDescription) {
|
|
379
|
-
return undefined;
|
|
380
|
-
}
|
|
381
|
-
return this._localDescription.toJSON();
|
|
382
|
-
}
|
|
383
|
-
get remoteDescription() {
|
|
384
|
-
if (!this._remoteDescription) {
|
|
385
|
-
return undefined;
|
|
386
|
-
}
|
|
387
|
-
return this._remoteDescription.toJSON();
|
|
388
|
-
}
|
|
389
|
-
/**@private */
|
|
390
|
-
get _localDescription() {
|
|
391
|
-
return this.pendingLocalDescription || this.currentLocalDescription;
|
|
392
|
-
}
|
|
393
|
-
/**@private */
|
|
394
|
-
get _remoteDescription() {
|
|
395
|
-
return this.pendingRemoteDescription || this.currentRemoteDescription;
|
|
396
|
-
}
|
|
397
|
-
getTransceiverByMid(mid) {
|
|
398
|
-
return this.transceivers.find((transceiver) => transceiver.mid === mid);
|
|
399
|
-
}
|
|
400
|
-
getTransceiverByMLineIndex(index) {
|
|
401
|
-
return this.transceivers.find((transceiver) => transceiver.mLineIndex === index);
|
|
402
405
|
}
|
|
403
406
|
getConfiguration() {
|
|
404
407
|
return this.config;
|
|
@@ -406,207 +409,63 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
406
409
|
async createOffer({ iceRestart } = {}) {
|
|
407
410
|
if (iceRestart || this.needRestart) {
|
|
408
411
|
this.needRestart = false;
|
|
409
|
-
|
|
410
|
-
t.restart();
|
|
411
|
-
}
|
|
412
|
+
this.secureManager.restartIce();
|
|
412
413
|
}
|
|
413
|
-
await this.ensureCerts();
|
|
414
|
-
const
|
|
415
|
-
return description.toJSON();
|
|
416
|
-
}
|
|
417
|
-
assignTransceiverCodecs(transceiver) {
|
|
418
|
-
const codecs = this.config.codecs[transceiver.kind].filter((codecCandidate) => {
|
|
419
|
-
switch (codecCandidate.direction) {
|
|
420
|
-
case "recvonly": {
|
|
421
|
-
if (const_1.ReceiverDirection.includes(transceiver.direction))
|
|
422
|
-
return true;
|
|
423
|
-
return false;
|
|
424
|
-
}
|
|
425
|
-
case "sendonly": {
|
|
426
|
-
if (const_1.SenderDirections.includes(transceiver.direction))
|
|
427
|
-
return true;
|
|
428
|
-
return false;
|
|
429
|
-
}
|
|
430
|
-
case "sendrecv": {
|
|
431
|
-
if ([media_1.Sendrecv, media_1.Recvonly, media_1.Sendonly].includes(transceiver.direction))
|
|
432
|
-
return true;
|
|
433
|
-
return false;
|
|
434
|
-
}
|
|
435
|
-
case "all": {
|
|
436
|
-
return true;
|
|
437
|
-
}
|
|
438
|
-
default:
|
|
439
|
-
return false;
|
|
440
|
-
}
|
|
441
|
-
});
|
|
442
|
-
transceiver.codecs = codecs;
|
|
443
|
-
}
|
|
444
|
-
buildOfferSdp() {
|
|
445
|
-
this.transceivers.forEach((transceiver) => {
|
|
414
|
+
await this.secureManager.ensureCerts();
|
|
415
|
+
for (const transceiver of this.transceiverManager.getTransceivers()) {
|
|
446
416
|
if (transceiver.codecs.length === 0) {
|
|
447
|
-
this.assignTransceiverCodecs(transceiver);
|
|
417
|
+
this.transceiverManager.assignTransceiverCodecs(transceiver);
|
|
448
418
|
}
|
|
449
419
|
if (transceiver.headerExtensions.length === 0) {
|
|
450
420
|
transceiver.headerExtensions =
|
|
451
421
|
this.config.headerExtensions[transceiver.kind] ?? [];
|
|
452
422
|
}
|
|
453
|
-
});
|
|
454
|
-
const description = new sdp_1.SessionDescription();
|
|
455
|
-
(0, sdp_1.addSDPHeader)("offer", description);
|
|
456
|
-
// # handle existing transceivers / sctp
|
|
457
|
-
const currentMedia = this._localDescription
|
|
458
|
-
? this._localDescription.media
|
|
459
|
-
: [];
|
|
460
|
-
currentMedia.forEach((m, i) => {
|
|
461
|
-
const mid = m.rtp.muxId;
|
|
462
|
-
if (!mid) {
|
|
463
|
-
log("mid missing", m);
|
|
464
|
-
return;
|
|
465
|
-
}
|
|
466
|
-
if (m.kind === "application") {
|
|
467
|
-
if (!this.sctpTransport) {
|
|
468
|
-
throw new Error("sctpTransport not found");
|
|
469
|
-
}
|
|
470
|
-
this.sctpTransport.mLineIndex = i;
|
|
471
|
-
description.media.push(createMediaDescriptionForSctp(this.sctpTransport));
|
|
472
|
-
}
|
|
473
|
-
else {
|
|
474
|
-
const transceiver = this.getTransceiverByMid(mid);
|
|
475
|
-
if (!transceiver) {
|
|
476
|
-
if (m.direction === "inactive") {
|
|
477
|
-
description.media.push(m);
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
throw new Error("transceiver not found");
|
|
481
|
-
}
|
|
482
|
-
transceiver.mLineIndex = i;
|
|
483
|
-
description.media.push(createMediaDescriptionForTransceiver(transceiver, this.cname, transceiver.direction));
|
|
484
|
-
}
|
|
485
|
-
});
|
|
486
|
-
// # handle new transceivers / sctp
|
|
487
|
-
this.transceivers
|
|
488
|
-
.filter((t) => !description.media.find((m) => m.rtp.muxId === t.mid))
|
|
489
|
-
.forEach((transceiver) => {
|
|
490
|
-
if (transceiver.mid == undefined) {
|
|
491
|
-
transceiver.mid = allocateMid(this.seenMid, this.config.midSuffix ? "av" : "");
|
|
492
|
-
}
|
|
493
|
-
const mediaDescription = createMediaDescriptionForTransceiver(transceiver, this.cname, transceiver.direction);
|
|
494
|
-
if (transceiver.mLineIndex === undefined) {
|
|
495
|
-
transceiver.mLineIndex = description.media.length;
|
|
496
|
-
description.media.push(mediaDescription);
|
|
497
|
-
}
|
|
498
|
-
else {
|
|
499
|
-
description.media[transceiver.mLineIndex] = mediaDescription;
|
|
500
|
-
}
|
|
501
|
-
});
|
|
502
|
-
if (this.sctpTransport &&
|
|
503
|
-
!description.media.find((m) => m.kind === "application")) {
|
|
504
|
-
this.sctpTransport.mLineIndex = description.media.length;
|
|
505
|
-
if (this.sctpTransport.mid == undefined) {
|
|
506
|
-
this.sctpTransport.mid = allocateMid(this.seenMid, this.config.midSuffix ? "dc" : "");
|
|
507
|
-
}
|
|
508
|
-
description.media.push(createMediaDescriptionForSctp(this.sctpTransport));
|
|
509
423
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
}
|
|
519
|
-
return description;
|
|
424
|
+
const description = this.sdpManager.buildOfferSdp(this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
425
|
+
return description.toJSON();
|
|
426
|
+
}
|
|
427
|
+
createSctpTransport() {
|
|
428
|
+
const sctp = this.sctpManager.createSctpTransport();
|
|
429
|
+
const dtlsTransport = this.findOrCreateTransport();
|
|
430
|
+
sctp.setDtlsTransport(dtlsTransport);
|
|
431
|
+
return sctp;
|
|
520
432
|
}
|
|
521
433
|
createDataChannel(label, options = {}) {
|
|
522
|
-
const base = {
|
|
523
|
-
protocol: "",
|
|
524
|
-
ordered: true,
|
|
525
|
-
negotiated: false,
|
|
526
|
-
};
|
|
527
|
-
const settings = { ...base, ...options };
|
|
528
|
-
if (settings.maxPacketLifeTime && settings.maxRetransmits) {
|
|
529
|
-
throw new Error("can not select both");
|
|
530
|
-
}
|
|
531
434
|
if (!this.sctpTransport) {
|
|
532
|
-
this.
|
|
435
|
+
this.createSctpTransport();
|
|
533
436
|
this.needNegotiation();
|
|
534
437
|
}
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
negotiated: settings.negotiated,
|
|
541
|
-
ordered: settings.ordered,
|
|
542
|
-
protocol: settings.protocol,
|
|
543
|
-
});
|
|
544
|
-
const channel = new dataChannel_1.RTCDataChannel(this.sctpTransport, parameters);
|
|
438
|
+
const channel = this.sctpManager.createDataChannel(label, options);
|
|
439
|
+
if (!channel.sctp.dtlsTransport) {
|
|
440
|
+
const dtlsTransport = this.findOrCreateTransport();
|
|
441
|
+
channel.sctp.setDtlsTransport(dtlsTransport);
|
|
442
|
+
}
|
|
545
443
|
return channel;
|
|
546
444
|
}
|
|
547
445
|
removeTrack(sender) {
|
|
548
|
-
if (this.isClosed)
|
|
446
|
+
if (this.isClosed) {
|
|
549
447
|
throw new Error("peer closed");
|
|
550
|
-
if (!this.getSenders().find(({ ssrc }) => sender.ssrc === ssrc)) {
|
|
551
|
-
throw new Error("unExist");
|
|
552
|
-
}
|
|
553
|
-
const transceiver = this.transceivers.find(({ sender: { ssrc } }) => sender.ssrc === ssrc);
|
|
554
|
-
if (!transceiver)
|
|
555
|
-
throw new Error("unExist");
|
|
556
|
-
sender.stop();
|
|
557
|
-
if (transceiver.currentDirection === "recvonly") {
|
|
558
|
-
this.needNegotiation();
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
if (transceiver.stopping || transceiver.stopped) {
|
|
562
|
-
transceiver.setDirection("inactive");
|
|
563
|
-
}
|
|
564
|
-
else {
|
|
565
|
-
if (transceiver.direction === "sendrecv") {
|
|
566
|
-
transceiver.setDirection("recvonly");
|
|
567
|
-
}
|
|
568
|
-
else if (transceiver.direction === "sendonly" ||
|
|
569
|
-
transceiver.direction === "recvonly") {
|
|
570
|
-
transceiver.setDirection("inactive");
|
|
571
|
-
}
|
|
572
448
|
}
|
|
449
|
+
this.transceiverManager.removeTrack(sender);
|
|
573
450
|
this.needNegotiation();
|
|
574
451
|
}
|
|
575
|
-
|
|
452
|
+
findOrCreateTransport() {
|
|
576
453
|
const [existing] = this.iceTransports;
|
|
577
454
|
// Gather ICE candidates for only one track. If the remote endpoint is not bundle-aware, negotiate only one media track.
|
|
578
455
|
// https://w3c.github.io/webrtc-pc/#rtcbundlepolicy-enum
|
|
579
|
-
if (this.
|
|
456
|
+
if (this.sdpManager.bundlePolicy === "max-bundle") {
|
|
580
457
|
if (existing) {
|
|
581
458
|
return this.dtlsTransports[0];
|
|
582
459
|
}
|
|
583
460
|
}
|
|
584
|
-
const
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
portRange: this.config.icePortRange,
|
|
588
|
-
interfaceAddresses: this.config.iceInterfaceAddresses,
|
|
589
|
-
additionalHostAddresses: this.config.iceAdditionalHostAddresses,
|
|
590
|
-
filterStunResponse: this.config.iceFilterStunResponse,
|
|
591
|
-
filterCandidatePair: this.config.iceFilterCandidatePair,
|
|
592
|
-
localPasswordPrefix: this.config.icePasswordPrefix,
|
|
593
|
-
useIpv4: this.config.iceUseIpv4,
|
|
594
|
-
useIpv6: this.config.iceUseIpv6,
|
|
595
|
-
turnTransport: this.config.forceTurnTCP === true ? "tcp" : "udp",
|
|
596
|
-
useLinkLocalAddress: this.config.iceUseLinkLocalAddress,
|
|
461
|
+
const dtlsTransport = this.secureManager.createTransport();
|
|
462
|
+
dtlsTransport.onRtp.subscribe((rtp) => {
|
|
463
|
+
this.router.routeRtp(rtp);
|
|
597
464
|
});
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
iceGatherer.connection.localPassword = existing.connection.localPassword;
|
|
601
|
-
}
|
|
602
|
-
iceGatherer.onGatheringStateChange.subscribe(() => {
|
|
603
|
-
this.updateIceGatheringState();
|
|
604
|
-
});
|
|
605
|
-
this.updateIceGatheringState();
|
|
606
|
-
const iceTransport = new ice_1.RTCIceTransport(iceGatherer);
|
|
607
|
-
iceTransport.onStateChange.subscribe(() => {
|
|
608
|
-
this.updateIceConnectionState();
|
|
465
|
+
dtlsTransport.onRtcp.subscribe((rtcp) => {
|
|
466
|
+
this.router.routeRtcp(rtcp);
|
|
609
467
|
});
|
|
468
|
+
const iceTransport = dtlsTransport.iceTransport;
|
|
610
469
|
iceTransport.onNegotiationNeeded.subscribe(() => {
|
|
611
470
|
this.needNegotiation();
|
|
612
471
|
});
|
|
@@ -616,7 +475,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
616
475
|
return;
|
|
617
476
|
}
|
|
618
477
|
if (!candidate) {
|
|
619
|
-
this.setLocal(this._localDescription);
|
|
478
|
+
this.sdpManager.setLocal(this._localDescription, this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
620
479
|
this.onIceCandidate.execute(undefined);
|
|
621
480
|
if (this.onicecandidate) {
|
|
622
481
|
this.onicecandidate({ candidate: undefined });
|
|
@@ -624,58 +483,44 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
624
483
|
this.emit("icecandidate", { candidate: undefined });
|
|
625
484
|
return;
|
|
626
485
|
}
|
|
627
|
-
if (this.
|
|
628
|
-
candidate
|
|
629
|
-
|
|
630
|
-
if (media) {
|
|
631
|
-
candidate.sdpMid = media.rtp.muxId;
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
else {
|
|
635
|
-
const transceiver = this.transceivers.find((t) => t.dtlsTransport.iceTransport.id === iceTransport.id);
|
|
636
|
-
if (transceiver) {
|
|
637
|
-
candidate.sdpMLineIndex = transceiver.mLineIndex;
|
|
638
|
-
candidate.sdpMid = transceiver.mid;
|
|
639
|
-
}
|
|
640
|
-
if (this.sctpTransport?.dtlsTransport.iceTransport.id === iceTransport.id) {
|
|
641
|
-
candidate.sdpMLineIndex = this.sctpTransport.mLineIndex;
|
|
642
|
-
candidate.sdpMid = this.sctpTransport.mid;
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
candidate.foundation = "candidate:" + candidate.foundation;
|
|
646
|
-
this.onIceCandidate.execute(candidate.toJSON());
|
|
647
|
-
if (this.onicecandidate) {
|
|
648
|
-
this.onicecandidate({ candidate: candidate.toJSON() });
|
|
486
|
+
if (!this._localDescription) {
|
|
487
|
+
log("localDescription not found when ice candidate was gathered");
|
|
488
|
+
return;
|
|
649
489
|
}
|
|
650
|
-
this.
|
|
490
|
+
this.secureManager.handleNewIceCandidate({
|
|
491
|
+
candidate,
|
|
492
|
+
bundlePolicy: this.sdpManager.bundlePolicy,
|
|
493
|
+
remoteIsBundled: !!this.sdpManager.remoteIsBundled,
|
|
494
|
+
media: this._localDescription.media[0],
|
|
495
|
+
transceiver: this.transceiverManager
|
|
496
|
+
.getTransceivers()
|
|
497
|
+
.find((t) => t.dtlsTransport.iceTransport.id === iceTransport.id),
|
|
498
|
+
sctpTransport: this.sctpTransport?.dtlsTransport.iceTransport.id === iceTransport.id
|
|
499
|
+
? this.sctpTransport
|
|
500
|
+
: undefined,
|
|
501
|
+
});
|
|
651
502
|
});
|
|
652
|
-
const dtlsTransport = new dtls_1.RTCDtlsTransport(this.config, iceTransport, this.router, this.certificate, srtpProfiles);
|
|
653
503
|
return dtlsTransport;
|
|
654
504
|
}
|
|
655
|
-
createSctpTransport() {
|
|
656
|
-
const dtlsTransport = this.createTransport([
|
|
657
|
-
const_1.SRTP_PROFILE.SRTP_AEAD_AES_128_GCM, // prefer
|
|
658
|
-
const_1.SRTP_PROFILE.SRTP_AES128_CM_HMAC_SHA1_80,
|
|
659
|
-
]);
|
|
660
|
-
const sctp = new sctp_1.RTCSctpTransport();
|
|
661
|
-
sctp.setDtlsTransport(dtlsTransport);
|
|
662
|
-
sctp.mid = undefined;
|
|
663
|
-
sctp.onDataChannel.subscribe((channel) => {
|
|
664
|
-
this.onDataChannel.execute(channel);
|
|
665
|
-
const event = { channel };
|
|
666
|
-
if (this.ondatachannel)
|
|
667
|
-
this.ondatachannel(event);
|
|
668
|
-
this.emit("datachannel", event);
|
|
669
|
-
});
|
|
670
|
-
this.sctpTransport = sctp;
|
|
671
|
-
this.updateIceConnectionState();
|
|
672
|
-
return sctp;
|
|
673
|
-
}
|
|
674
505
|
async setLocalDescription(sessionDescription) {
|
|
506
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription#type
|
|
507
|
+
const implicitOfferState = [
|
|
508
|
+
"stable",
|
|
509
|
+
"have-local-offer",
|
|
510
|
+
"have-remote-pranswer",
|
|
511
|
+
];
|
|
512
|
+
sessionDescription =
|
|
513
|
+
sessionDescription ??
|
|
514
|
+
(implicitOfferState.includes(this.signalingState)
|
|
515
|
+
? await this.createOffer()
|
|
516
|
+
: await this.createAnswer());
|
|
675
517
|
// # parse and validate description
|
|
676
|
-
const description =
|
|
677
|
-
|
|
678
|
-
|
|
518
|
+
const description = this.sdpManager.parseSdp({
|
|
519
|
+
sdp: sessionDescription.sdp,
|
|
520
|
+
isLocal: true,
|
|
521
|
+
signalingState: this.signalingState,
|
|
522
|
+
type: sessionDescription.type,
|
|
523
|
+
});
|
|
679
524
|
// # update signaling state
|
|
680
525
|
if (description.type === "offer") {
|
|
681
526
|
this.setSignalingState("have-local-offer");
|
|
@@ -686,9 +531,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
686
531
|
// # assign MID
|
|
687
532
|
for (const [i, media] of (0, helper_1.enumerate)(description.media)) {
|
|
688
533
|
const mid = media.rtp.muxId;
|
|
689
|
-
this.
|
|
534
|
+
this.sdpManager.registerMid(mid);
|
|
690
535
|
if (["audio", "video"].includes(media.kind)) {
|
|
691
|
-
const transceiver = this.getTransceiverByMLineIndex(i);
|
|
536
|
+
const transceiver = this.transceiverManager.getTransceiverByMLineIndex(i);
|
|
692
537
|
if (transceiver) {
|
|
693
538
|
transceiver.mid = mid;
|
|
694
539
|
}
|
|
@@ -698,38 +543,21 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
698
543
|
}
|
|
699
544
|
}
|
|
700
545
|
// setup ice,dtls role
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
else {
|
|
708
|
-
iceTransport.connection.iceControlling = false;
|
|
709
|
-
}
|
|
710
|
-
// One agent full, one lite: The full agent MUST take the controlling role, and the lite agent MUST take the controlled role
|
|
711
|
-
// RFC 8445 S6.1.1
|
|
712
|
-
if (iceTransport.connection.remoteIsLite) {
|
|
713
|
-
iceTransport.connection.iceControlling = true;
|
|
714
|
-
}
|
|
715
|
-
// # set DTLS role for mediasoup
|
|
716
|
-
if (description.type === "answer") {
|
|
717
|
-
const role = description.media.find((media) => media.dtlsParams)
|
|
718
|
-
?.dtlsParams?.role;
|
|
719
|
-
if (role) {
|
|
720
|
-
dtlsTransport.role = role;
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
}
|
|
546
|
+
const role = description.media.find((media) => media.dtlsParams)?.dtlsParams
|
|
547
|
+
?.role;
|
|
548
|
+
this.secureManager.setLocalRole({
|
|
549
|
+
type: description.type,
|
|
550
|
+
role,
|
|
551
|
+
});
|
|
724
552
|
// # configure direction
|
|
725
553
|
if (["answer", "pranswer"].includes(description.type)) {
|
|
726
|
-
for (const t of this.
|
|
554
|
+
for (const t of this.transceiverManager.getTransceivers()) {
|
|
727
555
|
const direction = (0, utils_1.andDirection)(t.direction, t.offerDirection);
|
|
728
556
|
t.setCurrentDirection(direction);
|
|
729
557
|
}
|
|
730
558
|
}
|
|
731
559
|
// for trickle ice
|
|
732
|
-
this.setLocal(description);
|
|
560
|
+
this.sdpManager.setLocal(description, this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
733
561
|
await this.gatherCandidates().catch((e) => {
|
|
734
562
|
log("gatherCandidates failed", e);
|
|
735
563
|
});
|
|
@@ -737,84 +565,21 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
737
565
|
if (description.type === "answer") {
|
|
738
566
|
this.connect().catch((err) => {
|
|
739
567
|
log("connect failed", err);
|
|
740
|
-
this.setConnectionState("failed");
|
|
568
|
+
this.secureManager.setConnectionState("failed");
|
|
741
569
|
});
|
|
742
570
|
}
|
|
743
|
-
this.setLocal(description);
|
|
571
|
+
this.sdpManager.setLocal(description, this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
744
572
|
if (this.shouldNegotiationneeded) {
|
|
745
573
|
this.needNegotiation();
|
|
746
574
|
}
|
|
747
575
|
return description;
|
|
748
576
|
}
|
|
749
577
|
async gatherCandidates() {
|
|
750
|
-
|
|
751
|
-
const connected = this.iceTransports.find((transport) => transport.state === "connected");
|
|
752
|
-
if (this.remoteIsBundled && connected) {
|
|
753
|
-
// no need to gather ice candidates on an existing bundled connection
|
|
754
|
-
}
|
|
755
|
-
else {
|
|
756
|
-
await Promise.allSettled(this.iceTransports.map((iceTransport) => iceTransport.gather()));
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
setLocal(description) {
|
|
760
|
-
description.media
|
|
761
|
-
.filter((m) => ["audio", "video"].includes(m.kind))
|
|
762
|
-
.forEach((m, i) => {
|
|
763
|
-
addTransportDescription(m, this.transceivers[i].dtlsTransport);
|
|
764
|
-
});
|
|
765
|
-
const sctpMedia = description.media.find((m) => m.kind === "application");
|
|
766
|
-
if (this.sctpTransport && sctpMedia) {
|
|
767
|
-
addTransportDescription(sctpMedia, this.sctpTransport.dtlsTransport);
|
|
768
|
-
}
|
|
769
|
-
if (description.type === "answer") {
|
|
770
|
-
this.currentLocalDescription = description;
|
|
771
|
-
this.pendingLocalDescription = undefined;
|
|
772
|
-
}
|
|
773
|
-
else {
|
|
774
|
-
this.pendingLocalDescription = description;
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
getTransportByMid(mid) {
|
|
778
|
-
let iceTransport;
|
|
779
|
-
const transceiver = this.transceivers.find((t) => t.mid === mid);
|
|
780
|
-
if (transceiver) {
|
|
781
|
-
iceTransport = transceiver.dtlsTransport.iceTransport;
|
|
782
|
-
}
|
|
783
|
-
else if (!iceTransport && this.sctpTransport?.mid === mid) {
|
|
784
|
-
iceTransport = this.sctpTransport?.dtlsTransport.iceTransport;
|
|
785
|
-
}
|
|
786
|
-
return iceTransport;
|
|
787
|
-
}
|
|
788
|
-
getTransportByMLineIndex(index) {
|
|
789
|
-
const sdp = this.buildOfferSdp();
|
|
790
|
-
const media = sdp.media[index];
|
|
791
|
-
if (!media) {
|
|
792
|
-
return;
|
|
793
|
-
}
|
|
794
|
-
const transport = this.getTransportByMid(media.rtp.muxId);
|
|
795
|
-
return transport;
|
|
578
|
+
await this.secureManager.gatherCandidates(!!this.sdpManager.remoteIsBundled);
|
|
796
579
|
}
|
|
797
580
|
async addIceCandidate(candidateMessage) {
|
|
798
|
-
const
|
|
799
|
-
|
|
800
|
-
return;
|
|
801
|
-
}
|
|
802
|
-
let iceTransport;
|
|
803
|
-
if (typeof candidate.sdpMid === "number") {
|
|
804
|
-
iceTransport = this.getTransportByMid(candidate.sdpMid);
|
|
805
|
-
}
|
|
806
|
-
if (!iceTransport && typeof candidate.sdpMLineIndex === "number") {
|
|
807
|
-
iceTransport = this.getTransportByMLineIndex(candidate.sdpMLineIndex);
|
|
808
|
-
}
|
|
809
|
-
if (!iceTransport) {
|
|
810
|
-
iceTransport = this.iceTransports[0];
|
|
811
|
-
}
|
|
812
|
-
if (iceTransport) {
|
|
813
|
-
await iceTransport.addRemoteCandidate(candidate);
|
|
814
|
-
}
|
|
815
|
-
else {
|
|
816
|
-
log("iceTransport not found", candidate);
|
|
817
|
-
}
|
|
581
|
+
const sdp = this.sdpManager.buildOfferSdp(this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
582
|
+
await this.secureManager.addIceCandidate(sdp, candidateMessage);
|
|
818
583
|
}
|
|
819
584
|
async connect() {
|
|
820
585
|
log("start connect");
|
|
@@ -823,12 +588,16 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
823
588
|
if (iceTransport.state === "connected") {
|
|
824
589
|
return;
|
|
825
590
|
}
|
|
826
|
-
|
|
591
|
+
const checkDtlsConnected = () => dtlsTransport.state === "connected";
|
|
592
|
+
if (checkDtlsConnected()) {
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
this.secureManager.setConnectionState("connecting");
|
|
827
596
|
await iceTransport.start().catch((err) => {
|
|
828
597
|
log("iceTransport.start failed", err);
|
|
829
598
|
throw err;
|
|
830
599
|
});
|
|
831
|
-
if (
|
|
600
|
+
if (checkDtlsConnected()) {
|
|
832
601
|
return;
|
|
833
602
|
}
|
|
834
603
|
await dtlsTransport.start().catch((err) => {
|
|
@@ -836,85 +605,27 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
836
605
|
throw err;
|
|
837
606
|
});
|
|
838
607
|
if (this.sctpTransport &&
|
|
839
|
-
this.sctpRemotePort &&
|
|
840
608
|
this.sctpTransport.dtlsTransport.id === dtlsTransport.id) {
|
|
841
|
-
await this.
|
|
842
|
-
await this.sctpTransport.sctp.stateChanged.connected.asPromise();
|
|
843
|
-
log("sctp connected");
|
|
609
|
+
await this.sctpManager.connectSctp();
|
|
844
610
|
}
|
|
845
611
|
}));
|
|
846
612
|
if (res.find((r) => r.status === "rejected")) {
|
|
847
|
-
this.setConnectionState("failed");
|
|
613
|
+
this.secureManager.setConnectionState("failed");
|
|
848
614
|
}
|
|
849
615
|
else {
|
|
850
|
-
this.setConnectionState("connected");
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
getLocalRtpParams(transceiver) {
|
|
854
|
-
if (transceiver.mid == undefined)
|
|
855
|
-
throw new Error("mid not assigned");
|
|
856
|
-
const rtp = {
|
|
857
|
-
codecs: transceiver.codecs,
|
|
858
|
-
muxId: transceiver.mid,
|
|
859
|
-
headerExtensions: transceiver.headerExtensions,
|
|
860
|
-
rtcp: { cname: this.cname, ssrc: transceiver.sender.ssrc, mux: true },
|
|
861
|
-
};
|
|
862
|
-
return rtp;
|
|
863
|
-
}
|
|
864
|
-
getRemoteRtpParams(media, transceiver) {
|
|
865
|
-
const receiveParameters = {
|
|
866
|
-
muxId: media.rtp.muxId,
|
|
867
|
-
rtcp: media.rtp.rtcp,
|
|
868
|
-
codecs: transceiver.codecs,
|
|
869
|
-
headerExtensions: transceiver.headerExtensions,
|
|
870
|
-
encodings: Object.values(transceiver.codecs.reduce((acc, codec) => {
|
|
871
|
-
if (codec.name.toLowerCase() === "rtx") {
|
|
872
|
-
const params = (0, sdp_1.codecParametersFromString)(codec.parameters ?? "");
|
|
873
|
-
const apt = acc[params["apt"]];
|
|
874
|
-
if (apt && media.ssrc.length === 2) {
|
|
875
|
-
apt.rtx = new media_1.RTCRtpRtxParameters({ ssrc: media.ssrc[1].ssrc });
|
|
876
|
-
}
|
|
877
|
-
return acc;
|
|
878
|
-
}
|
|
879
|
-
acc[codec.payloadType] = new media_1.RTCRtpCodingParameters({
|
|
880
|
-
ssrc: media.ssrc[0]?.ssrc,
|
|
881
|
-
payloadType: codec.payloadType,
|
|
882
|
-
});
|
|
883
|
-
return acc;
|
|
884
|
-
}, {})),
|
|
885
|
-
};
|
|
886
|
-
return receiveParameters;
|
|
887
|
-
}
|
|
888
|
-
get remoteIsBundled() {
|
|
889
|
-
const remoteSdp = this._remoteDescription;
|
|
890
|
-
if (!remoteSdp) {
|
|
891
|
-
return undefined;
|
|
616
|
+
this.secureManager.setConnectionState("connected");
|
|
892
617
|
}
|
|
893
|
-
const bundle = remoteSdp.group.find((g) => g.semantic === "BUNDLE" && this.config.bundlePolicy !== "disable");
|
|
894
|
-
return bundle;
|
|
895
618
|
}
|
|
896
619
|
restartIce() {
|
|
897
620
|
this.needRestart = true;
|
|
898
621
|
this.needNegotiation();
|
|
899
622
|
}
|
|
900
623
|
async setRemoteDescription(sessionDescription) {
|
|
901
|
-
if (
|
|
902
|
-
|
|
903
|
-
sessionDescription.type === "rollback" ||
|
|
904
|
-
sessionDescription.type === "pranswer") {
|
|
905
|
-
throw new Error("invalid sessionDescription");
|
|
624
|
+
if (sessionDescription instanceof sdp_1.SessionDescription) {
|
|
625
|
+
sessionDescription = sessionDescription.toSdp();
|
|
906
626
|
}
|
|
907
627
|
// # parse and validate description
|
|
908
|
-
const remoteSdp =
|
|
909
|
-
remoteSdp.type = sessionDescription.type;
|
|
910
|
-
this.validateDescription(remoteSdp, false);
|
|
911
|
-
if (remoteSdp.type === "answer") {
|
|
912
|
-
this.currentRemoteDescription = remoteSdp;
|
|
913
|
-
this.pendingRemoteDescription = undefined;
|
|
914
|
-
}
|
|
915
|
-
else {
|
|
916
|
-
this.pendingRemoteDescription = remoteSdp;
|
|
917
|
-
}
|
|
628
|
+
const remoteSdp = this.sdpManager.setRemoteDescription(sessionDescription, this.signalingState);
|
|
918
629
|
let bundleTransport;
|
|
919
630
|
// # apply description
|
|
920
631
|
const matchTransceiverWithMedia = (transceiver, media) => transceiver.kind === media.kind &&
|
|
@@ -922,10 +633,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
922
633
|
let transports = remoteSdp.media.map((remoteMedia, i) => {
|
|
923
634
|
let dtlsTransport;
|
|
924
635
|
if (["audio", "video"].includes(remoteMedia.kind)) {
|
|
925
|
-
let transceiver = this.
|
|
636
|
+
let transceiver = this.transceiverManager
|
|
637
|
+
.getTransceivers()
|
|
638
|
+
.find((t) => matchTransceiverWithMedia(t, remoteMedia));
|
|
926
639
|
if (!transceiver) {
|
|
927
640
|
// create remote transceiver
|
|
928
|
-
transceiver = this.
|
|
641
|
+
transceiver = this.addTransceiver(remoteMedia.kind, {
|
|
929
642
|
direction: "recvonly",
|
|
930
643
|
});
|
|
931
644
|
transceiver.mid = remoteMedia.rtp.muxId;
|
|
@@ -940,7 +653,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
940
653
|
return;
|
|
941
654
|
}
|
|
942
655
|
}
|
|
943
|
-
if (this.remoteIsBundled) {
|
|
656
|
+
if (this.sdpManager.remoteIsBundled) {
|
|
944
657
|
if (!bundleTransport) {
|
|
945
658
|
bundleTransport = transceiver.dtlsTransport;
|
|
946
659
|
}
|
|
@@ -949,30 +662,31 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
949
662
|
}
|
|
950
663
|
}
|
|
951
664
|
dtlsTransport = transceiver.dtlsTransport;
|
|
952
|
-
this.setRemoteRTP(transceiver, remoteMedia, remoteSdp.type, i);
|
|
665
|
+
this.transceiverManager.setRemoteRTP(transceiver, remoteMedia, remoteSdp.type, i);
|
|
953
666
|
}
|
|
954
667
|
else if (remoteMedia.kind === "application") {
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
668
|
+
let sctpTransport = this.sctpTransport;
|
|
669
|
+
if (!sctpTransport) {
|
|
670
|
+
sctpTransport = this.createSctpTransport();
|
|
671
|
+
sctpTransport.mid = remoteMedia.rtp.muxId;
|
|
958
672
|
}
|
|
959
|
-
if (this.remoteIsBundled) {
|
|
673
|
+
if (this.sdpManager.remoteIsBundled) {
|
|
960
674
|
if (!bundleTransport) {
|
|
961
|
-
bundleTransport =
|
|
675
|
+
bundleTransport = sctpTransport.dtlsTransport;
|
|
962
676
|
}
|
|
963
677
|
else {
|
|
964
|
-
|
|
678
|
+
sctpTransport.setDtlsTransport(bundleTransport);
|
|
965
679
|
}
|
|
966
680
|
}
|
|
967
|
-
dtlsTransport =
|
|
968
|
-
this.setRemoteSCTP(remoteMedia,
|
|
681
|
+
dtlsTransport = sctpTransport.dtlsTransport;
|
|
682
|
+
this.sctpManager.setRemoteSCTP(remoteMedia, i);
|
|
969
683
|
}
|
|
970
684
|
else {
|
|
971
685
|
throw new Error("invalid media kind");
|
|
972
686
|
}
|
|
973
687
|
const iceTransport = dtlsTransport.iceTransport;
|
|
974
688
|
if (remoteMedia.iceParams) {
|
|
975
|
-
const renomination = !!
|
|
689
|
+
const renomination = !!this.sdpManager.inactiveRemoteMedia;
|
|
976
690
|
iceTransport.setRemoteParams(remoteMedia.iceParams, renomination);
|
|
977
691
|
// One agent full, one lite: The full agent MUST take the controlling role, and the lite agent MUST take the controlled role
|
|
978
692
|
// RFC 8445 S6.1.1
|
|
@@ -997,7 +711,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
997
711
|
});
|
|
998
712
|
// filter out inactive transports
|
|
999
713
|
transports = transports.filter((iceTransport) => !!iceTransport);
|
|
1000
|
-
const removedTransceivers = this.
|
|
714
|
+
const removedTransceivers = this.transceiverManager
|
|
715
|
+
.getTransceivers()
|
|
716
|
+
.filter((t) => remoteSdp.media.find((m) => matchTransceiverWithMedia(t, m)) ==
|
|
1001
717
|
undefined);
|
|
1002
718
|
if (sessionDescription.type === "answer") {
|
|
1003
719
|
for (const transceiver of removedTransceivers) {
|
|
@@ -1018,7 +734,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1018
734
|
log("caller start connect");
|
|
1019
735
|
this.connect().catch((err) => {
|
|
1020
736
|
log("connect failed", err);
|
|
1021
|
-
this.setConnectionState("failed");
|
|
737
|
+
this.secureManager.setConnectionState("failed");
|
|
1022
738
|
});
|
|
1023
739
|
}
|
|
1024
740
|
this.negotiationneeded = false;
|
|
@@ -1026,177 +742,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1026
742
|
this.needNegotiation();
|
|
1027
743
|
}
|
|
1028
744
|
}
|
|
1029
|
-
setRemoteRTP(transceiver, remoteMedia, type, mLineIndex) {
|
|
1030
|
-
if (!transceiver.mid) {
|
|
1031
|
-
transceiver.mid = remoteMedia.rtp.muxId;
|
|
1032
|
-
}
|
|
1033
|
-
transceiver.mLineIndex = mLineIndex;
|
|
1034
|
-
// # negotiate codecs
|
|
1035
|
-
transceiver.codecs = remoteMedia.rtp.codecs.filter((remoteCodec) => {
|
|
1036
|
-
const localCodecs = this.config.codecs[remoteMedia.kind] || [];
|
|
1037
|
-
const existCodec = (0, exports.findCodecByMimeType)(localCodecs, remoteCodec);
|
|
1038
|
-
if (!existCodec) {
|
|
1039
|
-
return false;
|
|
1040
|
-
}
|
|
1041
|
-
if (existCodec?.name.toLowerCase() === "rtx") {
|
|
1042
|
-
const params = (0, sdp_1.codecParametersFromString)(existCodec.parameters ?? "");
|
|
1043
|
-
const pt = params["apt"];
|
|
1044
|
-
const origin = remoteMedia.rtp.codecs.find((c) => c.payloadType === pt);
|
|
1045
|
-
if (!origin) {
|
|
1046
|
-
return false;
|
|
1047
|
-
}
|
|
1048
|
-
return !!(0, exports.findCodecByMimeType)(localCodecs, origin);
|
|
1049
|
-
}
|
|
1050
|
-
return true;
|
|
1051
|
-
});
|
|
1052
|
-
log("negotiated codecs", transceiver.codecs);
|
|
1053
|
-
if (transceiver.codecs.length === 0) {
|
|
1054
|
-
throw new Error("negotiate codecs failed.");
|
|
1055
|
-
}
|
|
1056
|
-
transceiver.headerExtensions = remoteMedia.rtp.headerExtensions.filter((extension) => (this.config.headerExtensions[remoteMedia.kind] || []).find((v) => v.uri === extension.uri));
|
|
1057
|
-
// # configure direction
|
|
1058
|
-
const mediaDirection = remoteMedia.direction ?? "inactive";
|
|
1059
|
-
const direction = (0, utils_1.reverseDirection)(mediaDirection);
|
|
1060
|
-
if (["answer", "pranswer"].includes(type)) {
|
|
1061
|
-
transceiver.setCurrentDirection(direction);
|
|
1062
|
-
}
|
|
1063
|
-
else {
|
|
1064
|
-
transceiver.offerDirection = direction;
|
|
1065
|
-
}
|
|
1066
|
-
const localParams = this.getLocalRtpParams(transceiver);
|
|
1067
|
-
transceiver.sender.prepareSend(localParams);
|
|
1068
|
-
if (["recvonly", "sendrecv"].includes(transceiver.direction)) {
|
|
1069
|
-
const remotePrams = this.getRemoteRtpParams(remoteMedia, transceiver);
|
|
1070
|
-
// register simulcast receiver
|
|
1071
|
-
remoteMedia.simulcastParameters.forEach((param) => {
|
|
1072
|
-
this.router.registerRtpReceiverByRid(transceiver, param, remotePrams);
|
|
1073
|
-
});
|
|
1074
|
-
transceiver.receiver.prepareReceive(remotePrams);
|
|
1075
|
-
// register ssrc receiver
|
|
1076
|
-
this.router.registerRtpReceiverBySsrc(transceiver, remotePrams);
|
|
1077
|
-
}
|
|
1078
|
-
if (["sendonly", "sendrecv"].includes(mediaDirection)) {
|
|
1079
|
-
if (remoteMedia.msid) {
|
|
1080
|
-
const [streamId, trackId] = remoteMedia.msid.split(" ");
|
|
1081
|
-
transceiver.receiver.remoteStreamId = streamId;
|
|
1082
|
-
transceiver.receiver.remoteTrackId = trackId;
|
|
1083
|
-
}
|
|
1084
|
-
this.fireOnTrack(transceiver.receiver.track, transceiver, new media_1.MediaStream({
|
|
1085
|
-
id: transceiver.receiver.remoteStreamId,
|
|
1086
|
-
tracks: [transceiver.receiver.track],
|
|
1087
|
-
}));
|
|
1088
|
-
}
|
|
1089
|
-
if (remoteMedia.ssrc[0]?.ssrc) {
|
|
1090
|
-
transceiver.receiver.setupTWCC(remoteMedia.ssrc[0].ssrc);
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
setRemoteSCTP(remoteMedia, sctpTransport, mLineIndex) {
|
|
1094
|
-
// # configure sctp
|
|
1095
|
-
this.sctpRemotePort = remoteMedia.sctpPort;
|
|
1096
|
-
if (!this.sctpRemotePort) {
|
|
1097
|
-
throw new Error("sctpRemotePort not exist");
|
|
1098
|
-
}
|
|
1099
|
-
sctpTransport.setRemotePort(this.sctpRemotePort);
|
|
1100
|
-
sctpTransport.mLineIndex = mLineIndex;
|
|
1101
|
-
if (!sctpTransport.mid) {
|
|
1102
|
-
sctpTransport.mid = remoteMedia.rtp.muxId;
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
validateDescription(description, isLocal) {
|
|
1106
|
-
if (isLocal) {
|
|
1107
|
-
if (description.type === "offer") {
|
|
1108
|
-
if (!["stable", "have-local-offer"].includes(this.signalingState))
|
|
1109
|
-
throw new Error("Cannot handle offer in signaling state");
|
|
1110
|
-
}
|
|
1111
|
-
else if (description.type === "answer") {
|
|
1112
|
-
if (!["have-remote-offer", "have-local-pranswer"].includes(this.signalingState)) {
|
|
1113
|
-
throw new Error("Cannot handle answer in signaling state");
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
else {
|
|
1118
|
-
if (description.type === "offer") {
|
|
1119
|
-
if (!["stable", "have-remote-offer"].includes(this.signalingState)) {
|
|
1120
|
-
throw new Error("Cannot handle offer in signaling state");
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
else if (description.type === "answer") {
|
|
1124
|
-
if (!["have-local-offer", "have-remote-pranswer"].includes(this.signalingState)) {
|
|
1125
|
-
throw new Error("Cannot handle answer in signaling state");
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
description.media.forEach((media) => {
|
|
1130
|
-
if (media.direction === "inactive")
|
|
1131
|
-
return;
|
|
1132
|
-
if (!media.iceParams ||
|
|
1133
|
-
!media.iceParams.usernameFragment ||
|
|
1134
|
-
!media.iceParams.password)
|
|
1135
|
-
throw new Error("ICE username fragment or password is missing");
|
|
1136
|
-
});
|
|
1137
|
-
if (["answer", "pranswer"].includes(description.type || "")) {
|
|
1138
|
-
const offer = isLocal ? this._remoteDescription : this._localDescription;
|
|
1139
|
-
if (!offer)
|
|
1140
|
-
throw new Error();
|
|
1141
|
-
const answerMedia = description.media.map((v, i) => [v.kind, i]);
|
|
1142
|
-
const offerMedia = offer.media.map((v, i) => [v.kind, i]);
|
|
1143
|
-
if (!(0, isEqual_js_1.default)(offerMedia, answerMedia)) {
|
|
1144
|
-
throw new Error("Media sections in answer do not match offer");
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
fireOnTrack(track, transceiver, stream) {
|
|
1149
|
-
const event = {
|
|
1150
|
-
track,
|
|
1151
|
-
streams: [stream],
|
|
1152
|
-
transceiver,
|
|
1153
|
-
receiver: transceiver.receiver,
|
|
1154
|
-
};
|
|
1155
|
-
this.onTrack.execute(track);
|
|
1156
|
-
this.emit("track", event);
|
|
1157
|
-
if (this.ontrack) {
|
|
1158
|
-
this.ontrack(event);
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
745
|
addTransceiver(trackOrKind, options = {}) {
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
const kind = typeof trackOrKind === "string" ? trackOrKind : trackOrKind.kind;
|
|
1166
|
-
const direction = options.direction || "sendrecv";
|
|
1167
|
-
const dtlsTransport = this.createTransport([
|
|
1168
|
-
const_1.SRTP_PROFILE.SRTP_AEAD_AES_128_GCM, // prefer
|
|
1169
|
-
const_1.SRTP_PROFILE.SRTP_AES128_CM_HMAC_SHA1_80,
|
|
1170
|
-
]);
|
|
1171
|
-
const sender = new media_1.RTCRtpSender(trackOrKind);
|
|
1172
|
-
const receiver = new media_1.RTCRtpReceiver(this.config, kind, sender.ssrc);
|
|
1173
|
-
const newTransceiver = new media_1.RTCRtpTransceiver(kind, dtlsTransport, receiver, sender, direction);
|
|
1174
|
-
newTransceiver.options = options;
|
|
1175
|
-
this.router.registerRtpSender(newTransceiver.sender);
|
|
1176
|
-
// reuse inactive
|
|
1177
|
-
const inactiveTransceiverIndex = this.transceivers.findIndex((t) => t.currentDirection === "inactive");
|
|
1178
|
-
const inactiveTransceiver = this.transceivers.find((t) => t.currentDirection === "inactive");
|
|
1179
|
-
if (inactiveTransceiverIndex > -1 && inactiveTransceiver) {
|
|
1180
|
-
this.replaceTransceiver(newTransceiver, inactiveTransceiverIndex);
|
|
1181
|
-
newTransceiver.mLineIndex = inactiveTransceiver.mLineIndex;
|
|
1182
|
-
inactiveTransceiver.setCurrentDirection(undefined);
|
|
1183
|
-
}
|
|
1184
|
-
else {
|
|
1185
|
-
this.pushTransceiver(newTransceiver);
|
|
1186
|
-
}
|
|
1187
|
-
this.onTransceiverAdded.execute(newTransceiver);
|
|
1188
|
-
this.updateIceConnectionState();
|
|
746
|
+
const dtlsTransport = this.findOrCreateTransport();
|
|
747
|
+
const transceiver = this.transceiverManager.addTransceiver(trackOrKind, dtlsTransport, options);
|
|
748
|
+
this.secureManager.updateIceConnectionState();
|
|
1189
749
|
this.needNegotiation();
|
|
1190
|
-
return
|
|
1191
|
-
}
|
|
1192
|
-
getTransceivers() {
|
|
1193
|
-
return this.transceivers;
|
|
1194
|
-
}
|
|
1195
|
-
getSenders() {
|
|
1196
|
-
return this.getTransceivers().map((t) => t.sender);
|
|
1197
|
-
}
|
|
1198
|
-
getReceivers() {
|
|
1199
|
-
return this.getTransceivers().map((t) => t.receiver);
|
|
750
|
+
return transceiver;
|
|
1200
751
|
}
|
|
1201
752
|
// todo fix
|
|
1202
753
|
addTrack(track,
|
|
@@ -1205,207 +756,29 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1205
756
|
if (this.isClosed) {
|
|
1206
757
|
throw new Error("is closed");
|
|
1207
758
|
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
t.kind === track.kind &&
|
|
1213
|
-
const_1.SenderDirections.includes(t.direction) === true);
|
|
1214
|
-
if (emptyTrackSender) {
|
|
1215
|
-
const sender = emptyTrackSender.sender;
|
|
1216
|
-
sender.registerTrack(track);
|
|
1217
|
-
this.needNegotiation();
|
|
1218
|
-
return sender;
|
|
1219
|
-
}
|
|
1220
|
-
const notSendTransceiver = this.transceivers.find((t) => t.sender.track == undefined &&
|
|
1221
|
-
t.kind === track.kind &&
|
|
1222
|
-
const_1.SenderDirections.includes(t.direction) === false &&
|
|
1223
|
-
!t.usedForSender);
|
|
1224
|
-
if (notSendTransceiver) {
|
|
1225
|
-
const sender = notSendTransceiver.sender;
|
|
1226
|
-
sender.registerTrack(track);
|
|
1227
|
-
switch (notSendTransceiver.direction) {
|
|
1228
|
-
case "recvonly":
|
|
1229
|
-
notSendTransceiver.setDirection("sendrecv");
|
|
1230
|
-
break;
|
|
1231
|
-
case "inactive":
|
|
1232
|
-
notSendTransceiver.setDirection("sendonly");
|
|
1233
|
-
break;
|
|
1234
|
-
}
|
|
1235
|
-
this.needNegotiation();
|
|
1236
|
-
return sender;
|
|
1237
|
-
}
|
|
1238
|
-
else {
|
|
1239
|
-
const transceiver = this._addTransceiver(track, {
|
|
1240
|
-
direction: "sendrecv",
|
|
1241
|
-
});
|
|
1242
|
-
this.needNegotiation();
|
|
1243
|
-
return transceiver.sender;
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
async ensureCerts() {
|
|
1247
|
-
if (!this.certificate) {
|
|
1248
|
-
this.certificate = await dtls_1.RTCDtlsTransport.SetupCertificate();
|
|
1249
|
-
}
|
|
1250
|
-
for (const dtlsTransport of this.dtlsTransports) {
|
|
1251
|
-
dtlsTransport.localCertificate = this.certificate;
|
|
759
|
+
const transceiver = this.transceiverManager.addTrack(track, ms);
|
|
760
|
+
if (!transceiver.dtlsTransport) {
|
|
761
|
+
const dtlsTransport = this.findOrCreateTransport();
|
|
762
|
+
transceiver.setDtlsTransport(dtlsTransport);
|
|
1252
763
|
}
|
|
764
|
+
this.needNegotiation();
|
|
765
|
+
return transceiver.sender;
|
|
1253
766
|
}
|
|
1254
767
|
async createAnswer() {
|
|
1255
|
-
await this.ensureCerts();
|
|
1256
|
-
const description = this.buildAnswer();
|
|
1257
|
-
return description.toJSON();
|
|
1258
|
-
}
|
|
1259
|
-
buildAnswer() {
|
|
1260
768
|
this.assertNotClosed();
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
}
|
|
1267
|
-
const description = new sdp_1.SessionDescription();
|
|
1268
|
-
(0, sdp_1.addSDPHeader)("answer", description);
|
|
1269
|
-
this._remoteDescription.media.forEach((remoteMedia) => {
|
|
1270
|
-
let dtlsTransport;
|
|
1271
|
-
let media;
|
|
1272
|
-
if (["audio", "video"].includes(remoteMedia.kind)) {
|
|
1273
|
-
const transceiver = this.getTransceiverByMid(remoteMedia.rtp.muxId);
|
|
1274
|
-
media = createMediaDescriptionForTransceiver(transceiver, this.cname, (0, utils_1.andDirection)(transceiver.direction, transceiver.offerDirection));
|
|
1275
|
-
dtlsTransport = transceiver.dtlsTransport;
|
|
1276
|
-
}
|
|
1277
|
-
else if (remoteMedia.kind === "application") {
|
|
1278
|
-
if (!this.sctpTransport || !this.sctpTransport.mid) {
|
|
1279
|
-
throw new Error("sctpTransport not found");
|
|
1280
|
-
}
|
|
1281
|
-
media = createMediaDescriptionForSctp(this.sctpTransport);
|
|
1282
|
-
dtlsTransport = this.sctpTransport.dtlsTransport;
|
|
1283
|
-
}
|
|
1284
|
-
else {
|
|
1285
|
-
throw new Error("invalid kind");
|
|
1286
|
-
}
|
|
1287
|
-
// # determine DTLS role, or preserve the currently configured role
|
|
1288
|
-
if (media.dtlsParams) {
|
|
1289
|
-
if (dtlsTransport.role === "auto") {
|
|
1290
|
-
media.dtlsParams.role = "client";
|
|
1291
|
-
}
|
|
1292
|
-
else {
|
|
1293
|
-
media.dtlsParams.role = dtlsTransport.role;
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
media.simulcastParameters = remoteMedia.simulcastParameters.map((v) => ({
|
|
1297
|
-
...v,
|
|
1298
|
-
direction: (0, utils_1.reverseSimulcastDirection)(v.direction),
|
|
1299
|
-
}));
|
|
1300
|
-
description.media.push(media);
|
|
769
|
+
await this.secureManager.ensureCerts();
|
|
770
|
+
const description = this.sdpManager.buildAnswerSdp({
|
|
771
|
+
transceivers: this.transceiverManager.getTransceivers(),
|
|
772
|
+
sctpTransport: this.sctpTransport,
|
|
773
|
+
signalingState: this.signalingState,
|
|
1301
774
|
});
|
|
1302
|
-
|
|
1303
|
-
const bundle = new sdp_1.GroupDescription("BUNDLE", []);
|
|
1304
|
-
for (const media of description.media) {
|
|
1305
|
-
if (media.direction !== "inactive") {
|
|
1306
|
-
bundle.items.push(media.rtp.muxId);
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
description.group.push(bundle);
|
|
1310
|
-
}
|
|
1311
|
-
return description;
|
|
1312
|
-
}
|
|
1313
|
-
async close() {
|
|
1314
|
-
if (this.isClosed)
|
|
1315
|
-
return;
|
|
1316
|
-
this.isClosed = true;
|
|
1317
|
-
this.setSignalingState("closed");
|
|
1318
|
-
this.setConnectionState("closed");
|
|
1319
|
-
this.transceivers.forEach((transceiver) => {
|
|
1320
|
-
transceiver.receiver.stop();
|
|
1321
|
-
transceiver.sender.stop();
|
|
1322
|
-
});
|
|
1323
|
-
if (this.sctpTransport) {
|
|
1324
|
-
await this.sctpTransport.stop();
|
|
1325
|
-
}
|
|
1326
|
-
for (const dtlsTransport of this.dtlsTransports) {
|
|
1327
|
-
await dtlsTransport.stop();
|
|
1328
|
-
await dtlsTransport.iceTransport.stop();
|
|
1329
|
-
}
|
|
1330
|
-
this.dispose();
|
|
1331
|
-
log("peerConnection closed");
|
|
775
|
+
return description.toJSON();
|
|
1332
776
|
}
|
|
1333
777
|
assertNotClosed() {
|
|
1334
778
|
if (this.isClosed) {
|
|
1335
779
|
throw new Error("RTCPeerConnection is closed");
|
|
1336
780
|
}
|
|
1337
781
|
}
|
|
1338
|
-
// https://w3c.github.io/webrtc-pc/#dom-rtcicegatheringstate
|
|
1339
|
-
updateIceGatheringState() {
|
|
1340
|
-
const all = this.iceTransports;
|
|
1341
|
-
function allMatch(...state) {
|
|
1342
|
-
return (all.filter((check) => state.includes(check.gatheringState)).length ===
|
|
1343
|
-
all.length);
|
|
1344
|
-
}
|
|
1345
|
-
let newState;
|
|
1346
|
-
if (all.length && allMatch("complete")) {
|
|
1347
|
-
newState = "complete";
|
|
1348
|
-
}
|
|
1349
|
-
else if (!all.length || allMatch("new", "complete")) {
|
|
1350
|
-
newState = "new";
|
|
1351
|
-
}
|
|
1352
|
-
else if (all.map((check) => check.gatheringState).includes("gathering")) {
|
|
1353
|
-
newState = "gathering";
|
|
1354
|
-
}
|
|
1355
|
-
else {
|
|
1356
|
-
newState = "new";
|
|
1357
|
-
}
|
|
1358
|
-
if (this.iceGatheringState === newState) {
|
|
1359
|
-
return;
|
|
1360
|
-
}
|
|
1361
|
-
log("iceGatheringStateChange", newState);
|
|
1362
|
-
this.iceGatheringState = newState;
|
|
1363
|
-
this.iceGatheringStateChange.execute(newState);
|
|
1364
|
-
this.emit("icegatheringstatechange", newState);
|
|
1365
|
-
}
|
|
1366
|
-
// https://w3c.github.io/webrtc-pc/#dom-rtciceconnectionstate
|
|
1367
|
-
updateIceConnectionState() {
|
|
1368
|
-
const all = this.iceTransports;
|
|
1369
|
-
let newState;
|
|
1370
|
-
function allMatch(...state) {
|
|
1371
|
-
return (all.filter((check) => state.includes(check.state)).length === all.length);
|
|
1372
|
-
}
|
|
1373
|
-
if (this.connectionState === "closed") {
|
|
1374
|
-
newState = "closed";
|
|
1375
|
-
}
|
|
1376
|
-
else if (allMatch("failed")) {
|
|
1377
|
-
newState = "failed";
|
|
1378
|
-
}
|
|
1379
|
-
else if (allMatch("disconnected")) {
|
|
1380
|
-
newState = "disconnected";
|
|
1381
|
-
}
|
|
1382
|
-
else if (allMatch("new", "closed")) {
|
|
1383
|
-
newState = "new";
|
|
1384
|
-
}
|
|
1385
|
-
else if (allMatch("new", "checking")) {
|
|
1386
|
-
newState = "checking";
|
|
1387
|
-
}
|
|
1388
|
-
else if (allMatch("completed", "closed")) {
|
|
1389
|
-
newState = "completed";
|
|
1390
|
-
}
|
|
1391
|
-
else if (allMatch("connected", "completed", "closed")) {
|
|
1392
|
-
newState = "connected";
|
|
1393
|
-
}
|
|
1394
|
-
else {
|
|
1395
|
-
// unreachable?
|
|
1396
|
-
newState = "new";
|
|
1397
|
-
}
|
|
1398
|
-
if (this.iceConnectionState === newState) {
|
|
1399
|
-
return;
|
|
1400
|
-
}
|
|
1401
|
-
log("iceConnectionStateChange", newState);
|
|
1402
|
-
this.iceConnectionState = newState;
|
|
1403
|
-
this.iceConnectionStateChange.execute(newState);
|
|
1404
|
-
this.emit("iceconnectionstatechange", newState);
|
|
1405
|
-
if (this.oniceconnectionstatechange) {
|
|
1406
|
-
this.oniceconnectionstatechange();
|
|
1407
|
-
}
|
|
1408
|
-
}
|
|
1409
782
|
setSignalingState(state) {
|
|
1410
783
|
log("signalingStateChange", state);
|
|
1411
784
|
this.signalingState = state;
|
|
@@ -1414,16 +787,43 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1414
787
|
this.onsignalingstatechange({});
|
|
1415
788
|
}
|
|
1416
789
|
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
790
|
+
createPeerConnectionStats() {
|
|
791
|
+
const timestamp = (0, stats_1.getStatsTimestamp)();
|
|
792
|
+
return {
|
|
793
|
+
type: "peer-connection",
|
|
794
|
+
id: (0, stats_1.generateStatsId)("peer-connection"),
|
|
795
|
+
timestamp,
|
|
796
|
+
dataChannelsOpened: this.sctpManager.dataChannelsOpened,
|
|
797
|
+
dataChannelsClosed: this.sctpManager.dataChannelsClosed,
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
async getStats(selector) {
|
|
801
|
+
const stats = [];
|
|
802
|
+
// Peer connection stats - always included regardless of selector
|
|
803
|
+
stats.push(this.createPeerConnectionStats());
|
|
804
|
+
// Get stats from transceivers
|
|
805
|
+
const transceiverStats = await this.transceiverManager.getStats(selector);
|
|
806
|
+
stats.push(...transceiverStats);
|
|
807
|
+
// Get transport stats - always included regardless of selector
|
|
808
|
+
const transportStats = await this.secureManager.getStats();
|
|
809
|
+
stats.push(...transportStats);
|
|
810
|
+
// Get data channel stats - always included regardless of selector
|
|
811
|
+
if (this.sctpTransport) {
|
|
812
|
+
const dataChannelStats = await this.sctpManager.getStats();
|
|
813
|
+
if (dataChannelStats) {
|
|
814
|
+
stats.push(...dataChannelStats);
|
|
815
|
+
}
|
|
1423
816
|
}
|
|
1424
|
-
|
|
817
|
+
return new stats_1.RTCStatsReport(stats);
|
|
1425
818
|
}
|
|
1426
|
-
|
|
819
|
+
async close() {
|
|
820
|
+
if (this.isClosed)
|
|
821
|
+
return;
|
|
822
|
+
this.isClosed = true;
|
|
823
|
+
this.setSignalingState("closed");
|
|
824
|
+
await this.secureManager.close();
|
|
825
|
+
await this.sctpManager.close();
|
|
826
|
+
this.transceiverManager.close();
|
|
1427
827
|
this.onDataChannel.allUnsubscribe();
|
|
1428
828
|
this.iceGatheringStateChange.allUnsubscribe();
|
|
1429
829
|
this.iceConnectionStateChange.allUnsubscribe();
|
|
@@ -1431,77 +831,10 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1431
831
|
this.onTransceiverAdded.allUnsubscribe();
|
|
1432
832
|
this.onRemoteTransceiverAdded.allUnsubscribe();
|
|
1433
833
|
this.onIceCandidate.allUnsubscribe();
|
|
834
|
+
log("peerConnection closed");
|
|
1434
835
|
}
|
|
1435
836
|
}
|
|
1436
837
|
exports.RTCPeerConnection = RTCPeerConnection;
|
|
1437
|
-
function createMediaDescriptionForTransceiver(transceiver, cname, direction) {
|
|
1438
|
-
const media = new sdp_1.MediaDescription(transceiver.kind, 9, "UDP/TLS/RTP/SAVPF", transceiver.codecs.map((c) => c.payloadType));
|
|
1439
|
-
media.direction = direction;
|
|
1440
|
-
media.msid = transceiver.msid;
|
|
1441
|
-
media.rtp = {
|
|
1442
|
-
codecs: transceiver.codecs,
|
|
1443
|
-
headerExtensions: transceiver.headerExtensions,
|
|
1444
|
-
muxId: transceiver.mid,
|
|
1445
|
-
};
|
|
1446
|
-
media.rtcpHost = "0.0.0.0";
|
|
1447
|
-
media.rtcpPort = 9;
|
|
1448
|
-
media.rtcpMux = true;
|
|
1449
|
-
media.ssrc = [new sdp_1.SsrcDescription({ ssrc: transceiver.sender.ssrc, cname })];
|
|
1450
|
-
if (transceiver.options.simulcast) {
|
|
1451
|
-
media.simulcastParameters = transceiver.options.simulcast.map((o) => new media_1.RTCRtpSimulcastParameters(o));
|
|
1452
|
-
}
|
|
1453
|
-
if (media.rtp.codecs.find((c) => c.name.toLowerCase() === "rtx")) {
|
|
1454
|
-
media.ssrc.push(new sdp_1.SsrcDescription({ ssrc: transceiver.sender.rtxSsrc, cname }));
|
|
1455
|
-
media.ssrcGroup = [
|
|
1456
|
-
new sdp_1.GroupDescription("FID", [
|
|
1457
|
-
transceiver.sender.ssrc.toString(),
|
|
1458
|
-
transceiver.sender.rtxSsrc.toString(),
|
|
1459
|
-
]),
|
|
1460
|
-
];
|
|
1461
|
-
}
|
|
1462
|
-
addTransportDescription(media, transceiver.dtlsTransport);
|
|
1463
|
-
return media;
|
|
1464
|
-
}
|
|
1465
|
-
function createMediaDescriptionForSctp(sctp) {
|
|
1466
|
-
const media = new sdp_1.MediaDescription("application", const_1.DISCARD_PORT, "UDP/DTLS/SCTP", ["webrtc-datachannel"]);
|
|
1467
|
-
media.sctpPort = sctp.port;
|
|
1468
|
-
media.rtp.muxId = sctp.mid;
|
|
1469
|
-
media.sctpCapabilities = sctp_1.RTCSctpTransport.getCapabilities();
|
|
1470
|
-
addTransportDescription(media, sctp.dtlsTransport);
|
|
1471
|
-
return media;
|
|
1472
|
-
}
|
|
1473
|
-
function addTransportDescription(media, dtlsTransport) {
|
|
1474
|
-
const iceTransport = dtlsTransport.iceTransport;
|
|
1475
|
-
media.iceCandidates = iceTransport.localCandidates;
|
|
1476
|
-
media.iceCandidatesComplete = iceTransport.gatheringState === "complete";
|
|
1477
|
-
media.iceParams = iceTransport.localParameters;
|
|
1478
|
-
media.iceOptions = "trickle";
|
|
1479
|
-
media.host = const_1.DISCARD_HOST;
|
|
1480
|
-
media.port = const_1.DISCARD_PORT;
|
|
1481
|
-
if (media.direction === "inactive") {
|
|
1482
|
-
media.port = 0;
|
|
1483
|
-
media.msid = undefined;
|
|
1484
|
-
}
|
|
1485
|
-
if (!media.dtlsParams) {
|
|
1486
|
-
media.dtlsParams = dtlsTransport.localParameters;
|
|
1487
|
-
if (!media.dtlsParams.fingerprints) {
|
|
1488
|
-
media.dtlsParams.fingerprints =
|
|
1489
|
-
dtlsTransport.localParameters.fingerprints;
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
}
|
|
1493
|
-
function allocateMid(mids, type) {
|
|
1494
|
-
let mid = "";
|
|
1495
|
-
for (let i = 0;;) {
|
|
1496
|
-
// rfc9143.html#name-security-considerations
|
|
1497
|
-
// SHOULD be 3 bytes or fewer to allow them to efficiently fit into the MID RTP header extension
|
|
1498
|
-
mid = (i++).toString() + type;
|
|
1499
|
-
if (!mids.has(mid))
|
|
1500
|
-
break;
|
|
1501
|
-
}
|
|
1502
|
-
mids.add(mid);
|
|
1503
|
-
return mid;
|
|
1504
|
-
}
|
|
1505
838
|
const findCodecByMimeType = (codecs, target) => codecs.find((localCodec) => localCodec.mimeType.toLowerCase() === target.mimeType.toLowerCase())
|
|
1506
839
|
? target
|
|
1507
840
|
: undefined;
|