werift 0.22.1 → 0.22.3
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 +8 -7
- package/lib/common/src/binary.js +5 -2
- package/lib/common/src/binary.js.map +1 -1
- 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 +4 -1
- package/lib/common/src/transport.js +35 -14
- package/lib/common/src/transport.js.map +1 -1
- package/lib/dtls/src/cipher/create.d.ts +2 -1
- package/lib/dtls/src/cipher/create.js.map +1 -1
- package/lib/dtls/src/cipher/prf.d.ts +12 -12
- package/lib/dtls/src/cipher/suites/abstract.d.ts +2 -1
- package/lib/dtls/src/cipher/suites/abstract.js.map +1 -1
- package/lib/dtls/src/cipher/suites/aead.d.ts +3 -2
- package/lib/dtls/src/cipher/suites/aead.js +34 -41
- 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 +25 -15
- 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/extensions/useSrtp.js +4 -7
- package/lib/dtls/src/handshake/extensions/useSrtp.js.map +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/candidate.js +1 -5
- package/lib/ice/src/candidate.js.map +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 +93 -72
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/iceBase.d.ts +21 -2
- package/lib/ice/src/iceBase.js +47 -1
- 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 +48 -29
- 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 +22 -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/stun/protocol.js +6 -0
- package/lib/ice/src/stun/protocol.js.map +1 -1
- package/lib/ice/src/turn/protocol.d.ts +2 -2
- package/lib/ice/src/turn/protocol.js +3 -0
- package/lib/ice/src/turn/protocol.js.map +1 -1
- package/lib/index.mjs +2707 -1883
- package/lib/nonstandard/index.mjs +737 -698
- 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 +9 -9
- package/lib/rtp/src/extra/container/webm/container.js +24 -12
- package/lib/rtp/src/extra/container/webm/container.js.map +1 -1
- package/lib/rtp/src/extra/container/webm/ebml/ebml.d.ts +35 -1
- package/lib/rtp/src/extra/container/webm/ebml/ebml.js +75 -1
- package/lib/rtp/src/extra/container/webm/ebml/ebml.js.map +1 -1
- package/lib/rtp/src/extra/container/webm/ebml/id.d.ts +222 -222
- package/lib/rtp/src/extra/container/webm/index.d.ts +1 -0
- package/lib/rtp/src/extra/container/webm/index.js +1 -0
- package/lib/rtp/src/extra/container/webm/index.js.map +1 -1
- package/lib/rtp/src/extra/container/webm/util.d.ts +8 -0
- package/lib/rtp/src/extra/container/webm/util.js +100 -0
- package/lib/rtp/src/extra/container/webm/util.js.map +1 -0
- 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/dtx.d.ts +1 -1
- package/lib/rtp/src/extra/processor/dtx.js +1 -1
- package/lib/rtp/src/extra/processor/dtx.js.map +1 -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/lipsync.js +1 -1
- package/lib/rtp/src/extra/processor/lipsync.js.map +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/mute.d.ts +1 -1
- package/lib/rtp/src/extra/processor/mute.js +1 -1
- package/lib/rtp/src/extra/processor/mute.js.map +1 -1
- package/lib/rtp/src/extra/processor/nackHandlerCallback.d.ts +1 -1
- package/lib/rtp/src/extra/processor/ntpTime.d.ts +1 -1
- package/lib/rtp/src/extra/processor/ntpTime.js +1 -1
- package/lib/rtp/src/extra/processor/ntpTime.js.map +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 +3 -3
- package/lib/rtp/src/extra/processor/webm.js.map +1 -1
- package/lib/rtp/src/extra/processor/webmStream.d.ts +2 -2
- package/lib/rtp/src/extra/processor/webmStream.js.map +1 -1
- package/lib/rtp/src/helper.d.ts +1 -1
- package/lib/rtp/src/rtcp/header.d.ts +2 -1
- package/lib/rtp/src/rtcp/header.js +10 -0
- package/lib/rtp/src/rtcp/header.js.map +1 -1
- package/lib/rtp/src/rtcp/psfb/fullIntraRequest.d.ts +1 -1
- package/lib/rtp/src/rtcp/psfb/index.d.ts +2 -2
- package/lib/rtp/src/rtcp/psfb/index.js +2 -2
- package/lib/rtp/src/rtcp/psfb/index.js.map +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/rr.js +2 -2
- package/lib/rtp/src/rtcp/rr.js.map +1 -1
- package/lib/rtp/src/rtcp/rtcp.d.ts +0 -1
- package/lib/rtp/src/rtcp/rtcp.js +0 -10
- package/lib/rtp/src/rtcp/rtcp.js.map +1 -1
- package/lib/rtp/src/rtcp/rtpfb/const.d.ts +1 -0
- package/lib/rtp/src/rtcp/rtpfb/const.js +5 -0
- package/lib/rtp/src/rtcp/rtpfb/const.js.map +1 -0
- package/lib/rtp/src/rtcp/rtpfb/index.d.ts +1 -1
- package/lib/rtp/src/rtcp/rtpfb/index.js +2 -1
- package/lib/rtp/src/rtcp/rtpfb/index.js.map +1 -1
- package/lib/rtp/src/rtcp/rtpfb/nack.d.ts +1 -1
- package/lib/rtp/src/rtcp/rtpfb/nack.js +2 -2
- package/lib/rtp/src/rtcp/rtpfb/nack.js.map +1 -1
- package/lib/rtp/src/rtcp/rtpfb/twcc.d.ts +4 -4
- package/lib/rtp/src/rtcp/sdes.d.ts +4 -4
- package/lib/rtp/src/rtcp/sdes.js +2 -2
- package/lib/rtp/src/rtcp/sdes.js.map +1 -1
- package/lib/rtp/src/rtcp/sr.d.ts +2 -2
- package/lib/rtp/src/rtcp/sr.js +2 -2
- package/lib/rtp/src/rtcp/sr.js.map +1 -1
- 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 +10 -10
- 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/param.js +4 -5
- package/lib/sctp/src/param.js.map +1 -1
- package/lib/sctp/src/sctp.d.ts +3 -1
- package/lib/sctp/src/sctp.js +58 -15
- 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 +2 -0
- package/lib/webrtc/src/media/index.js +2 -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/receiver/nack.js +3 -7
- package/lib/webrtc/src/media/receiver/nack.js.map +1 -1
- package/lib/webrtc/src/media/receiver/receiverTwcc.d.ts +2 -2
- package/lib/webrtc/src/media/receiver/receiverTwcc.js +1 -1
- package/lib/webrtc/src/media/receiver/receiverTwcc.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 +53 -4
- 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 +64 -26
- 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 +30 -26
- 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/media/track.js +3 -3
- package/lib/webrtc/src/media/track.js.map +1 -1
- package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia.js +2 -2
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +35 -64
- package/lib/webrtc/src/peerConnection.js +337 -1034
- 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 +349 -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 +128 -13
- 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 +88 -2
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.js +13 -26
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +9 -4
- package/lib/webrtc/src/utils.js +34 -13
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +12 -26
|
@@ -1,135 +1,87 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
3
|
exports.defaultPeerConfig = exports.findCodecByMimeType = exports.RTCPeerConnection = void 0;
|
|
30
|
-
|
|
31
|
-
exports.createMediaDescriptionForSctp = createMediaDescriptionForSctp;
|
|
32
|
-
exports.addTransportDescription = addTransportDescription;
|
|
33
|
-
exports.allocateMid = allocateMid;
|
|
34
|
-
const cloneDeep_js_1 = __importDefault(require("lodash/cloneDeep.js"));
|
|
35
|
-
const isEqual_js_1 = __importDefault(require("lodash/isEqual.js"));
|
|
36
|
-
const uuid = __importStar(require("uuid"));
|
|
37
|
-
const const_1 = require("./const");
|
|
38
|
-
const dataChannel_1 = require("./dataChannel");
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
39
5
|
const helper_1 = require("./helper");
|
|
40
6
|
const common_1 = require("./imports/common");
|
|
41
7
|
const media_1 = require("./media");
|
|
8
|
+
const stats_1 = require("./media/stats");
|
|
9
|
+
const sctpManager_1 = require("./sctpManager");
|
|
42
10
|
const sdp_1 = require("./sdp");
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
const sctp_1 = require("./transport/sctp");
|
|
11
|
+
const sdpManager_1 = require("./sdpManager");
|
|
12
|
+
const secureTransportManager_1 = require("./secureTransportManager");
|
|
46
13
|
const utils_1 = require("./utils");
|
|
47
14
|
const log = (0, common_1.debug)("werift:packages/webrtc/src/peerConnection.ts");
|
|
48
15
|
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
16
|
constructor(config = {}) {
|
|
77
17
|
super();
|
|
78
18
|
Object.defineProperty(this, "cname", {
|
|
79
19
|
enumerable: true,
|
|
80
20
|
configurable: true,
|
|
81
21
|
writable: true,
|
|
82
|
-
value:
|
|
22
|
+
value: (0, crypto_1.randomUUID)().toString()
|
|
83
23
|
});
|
|
84
|
-
Object.defineProperty(this, "
|
|
24
|
+
Object.defineProperty(this, "config", {
|
|
85
25
|
enumerable: true,
|
|
86
26
|
configurable: true,
|
|
87
27
|
writable: true,
|
|
88
|
-
value:
|
|
28
|
+
value: generateDefaultPeerConfig()
|
|
89
29
|
});
|
|
90
|
-
Object.defineProperty(this, "
|
|
30
|
+
Object.defineProperty(this, "signalingState", {
|
|
91
31
|
enumerable: true,
|
|
92
32
|
configurable: true,
|
|
93
33
|
writable: true,
|
|
94
|
-
value:
|
|
34
|
+
value: "stable"
|
|
95
35
|
});
|
|
96
|
-
Object.defineProperty(this, "
|
|
36
|
+
Object.defineProperty(this, "negotiationneeded", {
|
|
97
37
|
enumerable: true,
|
|
98
38
|
configurable: true,
|
|
99
39
|
writable: true,
|
|
100
|
-
value:
|
|
40
|
+
value: false
|
|
101
41
|
});
|
|
102
|
-
Object.defineProperty(this, "
|
|
42
|
+
Object.defineProperty(this, "needRestart", {
|
|
103
43
|
enumerable: true,
|
|
104
44
|
configurable: true,
|
|
105
45
|
writable: true,
|
|
106
|
-
value:
|
|
46
|
+
value: false
|
|
107
47
|
});
|
|
108
|
-
Object.defineProperty(this, "
|
|
48
|
+
Object.defineProperty(this, "router", {
|
|
109
49
|
enumerable: true,
|
|
110
50
|
configurable: true,
|
|
111
51
|
writable: true,
|
|
112
|
-
value:
|
|
52
|
+
value: new media_1.RtpRouter()
|
|
113
53
|
});
|
|
114
|
-
Object.defineProperty(this, "
|
|
54
|
+
Object.defineProperty(this, "sdpManager", {
|
|
115
55
|
enumerable: true,
|
|
116
56
|
configurable: true,
|
|
117
57
|
writable: true,
|
|
118
|
-
value:
|
|
58
|
+
value: void 0
|
|
119
59
|
});
|
|
120
|
-
Object.defineProperty(this, "
|
|
60
|
+
Object.defineProperty(this, "transceiverManager", {
|
|
121
61
|
enumerable: true,
|
|
122
62
|
configurable: true,
|
|
123
63
|
writable: true,
|
|
124
|
-
value:
|
|
64
|
+
value: void 0
|
|
125
65
|
});
|
|
126
|
-
Object.defineProperty(this, "
|
|
66
|
+
Object.defineProperty(this, "sctpManager", {
|
|
127
67
|
enumerable: true,
|
|
128
68
|
configurable: true,
|
|
129
69
|
writable: true,
|
|
130
|
-
value:
|
|
70
|
+
value: void 0
|
|
131
71
|
});
|
|
132
|
-
Object.defineProperty(this, "
|
|
72
|
+
Object.defineProperty(this, "secureManager", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
configurable: true,
|
|
75
|
+
writable: true,
|
|
76
|
+
value: void 0
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(this, "isClosed", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
configurable: true,
|
|
81
|
+
writable: true,
|
|
82
|
+
value: false
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(this, "shouldNegotiationneeded", {
|
|
133
85
|
enumerable: true,
|
|
134
86
|
configurable: true,
|
|
135
87
|
writable: true,
|
|
@@ -207,96 +159,48 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
207
159
|
writable: true,
|
|
208
160
|
value: void 0
|
|
209
161
|
});
|
|
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", {
|
|
162
|
+
Object.defineProperty(this, "onicecandidateerror", {
|
|
223
163
|
enumerable: true,
|
|
224
164
|
configurable: true,
|
|
225
165
|
writable: true,
|
|
226
166
|
value: void 0
|
|
227
167
|
});
|
|
228
|
-
Object.defineProperty(this, "
|
|
229
|
-
enumerable: true,
|
|
230
|
-
configurable: true,
|
|
231
|
-
writable: true,
|
|
232
|
-
value: void 0
|
|
233
|
-
});
|
|
234
|
-
Object.defineProperty(this, "oniceconnectionstatechange", {
|
|
168
|
+
Object.defineProperty(this, "onicegatheringstatechange", {
|
|
235
169
|
enumerable: true,
|
|
236
170
|
configurable: true,
|
|
237
171
|
writable: true,
|
|
238
172
|
value: void 0
|
|
239
173
|
});
|
|
240
|
-
Object.defineProperty(this, "
|
|
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", {
|
|
174
|
+
Object.defineProperty(this, "onnegotiationneeded", {
|
|
253
175
|
enumerable: true,
|
|
254
176
|
configurable: true,
|
|
255
177
|
writable: true,
|
|
256
178
|
value: void 0
|
|
257
179
|
});
|
|
258
|
-
Object.defineProperty(this, "
|
|
259
|
-
enumerable: true,
|
|
260
|
-
configurable: true,
|
|
261
|
-
writable: true,
|
|
262
|
-
value: new Set()
|
|
263
|
-
});
|
|
264
|
-
Object.defineProperty(this, "currentLocalDescription", {
|
|
180
|
+
Object.defineProperty(this, "onsignalingstatechange", {
|
|
265
181
|
enumerable: true,
|
|
266
182
|
configurable: true,
|
|
267
183
|
writable: true,
|
|
268
184
|
value: void 0
|
|
269
185
|
});
|
|
270
|
-
Object.defineProperty(this, "
|
|
186
|
+
Object.defineProperty(this, "ontrack", {
|
|
271
187
|
enumerable: true,
|
|
272
188
|
configurable: true,
|
|
273
189
|
writable: true,
|
|
274
190
|
value: void 0
|
|
275
191
|
});
|
|
276
|
-
Object.defineProperty(this, "
|
|
192
|
+
Object.defineProperty(this, "onconnectionstatechange", {
|
|
277
193
|
enumerable: true,
|
|
278
194
|
configurable: true,
|
|
279
195
|
writable: true,
|
|
280
196
|
value: void 0
|
|
281
197
|
});
|
|
282
|
-
Object.defineProperty(this, "
|
|
198
|
+
Object.defineProperty(this, "oniceconnectionstatechange", {
|
|
283
199
|
enumerable: true,
|
|
284
200
|
configurable: true,
|
|
285
201
|
writable: true,
|
|
286
202
|
value: void 0
|
|
287
203
|
});
|
|
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
204
|
Object.defineProperty(this, "needNegotiation", {
|
|
301
205
|
enumerable: true,
|
|
302
206
|
configurable: true,
|
|
@@ -316,16 +220,113 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
316
220
|
}
|
|
317
221
|
});
|
|
318
222
|
this.setConfiguration(config);
|
|
319
|
-
this.
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
223
|
+
this.sdpManager = new sdpManager_1.SDPManager({
|
|
224
|
+
cname: this.cname,
|
|
225
|
+
bundlePolicy: this.config.bundlePolicy,
|
|
226
|
+
});
|
|
227
|
+
this.transceiverManager = new media_1.TransceiverManager(this.cname, this.config, this.router);
|
|
228
|
+
this.transceiverManager.onTransceiverAdded.pipe(this.onTransceiverAdded);
|
|
229
|
+
this.transceiverManager.onRemoteTransceiverAdded.pipe(this.onRemoteTransceiverAdded);
|
|
230
|
+
this.transceiverManager.onTrack.subscribe(({ track, stream, transceiver }) => {
|
|
231
|
+
const event = {
|
|
232
|
+
track,
|
|
233
|
+
streams: [stream],
|
|
234
|
+
transceiver,
|
|
235
|
+
receiver: transceiver.receiver,
|
|
236
|
+
};
|
|
237
|
+
this.onTrack.execute(track);
|
|
238
|
+
this.emit("track", event);
|
|
239
|
+
if (this.ontrack) {
|
|
240
|
+
this.ontrack(event);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
this.transceiverManager.onNegotiationNeeded.subscribe(() => this.needNegotiation());
|
|
244
|
+
this.sctpManager = new sctpManager_1.SctpTransportManager();
|
|
245
|
+
this.sctpManager.onDataChannel.subscribe((channel) => {
|
|
246
|
+
this.onDataChannel.execute(channel);
|
|
247
|
+
const event = { channel };
|
|
248
|
+
this.ondatachannel?.(event);
|
|
249
|
+
this.emit("datachannel", event);
|
|
250
|
+
});
|
|
251
|
+
this.secureManager = new secureTransportManager_1.SecureTransportManager({
|
|
252
|
+
config: this.config,
|
|
253
|
+
sctpManager: this.sctpManager,
|
|
254
|
+
transceiverManager: this.transceiverManager,
|
|
255
|
+
});
|
|
256
|
+
this.secureManager.iceGatheringStateChange.pipe(this.iceGatheringStateChange);
|
|
257
|
+
this.secureManager.iceConnectionStateChange.subscribe((state) => {
|
|
258
|
+
if (state === "closed") {
|
|
259
|
+
this.close();
|
|
327
260
|
}
|
|
261
|
+
this.iceConnectionStateChange.execute(state);
|
|
328
262
|
});
|
|
263
|
+
this.secureManager.connectionStateChange.subscribe((state) => {
|
|
264
|
+
this.connectionStateChange.execute(state);
|
|
265
|
+
this.onconnectionstatechange?.();
|
|
266
|
+
this.emit("connectionstatechange");
|
|
267
|
+
});
|
|
268
|
+
this.secureManager.onIceCandidate.subscribe((candidate) => {
|
|
269
|
+
const iceCandidate = candidate ? candidate.toJSON() : undefined;
|
|
270
|
+
this.onIceCandidate.execute(iceCandidate);
|
|
271
|
+
this.onicecandidate?.({ candidate: iceCandidate });
|
|
272
|
+
this.emit("icecandidate", { candidate: iceCandidate });
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
get connectionState() {
|
|
276
|
+
return this.secureManager.connectionState;
|
|
277
|
+
}
|
|
278
|
+
get iceConnectionState() {
|
|
279
|
+
return this.secureManager.iceConnectionState;
|
|
280
|
+
}
|
|
281
|
+
get iceGathererState() {
|
|
282
|
+
return this.secureManager.iceGatheringState;
|
|
283
|
+
}
|
|
284
|
+
get iceGatheringState() {
|
|
285
|
+
return this.secureManager.iceGatheringState;
|
|
286
|
+
}
|
|
287
|
+
get dtlsTransports() {
|
|
288
|
+
return this.secureManager.dtlsTransports;
|
|
289
|
+
}
|
|
290
|
+
get sctpTransport() {
|
|
291
|
+
return this.sctpManager.sctpTransport;
|
|
292
|
+
}
|
|
293
|
+
get sctpRemotePort() {
|
|
294
|
+
return this.sctpManager.sctpRemotePort;
|
|
295
|
+
}
|
|
296
|
+
get iceTransports() {
|
|
297
|
+
return this.secureManager.iceTransports;
|
|
298
|
+
}
|
|
299
|
+
get extIdUriMap() {
|
|
300
|
+
return this.router.extIdUriMap;
|
|
301
|
+
}
|
|
302
|
+
get iceGeneration() {
|
|
303
|
+
return this.iceTransports[0].connection.generation;
|
|
304
|
+
}
|
|
305
|
+
get localDescription() {
|
|
306
|
+
return this.sdpManager.localDescription;
|
|
307
|
+
}
|
|
308
|
+
get remoteDescription() {
|
|
309
|
+
return this.sdpManager.remoteDescription;
|
|
310
|
+
}
|
|
311
|
+
get remoteIsBundled() {
|
|
312
|
+
return this.sdpManager.remoteIsBundled;
|
|
313
|
+
}
|
|
314
|
+
/**@private */
|
|
315
|
+
get _localDescription() {
|
|
316
|
+
return this.sdpManager._localDescription;
|
|
317
|
+
}
|
|
318
|
+
/**@private */
|
|
319
|
+
get _remoteDescription() {
|
|
320
|
+
return this.sdpManager._remoteDescription;
|
|
321
|
+
}
|
|
322
|
+
getTransceivers() {
|
|
323
|
+
return this.transceiverManager.getTransceivers();
|
|
324
|
+
}
|
|
325
|
+
getSenders() {
|
|
326
|
+
return this.transceiverManager.getSenders();
|
|
327
|
+
}
|
|
328
|
+
getReceivers() {
|
|
329
|
+
return this.transceiverManager.getReceivers();
|
|
329
330
|
}
|
|
330
331
|
setConfiguration(config) {
|
|
331
332
|
(0, utils_1.deepMerge)(this.config, config);
|
|
@@ -367,38 +368,6 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
367
368
|
].forEach((v, i) => {
|
|
368
369
|
v.id = 1 + i;
|
|
369
370
|
});
|
|
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
371
|
}
|
|
403
372
|
getConfiguration() {
|
|
404
373
|
return this.config;
|
|
@@ -406,207 +375,64 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
406
375
|
async createOffer({ iceRestart } = {}) {
|
|
407
376
|
if (iceRestart || this.needRestart) {
|
|
408
377
|
this.needRestart = false;
|
|
409
|
-
|
|
410
|
-
t.restart();
|
|
411
|
-
}
|
|
378
|
+
this.secureManager.restartIce();
|
|
412
379
|
}
|
|
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) => {
|
|
380
|
+
await this.secureManager.ensureCerts();
|
|
381
|
+
for (const transceiver of this.transceiverManager.getTransceivers()) {
|
|
446
382
|
if (transceiver.codecs.length === 0) {
|
|
447
|
-
this.assignTransceiverCodecs(transceiver);
|
|
383
|
+
this.transceiverManager.assignTransceiverCodecs(transceiver);
|
|
448
384
|
}
|
|
449
385
|
if (transceiver.headerExtensions.length === 0) {
|
|
450
386
|
transceiver.headerExtensions =
|
|
451
387
|
this.config.headerExtensions[transceiver.kind] ?? [];
|
|
452
388
|
}
|
|
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
|
-
}
|
|
510
|
-
if (this.config.bundlePolicy !== "disable") {
|
|
511
|
-
const mids = description.media
|
|
512
|
-
.map((m) => (m.direction !== "inactive" ? m.rtp.muxId : undefined))
|
|
513
|
-
.filter((v) => v);
|
|
514
|
-
if (mids.length) {
|
|
515
|
-
const bundle = new sdp_1.GroupDescription("BUNDLE", mids);
|
|
516
|
-
description.group.push(bundle);
|
|
517
|
-
}
|
|
518
389
|
}
|
|
519
|
-
|
|
390
|
+
const description = this.sdpManager.buildOfferSdp(this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
391
|
+
return description.toJSON();
|
|
392
|
+
}
|
|
393
|
+
createSctpTransport() {
|
|
394
|
+
const sctp = this.sctpManager.createSctpTransport();
|
|
395
|
+
const dtlsTransport = this.findOrCreateTransport();
|
|
396
|
+
sctp.setDtlsTransport(dtlsTransport);
|
|
397
|
+
return sctp;
|
|
520
398
|
}
|
|
521
399
|
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
400
|
if (!this.sctpTransport) {
|
|
532
|
-
this.
|
|
401
|
+
this.createSctpTransport();
|
|
533
402
|
this.needNegotiation();
|
|
534
403
|
}
|
|
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);
|
|
404
|
+
const channel = this.sctpManager.createDataChannel(label, options);
|
|
405
|
+
if (!channel.sctp.dtlsTransport) {
|
|
406
|
+
const dtlsTransport = this.findOrCreateTransport();
|
|
407
|
+
channel.sctp.setDtlsTransport(dtlsTransport);
|
|
408
|
+
}
|
|
545
409
|
return channel;
|
|
546
410
|
}
|
|
547
411
|
removeTrack(sender) {
|
|
548
|
-
if (this.isClosed)
|
|
412
|
+
if (this.isClosed) {
|
|
549
413
|
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
414
|
}
|
|
415
|
+
this.transceiverManager.removeTrack(sender);
|
|
573
416
|
this.needNegotiation();
|
|
574
417
|
}
|
|
575
|
-
|
|
418
|
+
findOrCreateTransport() {
|
|
576
419
|
const [existing] = this.iceTransports;
|
|
577
420
|
// Gather ICE candidates for only one track. If the remote endpoint is not bundle-aware, negotiate only one media track.
|
|
578
421
|
// https://w3c.github.io/webrtc-pc/#rtcbundlepolicy-enum
|
|
579
|
-
if (this.
|
|
422
|
+
if (this.sdpManager.bundlePolicy === "max-bundle" ||
|
|
423
|
+
(this.sdpManager.bundlePolicy !== "disable" && this.remoteIsBundled)) {
|
|
580
424
|
if (existing) {
|
|
581
425
|
return this.dtlsTransports[0];
|
|
582
426
|
}
|
|
583
427
|
}
|
|
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,
|
|
428
|
+
const dtlsTransport = this.secureManager.createTransport();
|
|
429
|
+
dtlsTransport.onRtp.subscribe((rtp) => {
|
|
430
|
+
this.router.routeRtp(rtp);
|
|
597
431
|
});
|
|
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();
|
|
432
|
+
dtlsTransport.onRtcp.subscribe((rtcp) => {
|
|
433
|
+
this.router.routeRtcp(rtcp);
|
|
609
434
|
});
|
|
435
|
+
const iceTransport = dtlsTransport.iceTransport;
|
|
610
436
|
iceTransport.onNegotiationNeeded.subscribe(() => {
|
|
611
437
|
this.needNegotiation();
|
|
612
438
|
});
|
|
@@ -616,7 +442,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
616
442
|
return;
|
|
617
443
|
}
|
|
618
444
|
if (!candidate) {
|
|
619
|
-
this.setLocal(this._localDescription);
|
|
445
|
+
this.sdpManager.setLocal(this._localDescription, this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
620
446
|
this.onIceCandidate.execute(undefined);
|
|
621
447
|
if (this.onicecandidate) {
|
|
622
448
|
this.onicecandidate({ candidate: undefined });
|
|
@@ -624,58 +450,44 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
624
450
|
this.emit("icecandidate", { candidate: undefined });
|
|
625
451
|
return;
|
|
626
452
|
}
|
|
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() });
|
|
453
|
+
if (!this._localDescription) {
|
|
454
|
+
log("localDescription not found when ice candidate was gathered");
|
|
455
|
+
return;
|
|
649
456
|
}
|
|
650
|
-
this.
|
|
457
|
+
this.secureManager.handleNewIceCandidate({
|
|
458
|
+
candidate,
|
|
459
|
+
bundlePolicy: this.sdpManager.bundlePolicy,
|
|
460
|
+
remoteIsBundled: !!this.sdpManager.remoteIsBundled,
|
|
461
|
+
media: this._localDescription.media[0],
|
|
462
|
+
transceiver: this.transceiverManager
|
|
463
|
+
.getTransceivers()
|
|
464
|
+
.find((t) => t.dtlsTransport.iceTransport.id === iceTransport.id),
|
|
465
|
+
sctpTransport: this.sctpTransport?.dtlsTransport.iceTransport.id === iceTransport.id
|
|
466
|
+
? this.sctpTransport
|
|
467
|
+
: undefined,
|
|
468
|
+
});
|
|
651
469
|
});
|
|
652
|
-
const dtlsTransport = new dtls_1.RTCDtlsTransport(this.config, iceTransport, this.router, this.certificate, srtpProfiles);
|
|
653
470
|
return dtlsTransport;
|
|
654
471
|
}
|
|
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
472
|
async setLocalDescription(sessionDescription) {
|
|
473
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/setLocalDescription#type
|
|
474
|
+
const implicitOfferState = [
|
|
475
|
+
"stable",
|
|
476
|
+
"have-local-offer",
|
|
477
|
+
"have-remote-pranswer",
|
|
478
|
+
];
|
|
479
|
+
sessionDescription =
|
|
480
|
+
sessionDescription ??
|
|
481
|
+
(implicitOfferState.includes(this.signalingState)
|
|
482
|
+
? await this.createOffer()
|
|
483
|
+
: await this.createAnswer());
|
|
675
484
|
// # parse and validate description
|
|
676
|
-
const description =
|
|
677
|
-
|
|
678
|
-
|
|
485
|
+
const description = this.sdpManager.parseSdp({
|
|
486
|
+
sdp: sessionDescription.sdp,
|
|
487
|
+
isLocal: true,
|
|
488
|
+
signalingState: this.signalingState,
|
|
489
|
+
type: sessionDescription.type,
|
|
490
|
+
});
|
|
679
491
|
// # update signaling state
|
|
680
492
|
if (description.type === "offer") {
|
|
681
493
|
this.setSignalingState("have-local-offer");
|
|
@@ -686,9 +498,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
686
498
|
// # assign MID
|
|
687
499
|
for (const [i, media] of (0, helper_1.enumerate)(description.media)) {
|
|
688
500
|
const mid = media.rtp.muxId;
|
|
689
|
-
this.
|
|
501
|
+
this.sdpManager.registerMid(mid);
|
|
690
502
|
if (["audio", "video"].includes(media.kind)) {
|
|
691
|
-
const transceiver = this.getTransceiverByMLineIndex(i);
|
|
503
|
+
const transceiver = this.transceiverManager.getTransceiverByMLineIndex(i);
|
|
692
504
|
if (transceiver) {
|
|
693
505
|
transceiver.mid = mid;
|
|
694
506
|
}
|
|
@@ -698,38 +510,21 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
698
510
|
}
|
|
699
511
|
}
|
|
700
512
|
// 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
|
-
}
|
|
513
|
+
const role = description.media.find((media) => media.dtlsParams)?.dtlsParams
|
|
514
|
+
?.role;
|
|
515
|
+
this.secureManager.setLocalRole({
|
|
516
|
+
type: description.type,
|
|
517
|
+
role,
|
|
518
|
+
});
|
|
724
519
|
// # configure direction
|
|
725
520
|
if (["answer", "pranswer"].includes(description.type)) {
|
|
726
|
-
for (const t of this.
|
|
521
|
+
for (const t of this.transceiverManager.getTransceivers()) {
|
|
727
522
|
const direction = (0, utils_1.andDirection)(t.direction, t.offerDirection);
|
|
728
523
|
t.setCurrentDirection(direction);
|
|
729
524
|
}
|
|
730
525
|
}
|
|
731
526
|
// for trickle ice
|
|
732
|
-
this.setLocal(description);
|
|
527
|
+
this.sdpManager.setLocal(description, this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
733
528
|
await this.gatherCandidates().catch((e) => {
|
|
734
529
|
log("gatherCandidates failed", e);
|
|
735
530
|
});
|
|
@@ -737,84 +532,21 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
737
532
|
if (description.type === "answer") {
|
|
738
533
|
this.connect().catch((err) => {
|
|
739
534
|
log("connect failed", err);
|
|
740
|
-
this.setConnectionState("failed");
|
|
535
|
+
this.secureManager.setConnectionState("failed");
|
|
741
536
|
});
|
|
742
537
|
}
|
|
743
|
-
this.setLocal(description);
|
|
538
|
+
this.sdpManager.setLocal(description, this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
744
539
|
if (this.shouldNegotiationneeded) {
|
|
745
540
|
this.needNegotiation();
|
|
746
541
|
}
|
|
747
542
|
return description;
|
|
748
543
|
}
|
|
749
544
|
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;
|
|
545
|
+
await this.secureManager.gatherCandidates(!!this.sdpManager.remoteIsBundled);
|
|
796
546
|
}
|
|
797
547
|
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
|
-
}
|
|
548
|
+
const sdp = this.sdpManager.buildOfferSdp(this.transceiverManager.getTransceivers(), this.sctpTransport);
|
|
549
|
+
await this.secureManager.addIceCandidate(sdp, candidateMessage);
|
|
818
550
|
}
|
|
819
551
|
async connect() {
|
|
820
552
|
log("start connect");
|
|
@@ -823,12 +555,16 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
823
555
|
if (iceTransport.state === "connected") {
|
|
824
556
|
return;
|
|
825
557
|
}
|
|
826
|
-
|
|
558
|
+
const checkDtlsConnected = () => dtlsTransport.state === "connected";
|
|
559
|
+
if (checkDtlsConnected()) {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
this.secureManager.setConnectionState("connecting");
|
|
827
563
|
await iceTransport.start().catch((err) => {
|
|
828
564
|
log("iceTransport.start failed", err);
|
|
829
565
|
throw err;
|
|
830
566
|
});
|
|
831
|
-
if (
|
|
567
|
+
if (checkDtlsConnected()) {
|
|
832
568
|
return;
|
|
833
569
|
}
|
|
834
570
|
await dtlsTransport.start().catch((err) => {
|
|
@@ -836,85 +572,27 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
836
572
|
throw err;
|
|
837
573
|
});
|
|
838
574
|
if (this.sctpTransport &&
|
|
839
|
-
this.sctpRemotePort &&
|
|
840
575
|
this.sctpTransport.dtlsTransport.id === dtlsTransport.id) {
|
|
841
|
-
await this.
|
|
842
|
-
await this.sctpTransport.sctp.stateChanged.connected.asPromise();
|
|
843
|
-
log("sctp connected");
|
|
576
|
+
await this.sctpManager.connectSctp();
|
|
844
577
|
}
|
|
845
578
|
}));
|
|
846
579
|
if (res.find((r) => r.status === "rejected")) {
|
|
847
|
-
this.setConnectionState("failed");
|
|
580
|
+
this.secureManager.setConnectionState("failed");
|
|
848
581
|
}
|
|
849
582
|
else {
|
|
850
|
-
this.setConnectionState("connected");
|
|
583
|
+
this.secureManager.setConnectionState("connected");
|
|
851
584
|
}
|
|
852
585
|
}
|
|
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;
|
|
892
|
-
}
|
|
893
|
-
const bundle = remoteSdp.group.find((g) => g.semantic === "BUNDLE" && this.config.bundlePolicy !== "disable");
|
|
894
|
-
return bundle;
|
|
895
|
-
}
|
|
896
586
|
restartIce() {
|
|
897
587
|
this.needRestart = true;
|
|
898
588
|
this.needNegotiation();
|
|
899
589
|
}
|
|
900
590
|
async setRemoteDescription(sessionDescription) {
|
|
901
|
-
if (
|
|
902
|
-
|
|
903
|
-
sessionDescription.type === "rollback" ||
|
|
904
|
-
sessionDescription.type === "pranswer") {
|
|
905
|
-
throw new Error("invalid sessionDescription");
|
|
591
|
+
if (sessionDescription instanceof sdp_1.SessionDescription) {
|
|
592
|
+
sessionDescription = sessionDescription.toSdp();
|
|
906
593
|
}
|
|
907
594
|
// # 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
|
-
}
|
|
595
|
+
const remoteSdp = this.sdpManager.setRemoteDescription(sessionDescription, this.signalingState);
|
|
918
596
|
let bundleTransport;
|
|
919
597
|
// # apply description
|
|
920
598
|
const matchTransceiverWithMedia = (transceiver, media) => transceiver.kind === media.kind &&
|
|
@@ -922,10 +600,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
922
600
|
let transports = remoteSdp.media.map((remoteMedia, i) => {
|
|
923
601
|
let dtlsTransport;
|
|
924
602
|
if (["audio", "video"].includes(remoteMedia.kind)) {
|
|
925
|
-
let transceiver = this.
|
|
603
|
+
let transceiver = this.transceiverManager
|
|
604
|
+
.getTransceivers()
|
|
605
|
+
.find((t) => matchTransceiverWithMedia(t, remoteMedia));
|
|
926
606
|
if (!transceiver) {
|
|
927
607
|
// create remote transceiver
|
|
928
|
-
transceiver = this.
|
|
608
|
+
transceiver = this.addTransceiver(remoteMedia.kind, {
|
|
929
609
|
direction: "recvonly",
|
|
930
610
|
});
|
|
931
611
|
transceiver.mid = remoteMedia.rtp.muxId;
|
|
@@ -940,7 +620,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
940
620
|
return;
|
|
941
621
|
}
|
|
942
622
|
}
|
|
943
|
-
if (this.remoteIsBundled) {
|
|
623
|
+
if (this.sdpManager.remoteIsBundled) {
|
|
944
624
|
if (!bundleTransport) {
|
|
945
625
|
bundleTransport = transceiver.dtlsTransport;
|
|
946
626
|
}
|
|
@@ -949,30 +629,31 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
949
629
|
}
|
|
950
630
|
}
|
|
951
631
|
dtlsTransport = transceiver.dtlsTransport;
|
|
952
|
-
this.setRemoteRTP(transceiver, remoteMedia, remoteSdp.type, i);
|
|
632
|
+
this.transceiverManager.setRemoteRTP(transceiver, remoteMedia, remoteSdp.type, i);
|
|
953
633
|
}
|
|
954
634
|
else if (remoteMedia.kind === "application") {
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
635
|
+
let sctpTransport = this.sctpTransport;
|
|
636
|
+
if (!sctpTransport) {
|
|
637
|
+
sctpTransport = this.createSctpTransport();
|
|
638
|
+
sctpTransport.mid = remoteMedia.rtp.muxId;
|
|
958
639
|
}
|
|
959
|
-
if (this.remoteIsBundled) {
|
|
640
|
+
if (this.sdpManager.remoteIsBundled) {
|
|
960
641
|
if (!bundleTransport) {
|
|
961
|
-
bundleTransport =
|
|
642
|
+
bundleTransport = sctpTransport.dtlsTransport;
|
|
962
643
|
}
|
|
963
644
|
else {
|
|
964
|
-
|
|
645
|
+
sctpTransport.setDtlsTransport(bundleTransport);
|
|
965
646
|
}
|
|
966
647
|
}
|
|
967
|
-
dtlsTransport =
|
|
968
|
-
this.setRemoteSCTP(remoteMedia,
|
|
648
|
+
dtlsTransport = sctpTransport.dtlsTransport;
|
|
649
|
+
this.sctpManager.setRemoteSCTP(remoteMedia, i);
|
|
969
650
|
}
|
|
970
651
|
else {
|
|
971
652
|
throw new Error("invalid media kind");
|
|
972
653
|
}
|
|
973
654
|
const iceTransport = dtlsTransport.iceTransport;
|
|
974
655
|
if (remoteMedia.iceParams) {
|
|
975
|
-
const renomination = !!
|
|
656
|
+
const renomination = !!this.sdpManager.inactiveRemoteMedia;
|
|
976
657
|
iceTransport.setRemoteParams(remoteMedia.iceParams, renomination);
|
|
977
658
|
// One agent full, one lite: The full agent MUST take the controlling role, and the lite agent MUST take the controlled role
|
|
978
659
|
// RFC 8445 S6.1.1
|
|
@@ -997,7 +678,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
997
678
|
});
|
|
998
679
|
// filter out inactive transports
|
|
999
680
|
transports = transports.filter((iceTransport) => !!iceTransport);
|
|
1000
|
-
const removedTransceivers = this.
|
|
681
|
+
const removedTransceivers = this.transceiverManager
|
|
682
|
+
.getTransceivers()
|
|
683
|
+
.filter((t) => remoteSdp.media.find((m) => matchTransceiverWithMedia(t, m)) ==
|
|
1001
684
|
undefined);
|
|
1002
685
|
if (sessionDescription.type === "answer") {
|
|
1003
686
|
for (const transceiver of removedTransceivers) {
|
|
@@ -1018,7 +701,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1018
701
|
log("caller start connect");
|
|
1019
702
|
this.connect().catch((err) => {
|
|
1020
703
|
log("connect failed", err);
|
|
1021
|
-
this.setConnectionState("failed");
|
|
704
|
+
this.secureManager.setConnectionState("failed");
|
|
1022
705
|
});
|
|
1023
706
|
}
|
|
1024
707
|
this.negotiationneeded = false;
|
|
@@ -1026,177 +709,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1026
709
|
this.needNegotiation();
|
|
1027
710
|
}
|
|
1028
711
|
}
|
|
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
712
|
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();
|
|
713
|
+
const dtlsTransport = this.findOrCreateTransport();
|
|
714
|
+
const transceiver = this.transceiverManager.addTransceiver(trackOrKind, dtlsTransport, options);
|
|
715
|
+
this.secureManager.updateIceConnectionState();
|
|
1189
716
|
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);
|
|
717
|
+
return transceiver;
|
|
1200
718
|
}
|
|
1201
719
|
// todo fix
|
|
1202
720
|
addTrack(track,
|
|
@@ -1205,207 +723,29 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1205
723
|
if (this.isClosed) {
|
|
1206
724
|
throw new Error("is closed");
|
|
1207
725
|
}
|
|
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;
|
|
726
|
+
const transceiver = this.transceiverManager.addTrack(track, ms);
|
|
727
|
+
if (!transceiver.dtlsTransport) {
|
|
728
|
+
const dtlsTransport = this.findOrCreateTransport();
|
|
729
|
+
transceiver.setDtlsTransport(dtlsTransport);
|
|
1252
730
|
}
|
|
731
|
+
this.needNegotiation();
|
|
732
|
+
return transceiver.sender;
|
|
1253
733
|
}
|
|
1254
734
|
async createAnswer() {
|
|
1255
|
-
await this.ensureCerts();
|
|
1256
|
-
const description = this.buildAnswer();
|
|
1257
|
-
return description.toJSON();
|
|
1258
|
-
}
|
|
1259
|
-
buildAnswer() {
|
|
1260
735
|
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);
|
|
1301
|
-
});
|
|
1302
|
-
if (this.config.bundlePolicy !== "disable") {
|
|
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();
|
|
736
|
+
await this.secureManager.ensureCerts();
|
|
737
|
+
const description = this.sdpManager.buildAnswerSdp({
|
|
738
|
+
transceivers: this.transceiverManager.getTransceivers(),
|
|
739
|
+
sctpTransport: this.sctpTransport,
|
|
740
|
+
signalingState: this.signalingState,
|
|
1322
741
|
});
|
|
1323
|
-
|
|
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");
|
|
742
|
+
return description.toJSON();
|
|
1332
743
|
}
|
|
1333
744
|
assertNotClosed() {
|
|
1334
745
|
if (this.isClosed) {
|
|
1335
746
|
throw new Error("RTCPeerConnection is closed");
|
|
1336
747
|
}
|
|
1337
748
|
}
|
|
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
749
|
setSignalingState(state) {
|
|
1410
750
|
log("signalingStateChange", state);
|
|
1411
751
|
this.signalingState = state;
|
|
@@ -1414,16 +754,43 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1414
754
|
this.onsignalingstatechange({});
|
|
1415
755
|
}
|
|
1416
756
|
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
757
|
+
createPeerConnectionStats() {
|
|
758
|
+
const timestamp = (0, stats_1.getStatsTimestamp)();
|
|
759
|
+
return {
|
|
760
|
+
type: "peer-connection",
|
|
761
|
+
id: (0, stats_1.generateStatsId)("peer-connection"),
|
|
762
|
+
timestamp,
|
|
763
|
+
dataChannelsOpened: this.sctpManager.dataChannelsOpened,
|
|
764
|
+
dataChannelsClosed: this.sctpManager.dataChannelsClosed,
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
async getStats(selector) {
|
|
768
|
+
const stats = [];
|
|
769
|
+
// Peer connection stats - always included regardless of selector
|
|
770
|
+
stats.push(this.createPeerConnectionStats());
|
|
771
|
+
// Get stats from transceivers
|
|
772
|
+
const transceiverStats = await this.transceiverManager.getStats(selector);
|
|
773
|
+
stats.push(...transceiverStats);
|
|
774
|
+
// Get transport stats - always included regardless of selector
|
|
775
|
+
const transportStats = await this.secureManager.getStats();
|
|
776
|
+
stats.push(...transportStats);
|
|
777
|
+
// Get data channel stats - always included regardless of selector
|
|
778
|
+
if (this.sctpTransport) {
|
|
779
|
+
const dataChannelStats = await this.sctpManager.getStats();
|
|
780
|
+
if (dataChannelStats) {
|
|
781
|
+
stats.push(...dataChannelStats);
|
|
782
|
+
}
|
|
1423
783
|
}
|
|
1424
|
-
|
|
784
|
+
return new stats_1.RTCStatsReport(stats);
|
|
1425
785
|
}
|
|
1426
|
-
|
|
786
|
+
async close() {
|
|
787
|
+
if (this.isClosed)
|
|
788
|
+
return;
|
|
789
|
+
this.isClosed = true;
|
|
790
|
+
this.setSignalingState("closed");
|
|
791
|
+
this.transceiverManager.close();
|
|
792
|
+
await this.secureManager.close();
|
|
793
|
+
await this.sctpManager.close();
|
|
1427
794
|
this.onDataChannel.allUnsubscribe();
|
|
1428
795
|
this.iceGatheringStateChange.allUnsubscribe();
|
|
1429
796
|
this.iceConnectionStateChange.allUnsubscribe();
|
|
@@ -1431,105 +798,41 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1431
798
|
this.onTransceiverAdded.allUnsubscribe();
|
|
1432
799
|
this.onRemoteTransceiverAdded.allUnsubscribe();
|
|
1433
800
|
this.onIceCandidate.allUnsubscribe();
|
|
801
|
+
log("peerConnection closed");
|
|
1434
802
|
}
|
|
1435
803
|
}
|
|
1436
804
|
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
805
|
const findCodecByMimeType = (codecs, target) => codecs.find((localCodec) => localCodec.mimeType.toLowerCase() === target.mimeType.toLowerCase())
|
|
1506
806
|
? target
|
|
1507
807
|
: undefined;
|
|
1508
808
|
exports.findCodecByMimeType = findCodecByMimeType;
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
809
|
+
function generateDefaultPeerConfig() {
|
|
810
|
+
return {
|
|
811
|
+
codecs: {
|
|
812
|
+
audio: [(0, media_1.useOPUS)(), (0, media_1.usePCMU)()],
|
|
813
|
+
video: [(0, media_1.useVP8)()],
|
|
814
|
+
},
|
|
815
|
+
headerExtensions: {
|
|
816
|
+
audio: [],
|
|
817
|
+
video: [],
|
|
818
|
+
},
|
|
819
|
+
iceTransportPolicy: "all",
|
|
820
|
+
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
|
|
821
|
+
icePortRange: undefined,
|
|
822
|
+
iceInterfaceAddresses: undefined,
|
|
823
|
+
iceAdditionalHostAddresses: undefined,
|
|
824
|
+
iceUseIpv4: true,
|
|
825
|
+
iceUseIpv6: true,
|
|
826
|
+
iceFilterStunResponse: undefined,
|
|
827
|
+
iceFilterCandidatePair: undefined,
|
|
828
|
+
icePasswordPrefix: undefined,
|
|
829
|
+
iceUseLinkLocalAddress: undefined,
|
|
830
|
+
dtls: {},
|
|
831
|
+
bundlePolicy: "max-compat",
|
|
832
|
+
debug: {},
|
|
833
|
+
midSuffix: false,
|
|
834
|
+
forceTurnTCP: false,
|
|
835
|
+
};
|
|
836
|
+
}
|
|
837
|
+
exports.defaultPeerConfig = generateDefaultPeerConfig();
|
|
1535
838
|
//# sourceMappingURL=peerConnection.js.map
|