werift 0.15.10 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/src/index.d.ts +2 -0
- package/lib/common/src/index.js +2 -0
- package/lib/common/src/index.js.map +1 -1
- package/lib/common/src/log.d.ts +11 -0
- package/lib/common/src/log.js +17 -0
- package/lib/common/src/log.js.map +1 -0
- package/lib/common/src/network.d.ts +7 -3
- package/lib/common/src/network.js +15 -7
- package/lib/common/src/network.js.map +1 -1
- package/lib/common/src/type.d.ts +3 -0
- package/lib/common/src/type.js +3 -0
- package/lib/common/src/type.js.map +1 -0
- package/lib/dtls/src/context/cipher.js.map +1 -1
- package/lib/dtls/src/flight/server/flight2.js +10 -0
- package/lib/dtls/src/flight/server/flight2.js.map +1 -1
- package/lib/ice/src/ice.d.ts +3 -0
- package/lib/ice/src/ice.js +9 -2
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/stun/protocol.d.ts +2 -1
- package/lib/ice/src/stun/protocol.js +3 -3
- package/lib/ice/src/stun/protocol.js.map +1 -1
- package/lib/ice/src/transport.d.ts +4 -2
- package/lib/ice/src/transport.js +8 -6
- package/lib/ice/src/transport.js.map +1 -1
- package/lib/ice/src/turn/protocol.d.ts +3 -1
- package/lib/ice/src/turn/protocol.js +2 -2
- package/lib/ice/src/turn/protocol.js.map +1 -1
- package/lib/ice/src/utils.d.ts +2 -1
- package/lib/ice/src/utils.js +2 -2
- package/lib/ice/src/utils.js.map +1 -1
- package/lib/rtp/src/codec/index.d.ts +18 -0
- package/lib/rtp/src/codec/index.js +81 -0
- package/lib/rtp/src/codec/index.js.map +1 -0
- package/lib/rtp/src/codec/vp8.d.ts +5 -3
- package/lib/rtp/src/codec/vp8.js +19 -5
- package/lib/rtp/src/codec/vp8.js.map +1 -1
- package/lib/rtp/src/container/webm.d.ts +6 -1
- package/lib/rtp/src/container/webm.js +9 -2
- package/lib/rtp/src/container/webm.js.map +1 -1
- package/lib/rtp/src/index.d.ts +2 -6
- package/lib/rtp/src/index.js +2 -6
- package/lib/rtp/src/index.js.map +1 -1
- package/lib/rtp/src/processor/base.d.ts +3 -1
- package/lib/rtp/src/processor/base.js +19 -6
- package/lib/rtp/src/processor/base.js.map +1 -1
- package/lib/rtp/src/processor/jitterBuffer.js +1 -2
- package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
- package/lib/rtp/src/processor/lipsync.js +22 -2
- package/lib/rtp/src/processor/lipsync.js.map +1 -1
- package/lib/rtp/src/processor/webm.d.ts +11 -7
- package/lib/rtp/src/processor/webm.js +16 -41
- package/lib/rtp/src/processor/webm.js.map +1 -1
- package/lib/rtp/src/processor_v2/depacketizer.d.ts +17 -0
- package/lib/rtp/src/processor_v2/depacketizer.js +84 -0
- package/lib/rtp/src/processor_v2/depacketizer.js.map +1 -0
- package/lib/rtp/src/processor_v2/index.d.ts +4 -0
- package/lib/rtp/src/processor_v2/index.js +21 -0
- package/lib/rtp/src/processor_v2/index.js.map +1 -0
- package/lib/rtp/src/processor_v2/jitterBuffer.d.ts +33 -0
- package/lib/rtp/src/processor_v2/jitterBuffer.js +154 -0
- package/lib/rtp/src/processor_v2/jitterBuffer.js.map +1 -0
- package/lib/rtp/src/processor_v2/source/base.d.ts +8 -0
- package/lib/rtp/src/processor_v2/source/base.js +16 -0
- package/lib/rtp/src/processor_v2/source/base.js.map +1 -0
- package/lib/rtp/src/processor_v2/source/index.d.ts +2 -0
- package/lib/rtp/src/processor_v2/source/index.js +6 -0
- package/lib/rtp/src/processor_v2/source/index.js.map +1 -0
- package/lib/rtp/src/processor_v2/source/rtp.d.ts +14 -0
- package/lib/rtp/src/processor_v2/source/rtp.js +24 -0
- package/lib/rtp/src/processor_v2/source/rtp.js.map +1 -0
- package/lib/rtp/src/processor_v2/webmLive.d.ts +51 -0
- package/lib/rtp/src/processor_v2/webmLive.js +154 -0
- package/lib/rtp/src/processor_v2/webmLive.js.map +1 -0
- package/lib/rtp/src/rtcp/header.d.ts +2 -1
- package/lib/rtp/src/rtcp/header.js +3 -2
- package/lib/rtp/src/rtcp/header.js.map +1 -1
- package/lib/rtp/src/rtcp/rr.d.ts +2 -0
- package/lib/rtp/src/rtcp/rr.js.map +1 -1
- package/lib/rtp/src/rtcp/rtcp.js +4 -4
- package/lib/rtp/src/rtcp/rtcp.js.map +1 -1
- package/lib/rtp/src/rtcp/rtpfb/index.js +1 -1
- package/lib/rtp/src/rtcp/rtpfb/index.js.map +1 -1
- package/lib/rtp/src/rtcp/rtpfb/nack.js +15 -7
- package/lib/rtp/src/rtcp/rtpfb/nack.js.map +1 -1
- package/lib/rtp/src/rtp/red/packet.d.ts +1 -0
- package/lib/rtp/src/rtp/red/packet.js.map +1 -1
- package/lib/rtp/src/rtp/rtp.d.ts +1 -0
- package/lib/rtp/src/rtp/rtp.js +27 -26
- package/lib/rtp/src/rtp/rtp.js.map +1 -1
- package/lib/rtp/src/srtp/cipher/ctr.d.ts +1 -1
- package/lib/rtp/src/srtp/cipher/ctr.js +14 -20
- package/lib/rtp/src/srtp/cipher/ctr.js.map +1 -1
- package/lib/webrtc/src/dataChannel.js +1 -1
- package/lib/webrtc/src/dataChannel.js.map +1 -1
- package/lib/webrtc/src/media/extension/rtpExtension.d.ts +2 -0
- package/lib/webrtc/src/media/extension/rtpExtension.js +8 -1
- package/lib/webrtc/src/media/extension/rtpExtension.js.map +1 -1
- package/lib/webrtc/src/media/parameters.d.ts +2 -0
- package/lib/webrtc/src/media/parameters.js +1 -0
- package/lib/webrtc/src/media/parameters.js.map +1 -1
- package/lib/webrtc/src/media/receiver/nack.d.ts +10 -5
- package/lib/webrtc/src/media/receiver/nack.js +44 -27
- package/lib/webrtc/src/media/receiver/nack.js.map +1 -1
- 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/receiver/red.d.ts +1 -1
- package/lib/webrtc/src/media/receiver/red.js +14 -3
- package/lib/webrtc/src/media/receiver/red.js.map +1 -1
- package/lib/webrtc/src/media/router.d.ts +10 -3
- package/lib/webrtc/src/media/router.js +2 -0
- package/lib/webrtc/src/media/router.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.d.ts +11 -3
- package/lib/webrtc/src/media/rtpReceiver.js +42 -23
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpSender.d.ts +23 -2
- package/lib/webrtc/src/media/rtpSender.js +34 -10
- package/lib/webrtc/src/media/rtpSender.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +5 -1
- package/lib/webrtc/src/media/rtpTransceiver.js +9 -9
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/media/track.js +4 -2
- package/lib/webrtc/src/media/track.js.map +1 -1
- package/lib/webrtc/src/nonstandard/recorder/index.d.ts +5 -1
- package/lib/webrtc/src/nonstandard/recorder/index.js +2 -2
- package/lib/webrtc/src/nonstandard/recorder/index.js.map +1 -1
- package/lib/webrtc/src/nonstandard/recorder/writer/index.d.ts +1 -1
- package/lib/webrtc/src/nonstandard/recorder/writer/index.js +1 -1
- package/lib/webrtc/src/nonstandard/recorder/writer/index.js.map +1 -1
- package/lib/webrtc/src/nonstandard/recorder/writer/webm.d.ts +3 -3
- package/lib/webrtc/src/nonstandard/recorder/writer/webm.js +61 -41
- package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +13 -0
- package/lib/webrtc/src/peerConnection.js +40 -3
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sdp.d.ts +1 -0
- package/lib/webrtc/src/sdp.js +4 -0
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.js +6 -1
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.js +1 -1
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +7 -2
- package/lib/webrtc/src/utils.js +9 -3
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/dataChannel.ts +1 -1
- package/src/media/extension/rtpExtension.ts +8 -0
- package/src/media/parameters.ts +3 -0
- package/src/media/receiver/nack.ts +45 -26
- package/src/media/receiver/receiverTwcc.ts +1 -1
- package/src/media/receiver/red.ts +14 -1
- package/src/media/router.ts +5 -3
- package/src/media/rtpReceiver.ts +59 -28
- package/src/media/rtpSender.ts +38 -12
- package/src/media/rtpTransceiver.ts +10 -8
- package/src/media/track.ts +6 -2
- package/src/nonstandard/recorder/index.ts +6 -2
- package/src/nonstandard/recorder/writer/index.ts +1 -1
- package/src/nonstandard/recorder/writer/webm.ts +105 -57
- package/src/peerConnection.ts +61 -7
- package/src/sdp.ts +3 -0
- package/src/transport/dtls.ts +5 -1
- package/src/transport/sctp.ts +1 -1
- package/src/utils.ts +8 -2
|
@@ -3,22 +3,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.NackHandler = void 0;
|
|
7
|
+
const debug_1 = __importDefault(require("debug"));
|
|
7
8
|
const range_1 = __importDefault(require("lodash/range"));
|
|
8
9
|
const rx_mini_1 = __importDefault(require("rx.mini"));
|
|
9
10
|
const src_1 = require("../../../../common/src");
|
|
10
11
|
const src_2 = require("../../../../rtp/src");
|
|
12
|
+
const log = (0, debug_1.default)("werift:packages/webrtc/src/media/receiver/nack.ts");
|
|
11
13
|
const LOST_SIZE = 30 * 5;
|
|
12
|
-
class
|
|
14
|
+
class NackHandler {
|
|
13
15
|
constructor(receiver) {
|
|
14
16
|
this.receiver = receiver;
|
|
15
17
|
this.newEstSeqNum = 0;
|
|
16
|
-
this.
|
|
17
|
-
this.nackLoop = setInterval(() => this.
|
|
18
|
+
this.lost = {};
|
|
19
|
+
this.nackLoop = setInterval(() => this.sendNack(), 20);
|
|
18
20
|
this.onPacketLost = new rx_mini_1.default();
|
|
21
|
+
this.retryCount = 10;
|
|
19
22
|
}
|
|
20
|
-
get
|
|
21
|
-
return Object.keys(this.
|
|
23
|
+
get lostNumber() {
|
|
24
|
+
return Object.keys(this.lost).map(Number);
|
|
25
|
+
}
|
|
26
|
+
removeLost(sequenceNumber) {
|
|
27
|
+
delete this.lost[sequenceNumber];
|
|
22
28
|
}
|
|
23
29
|
addPacket(packet) {
|
|
24
30
|
const { sequenceNumber, ssrc } = packet.header;
|
|
@@ -27,8 +33,8 @@ class Nack {
|
|
|
27
33
|
this.newEstSeqNum = sequenceNumber;
|
|
28
34
|
return;
|
|
29
35
|
}
|
|
30
|
-
if (this.
|
|
31
|
-
|
|
36
|
+
if (this.lost[sequenceNumber]) {
|
|
37
|
+
this.removeLost(sequenceNumber);
|
|
32
38
|
return;
|
|
33
39
|
}
|
|
34
40
|
if (sequenceNumber === (0, src_1.uint16Add)(this.newEstSeqNum, 1)) {
|
|
@@ -37,45 +43,56 @@ class Nack {
|
|
|
37
43
|
else if (sequenceNumber > (0, src_1.uint16Add)(this.newEstSeqNum, 1)) {
|
|
38
44
|
// packet lost detected
|
|
39
45
|
(0, range_1.default)((0, src_1.uint16Add)(this.newEstSeqNum, 1), sequenceNumber).forEach((seq) => {
|
|
40
|
-
this.
|
|
46
|
+
this.lost[seq] = 1;
|
|
41
47
|
});
|
|
42
48
|
this.receiver.sendRtcpPLI(this.mediaSourceSsrc);
|
|
43
49
|
this.newEstSeqNum = sequenceNumber;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
this.pruneLost();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
pruneLost() {
|
|
54
|
+
if (Object.keys(this.lost).length > LOST_SIZE) {
|
|
55
|
+
this.lost = Object.entries(this.lost)
|
|
56
|
+
.slice(-LOST_SIZE)
|
|
57
|
+
.reduce((acc, [key, v]) => {
|
|
58
|
+
acc[key] = v;
|
|
59
|
+
return acc;
|
|
60
|
+
}, {});
|
|
52
61
|
}
|
|
53
62
|
}
|
|
54
63
|
close() {
|
|
55
64
|
clearInterval(this.nackLoop);
|
|
65
|
+
this.lost = {};
|
|
56
66
|
}
|
|
57
|
-
|
|
58
|
-
Object.keys(this.
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
updateRetryCount() {
|
|
68
|
+
const res = Object.keys(this.lost)
|
|
69
|
+
.map((seq) => {
|
|
70
|
+
const count = this.lost[seq]++;
|
|
71
|
+
if (count > this.retryCount) {
|
|
72
|
+
delete this.lost[seq];
|
|
73
|
+
return seq;
|
|
61
74
|
}
|
|
62
|
-
})
|
|
75
|
+
})
|
|
76
|
+
.filter((v) => v != undefined);
|
|
77
|
+
if (res.length > 0) {
|
|
78
|
+
// log("failed to retransmit", res);
|
|
79
|
+
}
|
|
63
80
|
}
|
|
64
|
-
|
|
65
|
-
if (this.
|
|
81
|
+
sendNack() {
|
|
82
|
+
if (this.lostNumber.length > 0 && this.mediaSourceSsrc) {
|
|
66
83
|
const nack = new src_2.GenericNack({
|
|
67
84
|
senderSsrc: this.receiver.rtcpSsrc,
|
|
68
85
|
mediaSourceSsrc: this.mediaSourceSsrc,
|
|
69
|
-
lost: this.
|
|
86
|
+
lost: this.lostNumber,
|
|
70
87
|
});
|
|
71
88
|
const rtcp = new src_2.RtcpTransportLayerFeedback({
|
|
72
89
|
feedback: nack,
|
|
73
90
|
});
|
|
74
91
|
this.receiver.dtlsTransport.sendRtcp([rtcp]);
|
|
75
|
-
this.
|
|
92
|
+
this.updateRetryCount();
|
|
76
93
|
this.onPacketLost.execute(nack);
|
|
77
94
|
}
|
|
78
95
|
}
|
|
79
96
|
}
|
|
80
|
-
exports.
|
|
97
|
+
exports.NackHandler = NackHandler;
|
|
81
98
|
//# sourceMappingURL=nack.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nack.js","sourceRoot":"","sources":["../../../../../src/media/receiver/nack.ts"],"names":[],"mappings":";;;;;;AAAA,yDAAiC;AACjC,sDAA4B;AAE5B,gDAAmD;AACnD,6CAI6B;AAG7B,MAAM,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC;AAEzB,MAAa,
|
|
1
|
+
{"version":3,"file":"nack.js","sourceRoot":"","sources":["../../../../../src/media/receiver/nack.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport range from \"lodash/range\";\nimport Event from \"rx.mini\";\n\nimport { uint16Add } from \"../../../../common/src\";\nimport {\n GenericNack,\n RtcpTransportLayerFeedback,\n RtpPacket,\n} from \"../../../../rtp/src\";\nimport { RTCRtpReceiver } from \"../rtpReceiver\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/receiver/nack.ts\");\n\nconst LOST_SIZE = 30 * 5;\n\nexport class NackHandler {\n private newEstSeqNum = 0;\n lost: { [seqNum: number]: number } = {};\n private nackLoop = setInterval(() => this.sendNack(), 20);\n\n readonly onPacketLost = new Event<[GenericNack]>();\n mediaSourceSsrc?: number;\n retryCount = 10;\n\n constructor(private receiver: RTCRtpReceiver) {}\n\n get lostNumber() {\n return Object.keys(this.lost).map(Number);\n }\n\n removeLost(sequenceNumber: number) {\n delete this.lost[sequenceNumber];\n }\n\n addPacket(packet: RtpPacket) {\n const { sequenceNumber, ssrc } = packet.header;\n this.mediaSourceSsrc = ssrc;\n\n if (this.newEstSeqNum === 0) {\n this.newEstSeqNum = sequenceNumber;\n return;\n }\n\n if (this.lost[sequenceNumber]) {\n this.removeLost(sequenceNumber);\n return;\n }\n\n if (sequenceNumber === uint16Add(this.newEstSeqNum, 1)) {\n this.newEstSeqNum = sequenceNumber;\n } else if (sequenceNumber > uint16Add(this.newEstSeqNum, 1)) {\n // packet lost detected\n range(uint16Add(this.newEstSeqNum, 1), sequenceNumber).forEach((seq) => {\n this.lost[seq] = 1;\n });\n this.receiver.sendRtcpPLI(this.mediaSourceSsrc);\n\n this.newEstSeqNum = sequenceNumber;\n this.pruneLost();\n }\n }\n\n private pruneLost() {\n if (Object.keys(this.lost).length > LOST_SIZE) {\n this.lost = Object.entries(this.lost)\n .slice(-LOST_SIZE)\n .reduce((acc, [key, v]) => {\n acc[key] = v;\n return acc;\n }, {} as { [seqNum: number]: number });\n }\n }\n\n close() {\n clearInterval(this.nackLoop);\n this.lost = {};\n }\n\n private updateRetryCount() {\n const res = Object.keys(this.lost)\n .map((seq) => {\n const count = this.lost[seq]++;\n if (count > this.retryCount) {\n delete this.lost[seq];\n return seq;\n }\n })\n .filter((v) => v != undefined);\n if (res.length > 0) {\n // log(\"failed to retransmit\", res);\n }\n }\n\n private sendNack() {\n if (this.lostNumber.length > 0 && this.mediaSourceSsrc) {\n const nack = new GenericNack({\n senderSsrc: this.receiver.rtcpSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n lost: this.lostNumber,\n });\n const rtcp = new RtcpTransportLayerFeedback({\n feedback: nack,\n });\n this.receiver.dtlsTransport.sendRtcp([rtcp]);\n\n this.updateRetryCount();\n this.onPacketLost.execute(nack);\n }\n }\n}\n"]}
|
|
@@ -9,7 +9,7 @@ const promises_1 = require("timers/promises");
|
|
|
9
9
|
const src_1 = require("../../../../common/src");
|
|
10
10
|
const src_2 = require("../../../../rtp/src");
|
|
11
11
|
const utils_1 = require("../../utils");
|
|
12
|
-
const log = (0, debug_1.default)("werift/webrtc/media/receiver/receiverTwcc");
|
|
12
|
+
const log = (0, debug_1.default)("werift:packages/webrtc/media/receiver/receiverTwcc");
|
|
13
13
|
class ReceiverTWCC {
|
|
14
14
|
constructor(dtlsTransport, rtcpSsrc, mediaSourceSsrc) {
|
|
15
15
|
this.dtlsTransport = dtlsTransport;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"receiverTwcc.js","sourceRoot":"","sources":["../../../../../src/media/receiver/receiverTwcc.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,8CAA6C;AAE7C,gDAAqE;AACrE,6CAO6B;AAE7B,uCAAwC;AAExC,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"receiverTwcc.js","sourceRoot":"","sources":["../../../../../src/media/receiver/receiverTwcc.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport { setTimeout } from \"timers/promises\";\n\nimport { uint8Add, uint16Add, uint24 } from \"../../../../common/src\";\nimport {\n PacketStatus,\n RecvDelta,\n RtcpTransportLayerFeedback,\n RunLengthChunk,\n StatusVectorChunk,\n TransportWideCC,\n} from \"../../../../rtp/src\";\nimport { RTCDtlsTransport } from \"../../transport/dtls\";\nimport { microTime } from \"../../utils\";\n\nconst log = debug(\"werift:packages/webrtc/media/receiver/receiverTwcc\");\n\ntype ExtensionInfo = { tsn: number; timestamp: number };\n\nexport class ReceiverTWCC {\n extensionInfo: {\n [tsn: number]: ExtensionInfo;\n } = {};\n twccRunning = false;\n /** uint8 */\n fbPktCount = 0;\n lastTimestamp?: number;\n\n constructor(\n private dtlsTransport: RTCDtlsTransport,\n private rtcpSsrc: number,\n private mediaSourceSsrc: number\n ) {\n this.runTWCC();\n }\n\n handleTWCC(transportSequenceNumber: number) {\n this.extensionInfo[transportSequenceNumber] = {\n tsn: transportSequenceNumber,\n timestamp: microTime(),\n };\n\n if (Object.keys(this.extensionInfo).length > 10) {\n this.sendTWCC();\n }\n }\n\n private async runTWCC() {\n while (this.twccRunning) {\n this.sendTWCC();\n await setTimeout(100);\n }\n }\n\n private sendTWCC() {\n if (Object.keys(this.extensionInfo).length === 0) return;\n const extensionsArr = Object.values(this.extensionInfo).sort(\n (a, b) => a.tsn - b.tsn\n );\n\n const minTSN = extensionsArr[0].tsn;\n const maxTSN = extensionsArr.slice(-1)[0].tsn;\n\n const packetChunks: (RunLengthChunk | StatusVectorChunk)[] = [];\n const baseSequenceNumber = extensionsArr[0].tsn;\n const packetStatusCount = uint16Add(maxTSN - minTSN, 1);\n /**micro sec */\n let referenceTime!: number;\n let lastPacketStatus: { status: PacketStatus; minTSN: number } | undefined;\n const recvDeltas: RecvDelta[] = [];\n\n for (let i = minTSN; i <= maxTSN; i++) {\n /**micro sec */\n const timestamp = this.extensionInfo[i]?.timestamp;\n\n if (timestamp) {\n if (!this.lastTimestamp) {\n this.lastTimestamp = timestamp;\n }\n if (!referenceTime) {\n referenceTime = this.lastTimestamp;\n }\n\n const delta = timestamp - this.lastTimestamp;\n this.lastTimestamp = timestamp;\n\n const recvDelta = new RecvDelta({\n delta: Number(delta),\n });\n recvDelta.parseDelta();\n recvDeltas.push(recvDelta);\n\n // when status changed\n if (\n lastPacketStatus != undefined &&\n lastPacketStatus.status !== recvDelta.type\n ) {\n packetChunks.push(\n new RunLengthChunk({\n packetStatus: lastPacketStatus.status,\n runLength: i - lastPacketStatus.minTSN,\n })\n );\n lastPacketStatus = { minTSN: i, status: recvDelta.type! };\n }\n // last status\n if (i === maxTSN) {\n if (lastPacketStatus != undefined) {\n packetChunks.push(\n new RunLengthChunk({\n packetStatus: lastPacketStatus.status,\n runLength: i - lastPacketStatus.minTSN + 1,\n })\n );\n } else {\n packetChunks.push(\n new RunLengthChunk({\n packetStatus: recvDelta.type,\n runLength: 1,\n })\n );\n }\n }\n\n if (lastPacketStatus == undefined) {\n lastPacketStatus = { minTSN: i, status: recvDelta.type! };\n }\n }\n }\n\n if (!referenceTime) {\n return;\n }\n\n const packet = new RtcpTransportLayerFeedback({\n feedback: new TransportWideCC({\n senderSsrc: this.rtcpSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n baseSequenceNumber,\n packetStatusCount,\n referenceTime: uint24(Math.floor(referenceTime / 1000 / 64)),\n fbPktCount: this.fbPktCount,\n recvDeltas,\n packetChunks,\n }),\n });\n\n this.dtlsTransport.sendRtcp([packet]).catch((err) => {\n log(err);\n });\n this.extensionInfo = {};\n this.fbPktCount = uint8Add(this.fbPktCount, 1);\n }\n}\n"]}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.AudioRedHandler = void 0;
|
|
4
4
|
const __1 = require("../..");
|
|
5
|
-
|
|
5
|
+
// 0 1 2 3
|
|
6
|
+
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
7
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
8
|
+
// |F| block PT | timestamp offset | block length |
|
|
9
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
10
|
+
// 0 1 2 3 4 5 6 7
|
|
11
|
+
// +-+-+-+-+-+-+-+-+
|
|
12
|
+
// |0| Block PT |
|
|
13
|
+
// +-+-+-+-+-+-+-+-+
|
|
14
|
+
class AudioRedHandler {
|
|
6
15
|
constructor() {
|
|
7
16
|
this.size = 150;
|
|
8
17
|
this.sequenceNumbers = [];
|
|
@@ -31,10 +40,12 @@ class RedHandler {
|
|
|
31
40
|
}
|
|
32
41
|
});
|
|
33
42
|
const filtered = packets.filter((p) => {
|
|
43
|
+
// duplicate
|
|
34
44
|
if (this.sequenceNumbers.includes(p.header.sequenceNumber)) {
|
|
35
45
|
return false;
|
|
36
46
|
}
|
|
37
47
|
else {
|
|
48
|
+
// buffer overflow
|
|
38
49
|
if (this.sequenceNumbers.length > this.size) {
|
|
39
50
|
this.sequenceNumbers.shift();
|
|
40
51
|
}
|
|
@@ -45,5 +56,5 @@ class RedHandler {
|
|
|
45
56
|
return filtered;
|
|
46
57
|
}
|
|
47
58
|
}
|
|
48
|
-
exports.
|
|
59
|
+
exports.AudioRedHandler = AudioRedHandler;
|
|
49
60
|
//# sourceMappingURL=red.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"red.js","sourceRoot":"","sources":["../../../../../src/media/receiver/red.ts"],"names":[],"mappings":";;;AAAA,6BAAwE;AAExE,MAAa,
|
|
1
|
+
{"version":3,"file":"red.js","sourceRoot":"","sources":["../../../../../src/media/receiver/red.ts"],"names":[],"mappings":";;;AAAA,6BAAwE;AAExE,iEAAiE;AACjE,mEAAmE;AACnE,oEAAoE;AACpE,oEAAoE;AACpE,oEAAoE;AAEpE,kBAAkB;AAClB,oBAAoB;AACpB,oBAAoB;AACpB,oBAAoB;AAEpB,MAAa,eAAe;IAA5B;QACmB,SAAI,GAAG,GAAG,CAAC;QACpB,oBAAe,GAAa,EAAE,CAAC;IAsDzC,CAAC;IApDC,IAAI,CAAC,GAAQ,EAAE,GAAc;QAC3B,MAAM,OAAO,GAAgB,EAAE,CAAC;QAEhC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;YAC5D,MAAM,cAAc,GAAG,IAAA,aAAS,EAC9B,GAAG,CAAC,MAAM,CAAC,cAAc,EACzB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAC/B,CAAC;YACF,IAAI,eAAe,EAAE;gBACnB,OAAO,CAAC,IAAI,CACV,IAAI,aAAS,CACX,IAAI,aAAS,CAAC;oBACZ,SAAS,EAAE,IAAA,aAAS,EAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,eAAe,CAAC;oBAC5D,WAAW,EAAE,OAAO;oBACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI;oBACrB,cAAc;oBACd,MAAM,EAAE,IAAI;iBACb,CAAC,EACF,KAAK,CACN,CACF,CAAC;aACH;iBAAM;gBACL,OAAO,CAAC,IAAI,CACV,IAAI,aAAS,CACX,IAAI,aAAS,CAAC;oBACZ,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS;oBAC/B,WAAW,EAAE,OAAO;oBACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI;oBACrB,cAAc;oBACd,MAAM,EAAE,IAAI;iBACb,CAAC,EACF,KAAK,CACN,CACF,CAAC;aACH;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACpC,YAAY;YACZ,IAAI,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;gBAC1D,OAAO,KAAK,CAAC;aACd;iBAAM;gBACL,kBAAkB;gBAClB,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE;oBAC3C,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;iBAC9B;gBACD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;gBACnD,OAAO,IAAI,CAAC;aACb;QACH,CAAC,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAxDD,0CAwDC","sourcesContent":["import { Red, RtpHeader, RtpPacket, uint16Add, uint32Add } from \"../..\";\n\n// 0 1 2 3\n// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |F| block PT | timestamp offset | block length |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n// 0 1 2 3 4 5 6 7\n// +-+-+-+-+-+-+-+-+\n// |0| Block PT |\n// +-+-+-+-+-+-+-+-+\n\nexport class AudioRedHandler {\n private readonly size = 150;\n private sequenceNumbers: number[] = [];\n\n push(red: Red, rtp: RtpPacket) {\n const packets: RtpPacket[] = [];\n\n red.blocks.forEach(({ blockPT, timestampOffset, block }, i) => {\n const sequenceNumber = uint16Add(\n rtp.header.sequenceNumber,\n -(red.blocks.length - (i + 1))\n );\n if (timestampOffset) {\n packets.push(\n new RtpPacket(\n new RtpHeader({\n timestamp: uint32Add(rtp.header.timestamp, -timestampOffset),\n payloadType: blockPT,\n ssrc: rtp.header.ssrc,\n sequenceNumber,\n marker: true,\n }),\n block\n )\n );\n } else {\n packets.push(\n new RtpPacket(\n new RtpHeader({\n timestamp: rtp.header.timestamp,\n payloadType: blockPT,\n ssrc: rtp.header.ssrc,\n sequenceNumber,\n marker: true,\n }),\n block\n )\n );\n }\n });\n\n const filtered = packets.filter((p) => {\n // duplicate\n if (this.sequenceNumbers.includes(p.header.sequenceNumber)) {\n return false;\n } else {\n // buffer overflow\n if (this.sequenceNumbers.length > this.size) {\n this.sequenceNumbers.shift();\n }\n this.sequenceNumbers.push(p.header.sequenceNumber);\n return true;\n }\n });\n return filtered;\n }\n}\n"]}
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import { Extension, RtcpPacket, RtpPacket } from "../../../rtp/src";
|
|
2
2
|
import { RTCRtpReceiveParameters, RTCRtpSimulcastParameters } from "./parameters";
|
|
3
|
+
import { RTCRtpReceiver } from "./rtpReceiver";
|
|
3
4
|
import { RTCRtpSender } from "./rtpSender";
|
|
4
5
|
import { RTCRtpTransceiver } from "./rtpTransceiver";
|
|
5
6
|
export declare type Extensions = {
|
|
6
7
|
[uri: string]: number | string;
|
|
7
8
|
};
|
|
8
9
|
export declare class RtpRouter {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
ssrcTable: {
|
|
11
|
+
[ssrc: number]: RTCRtpReceiver | RTCRtpSender;
|
|
12
|
+
};
|
|
13
|
+
ridTable: {
|
|
14
|
+
[rid: string]: RTCRtpReceiver | RTCRtpSender;
|
|
15
|
+
};
|
|
16
|
+
extIdUriMap: {
|
|
17
|
+
[id: number]: string;
|
|
18
|
+
};
|
|
12
19
|
constructor();
|
|
13
20
|
registerRtpSender(sender: RTCRtpSender): void;
|
|
14
21
|
private registerRtpReceiver;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/media/router.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport { bufferReader } from \"../../../common/src\";\nimport {\n Extension,\n ReceiverEstimatedMaxBitrate,\n RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpRrPacket,\n RtcpSourceDescriptionPacket,\n RtcpSrPacket,\n RtcpTransportLayerFeedback,\n RtpPacket,\n} from \"../../../rtp/src\";\nimport { RTP_EXTENSION_URI } from \"./extension/rtpExtension\";\nimport {\n RTCRtpReceiveParameters,\n RTCRtpSimulcastParameters,\n} from \"./parameters\";\nimport { RTCRtpReceiver } from \"./rtpReceiver\";\nimport { RTCRtpSender } from \"./rtpSender\";\nimport { RTCRtpTransceiver } from \"./rtpTransceiver\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/router.ts\");\n\nexport type Extensions = { [uri: string]: number | string };\n\nexport class RtpRouter {\n private ssrcTable: { [ssrc: number]: RTCRtpReceiver | RTCRtpSender } = {};\n private ridTable: { [rid: string]: RTCRtpReceiver | RTCRtpSender } = {};\n private extIdUriMap: { [id: number]: string } = {};\n\n constructor() {}\n\n registerRtpSender(sender: RTCRtpSender) {\n this.ssrcTable[sender.ssrc] = sender;\n }\n\n private registerRtpReceiver(receiver: RTCRtpReceiver, ssrc: number) {\n this.ssrcTable[ssrc] = receiver;\n }\n\n registerRtpReceiverBySsrc(\n transceiver: RTCRtpTransceiver,\n params: RTCRtpReceiveParameters\n ) {\n log(\"registerRtpReceiverBySsrc\", params);\n\n params.encodings\n .filter((e) => e.ssrc != undefined) // todo fix\n .forEach((encode, i) => {\n this.registerRtpReceiver(transceiver.receiver, encode.ssrc);\n transceiver.addTrack(\n new MediaStreamTrack({\n ssrc: encode.ssrc,\n kind: transceiver.kind,\n id: transceiver.sender.trackId,\n remote: true,\n codec: params.codecs[i],\n })\n );\n if (encode.rtx) {\n this.registerRtpReceiver(transceiver.receiver, encode.rtx.ssrc);\n }\n });\n\n params.headerExtensions.forEach((extension) => {\n this.extIdUriMap[extension.id] = extension.uri;\n });\n }\n\n registerRtpReceiverByRid(\n transceiver: RTCRtpTransceiver,\n param: RTCRtpSimulcastParameters,\n params: RTCRtpReceiveParameters\n ) {\n // サイマルキャスト利用時のRTXをサポートしていないのでcodecs/encodingsは常に一つ\n const [codec] = params.codecs;\n\n log(\"registerRtpReceiverByRid\", param);\n transceiver.addTrack(\n new MediaStreamTrack({\n rid: param.rid,\n kind: transceiver.kind,\n id: transceiver.sender.trackId,\n remote: true,\n codec,\n })\n );\n this.ridTable[param.rid] = transceiver.receiver;\n }\n\n static rtpHeaderExtensionsParser(\n extensions: Extension[],\n extIdUriMap: { [id: number]: string }\n ): Extensions {\n return extensions\n .map((extension) => {\n const uri = extIdUriMap[extension.id];\n switch (uri) {\n case RTP_EXTENSION_URI.sdesMid:\n case RTP_EXTENSION_URI.sdesRTPStreamID:\n case RTP_EXTENSION_URI.repairedRtpStreamId:\n return { uri, value: extension.payload.toString() };\n case RTP_EXTENSION_URI.transportWideCC:\n return { uri, value: extension.payload.readUInt16BE() };\n case RTP_EXTENSION_URI.absSendTime:\n return {\n uri,\n value: bufferReader(extension.payload, [3])[0],\n };\n }\n })\n .reduce((acc: { [uri: string]: any }, cur) => {\n if (cur) acc[cur.uri] = cur.value;\n return acc;\n }, {});\n }\n\n routeRtp = (packet: RtpPacket) => {\n const extensions = RtpRouter.rtpHeaderExtensionsParser(\n packet.header.extensions,\n this.extIdUriMap\n );\n\n let ssrcReceiver: RTCRtpReceiver | undefined = this.ssrcTable[\n packet.header.ssrc\n ] as RTCRtpReceiver;\n\n const rid = extensions[RTP_EXTENSION_URI.sdesRTPStreamID];\n if (typeof rid === \"string\") {\n ssrcReceiver = this.ridTable[rid] as RTCRtpReceiver;\n ssrcReceiver.latestRid = rid;\n ssrcReceiver.handleRtpByRid(packet, rid, extensions);\n } else if (ssrcReceiver) {\n ssrcReceiver.handleRtpBySsrc(packet, extensions);\n } else {\n // simulcast after send receiver report\n ssrcReceiver = Object.values(this.ridTable)\n .filter((r): r is RTCRtpReceiver => r instanceof RTCRtpReceiver)\n .find((r) => r.trackBySSRC[packet.header.ssrc]);\n if (ssrcReceiver) {\n log(\"simulcast register receiver by ssrc\", packet.header.ssrc);\n this.registerRtpReceiver(ssrcReceiver, packet.header.ssrc);\n ssrcReceiver.handleRtpBySsrc(packet, extensions);\n }\n }\n\n if (!ssrcReceiver) {\n log(\"ssrcReceiver not found\");\n return;\n }\n\n const sdesMid = extensions[RTP_EXTENSION_URI.sdesMid];\n if (typeof sdesMid === \"string\") {\n ssrcReceiver.sdesMid = sdesMid;\n }\n\n const repairedRid = extensions[\n RTP_EXTENSION_URI.repairedRtpStreamId\n ] as string;\n if (typeof repairedRid === \"string\") {\n ssrcReceiver.latestRepairedRid = repairedRid;\n }\n };\n\n routeRtcp = (packet: RtcpPacket) => {\n const recipients: (RTCRtpReceiver | RTCRtpSender)[] = [];\n\n switch (packet.type) {\n case RtcpSrPacket.type:\n {\n packet = packet as RtcpSrPacket;\n recipients.push(this.ssrcTable[packet.ssrc]);\n }\n break;\n case RtcpRrPacket.type:\n {\n packet = packet as RtcpRrPacket;\n packet.reports.forEach((report) => {\n recipients.push(this.ssrcTable[report.ssrc]);\n });\n }\n break;\n case RtcpSourceDescriptionPacket.type:\n {\n const sdes = packet as RtcpSourceDescriptionPacket;\n // log(\"sdes\", JSON.stringify(sdes.chunks));\n }\n break;\n case RtcpTransportLayerFeedback.type:\n {\n const rtpfb = packet as RtcpTransportLayerFeedback;\n if (rtpfb.feedback) {\n recipients.push(this.ssrcTable[rtpfb.feedback.mediaSourceSsrc]);\n }\n }\n break;\n case RtcpPayloadSpecificFeedback.type:\n {\n const psfb = packet as RtcpPayloadSpecificFeedback;\n switch (psfb.feedback.count) {\n case ReceiverEstimatedMaxBitrate.count:\n const remb = psfb.feedback as ReceiverEstimatedMaxBitrate;\n recipients.push(this.ssrcTable[remb.ssrcFeedbacks[0]]);\n break;\n default:\n recipients.push(this.ssrcTable[psfb.feedback.senderSsrc]);\n }\n }\n break;\n }\n recipients\n .filter((v) => v) // todo simulcast\n .forEach((recipient) => recipient.handleRtcpPacket(packet));\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/media/router.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport { bufferReader } from \"../../../common/src\";\nimport {\n Extension,\n ReceiverEstimatedMaxBitrate,\n RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpRrPacket,\n RtcpSourceDescriptionPacket,\n RtcpSrPacket,\n RtcpTransportLayerFeedback,\n RtpPacket,\n} from \"../../../rtp/src\";\nimport { RTP_EXTENSION_URI } from \"./extension/rtpExtension\";\nimport {\n RTCRtpReceiveParameters,\n RTCRtpSimulcastParameters,\n} from \"./parameters\";\nimport { RTCRtpReceiver } from \"./rtpReceiver\";\nimport { RTCRtpSender } from \"./rtpSender\";\nimport { RTCRtpTransceiver } from \"./rtpTransceiver\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/router.ts\");\n\nexport type Extensions = { [uri: string]: number | string };\n\nexport class RtpRouter {\n ssrcTable: { [ssrc: number]: RTCRtpReceiver | RTCRtpSender } = {};\n ridTable: { [rid: string]: RTCRtpReceiver | RTCRtpSender } = {};\n extIdUriMap: { [id: number]: string } = {};\n\n constructor() {}\n\n registerRtpSender(sender: RTCRtpSender) {\n this.ssrcTable[sender.ssrc] = sender;\n }\n\n private registerRtpReceiver(receiver: RTCRtpReceiver, ssrc: number) {\n this.ssrcTable[ssrc] = receiver;\n }\n\n registerRtpReceiverBySsrc(\n transceiver: RTCRtpTransceiver,\n params: RTCRtpReceiveParameters\n ) {\n log(\"registerRtpReceiverBySsrc\", params);\n\n params.encodings\n .filter((e) => e.ssrc != undefined) // todo fix\n .forEach((encode, i) => {\n this.registerRtpReceiver(transceiver.receiver, encode.ssrc);\n transceiver.addTrack(\n new MediaStreamTrack({\n ssrc: encode.ssrc,\n kind: transceiver.kind,\n id: transceiver.sender.trackId,\n remote: true,\n codec: params.codecs[i],\n })\n );\n if (encode.rtx) {\n this.registerRtpReceiver(transceiver.receiver, encode.rtx.ssrc);\n }\n });\n\n params.headerExtensions.forEach((extension) => {\n this.extIdUriMap[extension.id] = extension.uri;\n });\n }\n\n registerRtpReceiverByRid(\n transceiver: RTCRtpTransceiver,\n param: RTCRtpSimulcastParameters,\n params: RTCRtpReceiveParameters\n ) {\n // サイマルキャスト利用時のRTXをサポートしていないのでcodecs/encodingsは常に一つ\n const [codec] = params.codecs;\n\n log(\"registerRtpReceiverByRid\", param);\n transceiver.addTrack(\n new MediaStreamTrack({\n rid: param.rid,\n kind: transceiver.kind,\n id: transceiver.sender.trackId,\n remote: true,\n codec,\n })\n );\n this.ridTable[param.rid] = transceiver.receiver;\n }\n\n static rtpHeaderExtensionsParser(\n extensions: Extension[],\n extIdUriMap: { [id: number]: string }\n ): Extensions {\n return extensions\n .map((extension) => {\n const uri = extIdUriMap[extension.id];\n switch (uri) {\n case RTP_EXTENSION_URI.sdesMid:\n case RTP_EXTENSION_URI.sdesRTPStreamID:\n case RTP_EXTENSION_URI.repairedRtpStreamId:\n return { uri, value: extension.payload.toString() };\n case RTP_EXTENSION_URI.transportWideCC:\n return { uri, value: extension.payload.readUInt16BE() };\n case RTP_EXTENSION_URI.absSendTime:\n return {\n uri,\n value: bufferReader(extension.payload, [3])[0],\n };\n default:\n return { uri, value: 0 };\n }\n })\n .reduce((acc: { [uri: string]: any }, cur) => {\n if (cur) acc[cur.uri] = cur.value;\n return acc;\n }, {});\n }\n\n routeRtp = (packet: RtpPacket) => {\n const extensions = RtpRouter.rtpHeaderExtensionsParser(\n packet.header.extensions,\n this.extIdUriMap\n );\n\n let ssrcReceiver: RTCRtpReceiver | undefined = this.ssrcTable[\n packet.header.ssrc\n ] as RTCRtpReceiver;\n\n const rid = extensions[RTP_EXTENSION_URI.sdesRTPStreamID];\n if (typeof rid === \"string\") {\n ssrcReceiver = this.ridTable[rid] as RTCRtpReceiver;\n ssrcReceiver.latestRid = rid;\n ssrcReceiver.handleRtpByRid(packet, rid, extensions);\n } else if (ssrcReceiver) {\n ssrcReceiver.handleRtpBySsrc(packet, extensions);\n } else {\n // simulcast after send receiver report\n ssrcReceiver = Object.values(this.ridTable)\n .filter((r): r is RTCRtpReceiver => r instanceof RTCRtpReceiver)\n .find((r) => r.trackBySSRC[packet.header.ssrc]);\n if (ssrcReceiver) {\n log(\"simulcast register receiver by ssrc\", packet.header.ssrc);\n this.registerRtpReceiver(ssrcReceiver, packet.header.ssrc);\n ssrcReceiver.handleRtpBySsrc(packet, extensions);\n }\n }\n\n if (!ssrcReceiver) {\n log(\"ssrcReceiver not found\");\n return;\n }\n\n const sdesMid = extensions[RTP_EXTENSION_URI.sdesMid];\n if (typeof sdesMid === \"string\") {\n ssrcReceiver.sdesMid = sdesMid;\n }\n\n const repairedRid = extensions[\n RTP_EXTENSION_URI.repairedRtpStreamId\n ] as string;\n if (typeof repairedRid === \"string\") {\n ssrcReceiver.latestRepairedRid = repairedRid;\n }\n };\n\n routeRtcp = (packet: RtcpPacket) => {\n const recipients: (RTCRtpReceiver | RTCRtpSender)[] = [];\n\n switch (packet.type) {\n case RtcpSrPacket.type:\n {\n packet = packet as RtcpSrPacket;\n recipients.push(this.ssrcTable[packet.ssrc]);\n }\n break;\n case RtcpRrPacket.type:\n {\n packet = packet as RtcpRrPacket;\n packet.reports.forEach((report) => {\n recipients.push(this.ssrcTable[report.ssrc]);\n });\n }\n break;\n case RtcpSourceDescriptionPacket.type:\n {\n const sdes = packet as RtcpSourceDescriptionPacket;\n // log(\"sdes\", JSON.stringify(sdes.chunks));\n }\n break;\n case RtcpTransportLayerFeedback.type:\n {\n const rtpfb = packet as RtcpTransportLayerFeedback;\n if (rtpfb.feedback) {\n recipients.push(this.ssrcTable[rtpfb.feedback.mediaSourceSsrc]);\n }\n }\n break;\n case RtcpPayloadSpecificFeedback.type:\n {\n const psfb = packet as RtcpPayloadSpecificFeedback;\n switch (psfb.feedback.count) {\n case ReceiverEstimatedMaxBitrate.count:\n const remb = psfb.feedback as ReceiverEstimatedMaxBitrate;\n recipients.push(this.ssrcTable[remb.ssrcFeedbacks[0]]);\n break;\n default:\n recipients.push(this.ssrcTable[psfb.feedback.senderSsrc]);\n }\n }\n break;\n }\n recipients\n .filter((v) => v) // todo simulcast\n .forEach((recipient) => recipient.handleRtcpPacket(packet));\n };\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Event from "rx.mini";
|
|
2
2
|
import { RtcpPacket, RtpPacket } from "../../../rtp/src";
|
|
3
|
+
import { PeerConfig } from "..";
|
|
3
4
|
import { RTCDtlsTransport } from "../transport/dtls";
|
|
4
5
|
import { Kind } from "../types/domain";
|
|
5
6
|
import { RTCRtpReceiveParameters } from "./parameters";
|
|
@@ -7,9 +8,11 @@ import { ReceiverTWCC } from "./receiver/receiverTwcc";
|
|
|
7
8
|
import { Extensions } from "./router";
|
|
8
9
|
import { MediaStreamTrack } from "./track";
|
|
9
10
|
export declare class RTCRtpReceiver {
|
|
11
|
+
readonly config: PeerConfig;
|
|
10
12
|
kind: Kind;
|
|
11
13
|
rtcpSsrc: number;
|
|
12
14
|
private readonly codecs;
|
|
15
|
+
private get codecArray();
|
|
13
16
|
private readonly ssrcByRtx;
|
|
14
17
|
private readonly nack;
|
|
15
18
|
private readonly redHandler;
|
|
@@ -22,10 +25,14 @@ export declare class RTCRtpReceiver {
|
|
|
22
25
|
readonly trackByRID: {
|
|
23
26
|
[rid: string]: MediaStreamTrack;
|
|
24
27
|
};
|
|
25
|
-
|
|
28
|
+
/**last sender Report Timestamp
|
|
29
|
+
* compactNtp
|
|
30
|
+
*/
|
|
31
|
+
readonly lastSRtimestamp: {
|
|
26
32
|
[ssrc: number]: number;
|
|
27
33
|
};
|
|
28
|
-
|
|
34
|
+
/**seconds */
|
|
35
|
+
readonly receiveLastSRTimestamp: {
|
|
29
36
|
[ssrc: number]: number;
|
|
30
37
|
};
|
|
31
38
|
readonly onPacketLost: Event<[import("..").GenericNack]>;
|
|
@@ -42,9 +49,10 @@ export declare class RTCRtpReceiver {
|
|
|
42
49
|
rtcpRunning: boolean;
|
|
43
50
|
private rtcpCancel;
|
|
44
51
|
private remoteStreams;
|
|
45
|
-
constructor(kind: Kind, rtcpSsrc: number);
|
|
52
|
+
constructor(config: PeerConfig, kind: Kind, rtcpSsrc: number);
|
|
46
53
|
setDtlsTransport(dtls: RTCDtlsTransport): void;
|
|
47
54
|
get track(): MediaStreamTrack;
|
|
55
|
+
get nackEnabled(): import("./parameters").RTCPFB | undefined;
|
|
48
56
|
prepareReceive(params: RTCRtpReceiveParameters): void;
|
|
49
57
|
/**
|
|
50
58
|
* setup TWCC if supported
|
|
@@ -20,21 +20,25 @@ const red_1 = require("./receiver/red");
|
|
|
20
20
|
const statistics_1 = require("./receiver/statistics");
|
|
21
21
|
const log = (0, debug_1.debug)("werift:packages/webrtc/src/media/rtpReceiver.ts");
|
|
22
22
|
class RTCRtpReceiver {
|
|
23
|
-
constructor(kind, rtcpSsrc) {
|
|
23
|
+
constructor(config, kind, rtcpSsrc) {
|
|
24
|
+
this.config = config;
|
|
24
25
|
this.kind = kind;
|
|
25
26
|
this.rtcpSsrc = rtcpSsrc;
|
|
26
27
|
this.codecs = {};
|
|
27
28
|
this.ssrcByRtx = {};
|
|
28
|
-
this.nack = new nack_1.
|
|
29
|
-
this.redHandler = new red_1.
|
|
29
|
+
this.nack = new nack_1.NackHandler(this);
|
|
30
|
+
this.redHandler = new red_1.AudioRedHandler();
|
|
30
31
|
this.type = "receiver";
|
|
31
32
|
this.uuid = (0, uuid_1.v4)();
|
|
32
33
|
this.tracks = [];
|
|
33
34
|
this.trackBySSRC = {};
|
|
34
35
|
this.trackByRID = {};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
/**last sender Report Timestamp
|
|
37
|
+
* compactNtp
|
|
38
|
+
*/
|
|
39
|
+
this.lastSRtimestamp = {};
|
|
40
|
+
/**seconds */
|
|
41
|
+
this.receiveLastSRTimestamp = {};
|
|
38
42
|
this.onPacketLost = this.nack.onPacketLost;
|
|
39
43
|
this.onRtcp = new rx_mini_1.default();
|
|
40
44
|
this.supportTWCC = false;
|
|
@@ -54,6 +58,9 @@ class RTCRtpReceiver {
|
|
|
54
58
|
this.handleRTP(packet, extensions, track);
|
|
55
59
|
};
|
|
56
60
|
}
|
|
61
|
+
get codecArray() {
|
|
62
|
+
return Object.values(this.codecs).sort((a, b) => a.payloadType - b.payloadType);
|
|
63
|
+
}
|
|
57
64
|
setDtlsTransport(dtls) {
|
|
58
65
|
this.dtlsTransport = dtls;
|
|
59
66
|
}
|
|
@@ -61,6 +68,9 @@ class RTCRtpReceiver {
|
|
|
61
68
|
get track() {
|
|
62
69
|
return this.tracks[0];
|
|
63
70
|
}
|
|
71
|
+
get nackEnabled() {
|
|
72
|
+
return this.codecArray[0].rtcpFeedback.find((f) => f.type === "nack");
|
|
73
|
+
}
|
|
64
74
|
prepareReceive(params) {
|
|
65
75
|
params.codecs.forEach((c) => {
|
|
66
76
|
this.codecs[c.payloadType] = c;
|
|
@@ -115,12 +125,12 @@ class RTCRtpReceiver {
|
|
|
115
125
|
signal: this.rtcpCancel.signal,
|
|
116
126
|
});
|
|
117
127
|
const reports = Object.entries(this.remoteStreams).map(([ssrc, stream]) => {
|
|
118
|
-
let
|
|
119
|
-
if (this.
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
if (
|
|
123
|
-
|
|
128
|
+
let lastSRtimestamp = 0, delaySinceLastSR = 0;
|
|
129
|
+
if (this.lastSRtimestamp[ssrc]) {
|
|
130
|
+
lastSRtimestamp = this.lastSRtimestamp[ssrc];
|
|
131
|
+
const delaySeconds = (0, utils_1.timestampSeconds)() - this.receiveLastSRTimestamp[ssrc];
|
|
132
|
+
if (delaySeconds > 0 && delaySeconds < 65536) {
|
|
133
|
+
delaySinceLastSR = (0, src_1.int)(delaySeconds * 65536);
|
|
124
134
|
}
|
|
125
135
|
}
|
|
126
136
|
return new src_2.RtcpReceiverInfo({
|
|
@@ -129,12 +139,15 @@ class RTCRtpReceiver {
|
|
|
129
139
|
packetsLost: stream.packets_lost,
|
|
130
140
|
highestSequence: stream.max_seq,
|
|
131
141
|
jitter: stream.jitter,
|
|
132
|
-
lsr,
|
|
133
|
-
dlsr,
|
|
142
|
+
lsr: lastSRtimestamp,
|
|
143
|
+
dlsr: delaySinceLastSR,
|
|
134
144
|
});
|
|
135
145
|
});
|
|
136
146
|
const packet = new src_2.RtcpRrPacket({ ssrc: this.rtcpSsrc, reports });
|
|
137
147
|
try {
|
|
148
|
+
if (this.config.debug.receiverReportDelay) {
|
|
149
|
+
await (0, promises_1.setTimeout)(this.config.debug.receiverReportDelay);
|
|
150
|
+
}
|
|
138
151
|
await this.dtlsTransport.sendRtcp([packet]);
|
|
139
152
|
}
|
|
140
153
|
catch (error) {
|
|
@@ -166,8 +179,8 @@ class RTCRtpReceiver {
|
|
|
166
179
|
case src_2.RtcpSrPacket.type:
|
|
167
180
|
{
|
|
168
181
|
const sr = packet;
|
|
169
|
-
this.
|
|
170
|
-
this.
|
|
182
|
+
this.lastSRtimestamp[sr.ssrc] = (0, utils_1.compactNtp)(sr.senderInfo.ntpTimestamp);
|
|
183
|
+
this.receiveLastSRTimestamp[sr.ssrc] = (0, utils_1.timestampSeconds)();
|
|
171
184
|
const track = this.trackBySSRC[packet.ssrc];
|
|
172
185
|
if (track) {
|
|
173
186
|
track.onReceiveRtcp.execute(packet);
|
|
@@ -211,16 +224,22 @@ class RTCRtpReceiver {
|
|
|
211
224
|
let red;
|
|
212
225
|
if (codec.name.toLowerCase() === "red") {
|
|
213
226
|
red = src_2.Red.deSerialize(packet.payload);
|
|
227
|
+
if (!Object.keys(this.codecs).includes(red.header.fields[0].blockPT.toString())) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
214
230
|
}
|
|
215
|
-
|
|
216
|
-
if (track?.kind === "video") {
|
|
231
|
+
if (track?.kind === "video" && this.nackEnabled) {
|
|
217
232
|
this.nack.addPacket(packet);
|
|
218
233
|
}
|
|
219
234
|
if (track) {
|
|
220
235
|
if (red) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
236
|
+
if (track.kind === "audio") {
|
|
237
|
+
const payloads = this.redHandler.push(red, packet);
|
|
238
|
+
for (const packet of payloads) {
|
|
239
|
+
track.onReceiveRtp.execute(packet.clone());
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
224
243
|
}
|
|
225
244
|
}
|
|
226
245
|
else {
|
|
@@ -235,10 +254,10 @@ function unwrapRtx(rtx, payloadType, ssrc) {
|
|
|
235
254
|
const packet = new src_2.RtpPacket(new src_2.RtpHeader({
|
|
236
255
|
payloadType,
|
|
237
256
|
marker: rtx.header.marker,
|
|
238
|
-
sequenceNumber: jspack_1.jspack.Unpack("!H", rtx.payload.
|
|
257
|
+
sequenceNumber: jspack_1.jspack.Unpack("!H", rtx.payload.subarray(0, 2))[0],
|
|
239
258
|
timestamp: rtx.header.timestamp,
|
|
240
259
|
ssrc,
|
|
241
|
-
}), rtx.payload.
|
|
260
|
+
}), rtx.payload.subarray(2));
|
|
242
261
|
return packet;
|
|
243
262
|
}
|
|
244
263
|
exports.unwrapRtx = unwrapRtx;
|