werift 0.23.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/lib/common/src/binary.js +2 -3
- package/lib/common/src/binary.js.map +1 -1
- package/lib/common/src/transport.d.ts +22 -9
- package/lib/common/src/transport.js +152 -25
- package/lib/common/src/transport.js.map +1 -1
- package/lib/ice/src/candidate.d.ts +16 -1
- package/lib/ice/src/candidate.js +99 -15
- package/lib/ice/src/candidate.js.map +1 -1
- package/lib/ice/src/ice.d.ts +2 -0
- package/lib/ice/src/ice.js +175 -50
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/iceBase.d.ts +23 -2
- package/lib/ice/src/iceBase.js +63 -1
- package/lib/ice/src/iceBase.js.map +1 -1
- package/lib/ice/src/index.d.ts +2 -0
- package/lib/ice/src/index.js +2 -0
- package/lib/ice/src/index.js.map +1 -1
- package/lib/ice/src/internal/selectAddresses.d.ts +9 -0
- package/lib/ice/src/internal/selectAddresses.js +40 -0
- package/lib/ice/src/internal/selectAddresses.js.map +1 -0
- package/lib/ice/src/stun/const.d.ts +1 -26
- package/lib/ice/src/stun/const.js +15 -54
- package/lib/ice/src/stun/const.js.map +1 -1
- package/lib/ice/src/stun/message.d.ts +1 -25
- package/lib/ice/src/stun/message.js +15 -149
- package/lib/ice/src/stun/message.js.map +1 -1
- package/lib/ice/src/stun/protocol.d.ts +1 -1
- package/lib/ice/src/stun/protocol.js +2 -2
- package/lib/ice/src/stun/protocol.js.map +1 -1
- package/lib/ice/src/stun/tcpFrame.d.ts +5 -0
- package/lib/ice/src/stun/tcpFrame.js +26 -0
- package/lib/ice/src/stun/tcpFrame.js.map +1 -0
- package/lib/ice/src/stun/tcpProtocol.d.ts +51 -0
- package/lib/ice/src/stun/tcpProtocol.js +326 -0
- package/lib/ice/src/stun/tcpProtocol.js.map +1 -0
- package/lib/ice/src/stun/transaction.d.ts +2 -1
- package/lib/ice/src/stun/transaction.js +9 -3
- package/lib/ice/src/stun/transaction.js.map +1 -1
- package/lib/ice/src/turn/frame.d.ts +1 -0
- package/lib/ice/src/turn/frame.js +18 -0
- package/lib/ice/src/turn/frame.js.map +1 -0
- package/lib/ice/src/turn/protocol.d.ts +9 -7
- package/lib/ice/src/turn/protocol.js +32 -44
- package/lib/ice/src/turn/protocol.js.map +1 -1
- package/lib/ice/src/types/model.d.ts +1 -1
- package/lib/ice/src/types/model.js.map +1 -1
- package/lib/ice/src/utils.js +2 -31
- package/lib/ice/src/utils.js.map +1 -1
- package/lib/{ice → ice-server}/src/stun/attributes.d.ts +12 -5
- package/lib/{ice → ice-server}/src/stun/attributes.js +69 -66
- package/lib/ice-server/src/stun/attributes.js.map +1 -0
- package/lib/ice-server/src/stun/const.d.ts +28 -0
- package/lib/ice-server/src/stun/const.js +88 -0
- package/lib/ice-server/src/stun/const.js.map +1 -0
- package/lib/ice-server/src/stun/ip.d.ts +12 -0
- package/lib/ice-server/src/stun/ip.js +88 -0
- package/lib/ice-server/src/stun/ip.js.map +1 -0
- package/lib/ice-server/src/stun/message.d.ts +37 -0
- package/lib/ice-server/src/stun/message.js +190 -0
- package/lib/ice-server/src/stun/message.js.map +1 -0
- package/lib/ice-server/src/turn/auth.d.ts +1 -0
- package/lib/ice-server/src/turn/auth.js +10 -0
- package/lib/ice-server/src/turn/auth.js.map +1 -0
- package/lib/ice-server/src/turn/frame.d.ts +13 -0
- package/lib/ice-server/src/turn/frame.js +69 -0
- package/lib/ice-server/src/turn/frame.js.map +1 -0
- package/lib/index.mjs +2866 -946
- package/lib/nonstandard/index.mjs +1872 -455
- package/lib/rtp/src/codec/av1.js +11 -5
- package/lib/rtp/src/codec/av1.js.map +1 -1
- package/lib/rtp/src/codec/leb128.d.ts +5 -0
- package/lib/rtp/src/codec/leb128.js +24 -0
- package/lib/rtp/src/codec/leb128.js.map +1 -0
- package/lib/rtp/src/extra/container/mp4/container.d.ts +9 -6
- package/lib/rtp/src/extra/container/mp4/container.js +258 -173
- package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
- package/lib/rtp/src/extra/container/mp4/h264.d.ts +1 -0
- package/lib/rtp/src/extra/container/mp4/h264.js +13 -0
- package/lib/rtp/src/extra/container/mp4/h264.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4.d.ts +11 -7
- package/lib/rtp/src/extra/processor/mp4.js +115 -60
- package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4Callback.d.ts +2 -3
- package/lib/rtp/src/extra/processor/mp4Callback.js +5 -3
- package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
- package/lib/rtp/src/rtp/rtx.js +4 -6
- package/lib/rtp/src/rtp/rtx.js.map +1 -1
- package/lib/rtp/src/srtp/context/context.d.ts +2 -0
- package/lib/rtp/src/srtp/context/context.js +12 -12
- package/lib/rtp/src/srtp/context/context.js.map +1 -1
- package/lib/sctp/src/param.js +31 -15
- package/lib/sctp/src/param.js.map +1 -1
- package/lib/sctp/src/sctp.js +10 -9
- package/lib/sctp/src/sctp.js.map +1 -1
- package/lib/webrtc/src/dataChannel.d.ts +3 -2
- package/lib/webrtc/src/dataChannel.js +9 -2
- package/lib/webrtc/src/dataChannel.js.map +1 -1
- package/lib/webrtc/src/errors.d.ts +3 -0
- package/lib/webrtc/src/errors.js +11 -0
- package/lib/webrtc/src/errors.js.map +1 -0
- package/lib/webrtc/src/helper.d.ts +5 -1
- package/lib/webrtc/src/helper.js +33 -1
- package/lib/webrtc/src/helper.js.map +1 -1
- package/lib/webrtc/src/media/receiver/statistics.d.ts +4 -1
- package/lib/webrtc/src/media/receiver/statistics.js +22 -0
- package/lib/webrtc/src/media/receiver/statistics.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.d.ts +15 -2
- package/lib/webrtc/src/media/rtpReceiver.js +135 -20
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpSender.d.ts +32 -7
- package/lib/webrtc/src/media/rtpSender.js +179 -31
- package/lib/webrtc/src/media/rtpSender.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +13 -4
- package/lib/webrtc/src/media/rtpTransceiver.js +26 -5
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/media/stats.d.ts +15 -1
- package/lib/webrtc/src/media/stats.js +55 -1
- package/lib/webrtc/src/media/stats.js.map +1 -1
- package/lib/webrtc/src/media/track.d.ts +2 -1
- package/lib/webrtc/src/media/track.js +7 -1
- package/lib/webrtc/src/media/track.js.map +1 -1
- package/lib/webrtc/src/nonstandard/dummyMedia.d.ts +19 -0
- package/lib/webrtc/src/nonstandard/dummyMedia.js +157 -0
- package/lib/webrtc/src/nonstandard/dummyMedia.js.map +1 -0
- package/lib/webrtc/src/nonstandard/navigator.d.ts +18 -8
- package/lib/webrtc/src/nonstandard/navigator.js +96 -32
- package/lib/webrtc/src/nonstandard/navigator.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.d.ts +16 -0
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.js +360 -0
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.js.map +1 -0
- package/lib/webrtc/src/nonstandard/userMedia.d.ts +71 -31
- package/lib/webrtc/src/nonstandard/userMedia.js +454 -108
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +183 -50
- package/lib/webrtc/src/peerConnection.js +458 -109
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sctpManager.d.ts +1 -1
- package/lib/webrtc/src/sctpManager.js +27 -7
- package/lib/webrtc/src/sctpManager.js.map +1 -1
- package/lib/webrtc/src/sdp.d.ts +10 -7
- package/lib/webrtc/src/sdp.js +40 -44
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/sdpManager.d.ts +4 -3
- package/lib/webrtc/src/sdpManager.js +50 -27
- package/lib/webrtc/src/sdpManager.js.map +1 -1
- package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
- package/lib/webrtc/src/secureTransportManager.js +100 -22
- package/lib/webrtc/src/secureTransportManager.js.map +1 -1
- package/lib/webrtc/src/transceiverManager.d.ts +5 -4
- package/lib/webrtc/src/transceiverManager.js +61 -62
- package/lib/webrtc/src/transceiverManager.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.d.ts +15 -4
- package/lib/webrtc/src/transport/dtls.js +91 -23
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/lib/webrtc/src/transport/ice.d.ts +21 -3
- package/lib/webrtc/src/transport/ice.js +159 -30
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.d.ts +1 -0
- package/lib/webrtc/src/transport/sctp.js +26 -22
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +12 -4
- package/lib/webrtc/src/utils.js +118 -16
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +7 -10
- package/lib/ice/src/stun/attributes.js.map +0 -1
- package/lib/rtp/src/extra/container/mp4/mp4box.d.ts +0 -5
- package/lib/rtp/src/extra/container/mp4/mp4box.js +0 -32
- package/lib/rtp/src/extra/container/mp4/mp4box.js.map +0 -1
package/lib/webrtc/src/helper.js
CHANGED
|
@@ -57,7 +57,11 @@ class EventTarget extends node_events_1.EventEmitter {
|
|
|
57
57
|
enumerable: true,
|
|
58
58
|
configurable: true,
|
|
59
59
|
writable: true,
|
|
60
|
-
value: (type, listener) => {
|
|
60
|
+
value: (type, listener, options) => {
|
|
61
|
+
if (typeof options === "object" && options?.once) {
|
|
62
|
+
this.once(type, listener);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
61
65
|
this.addListener(type, listener);
|
|
62
66
|
}
|
|
63
67
|
});
|
|
@@ -69,6 +73,34 @@ class EventTarget extends node_events_1.EventEmitter {
|
|
|
69
73
|
this.removeListener(type, listener);
|
|
70
74
|
}
|
|
71
75
|
});
|
|
76
|
+
Object.defineProperty(this, "dispatchEvent", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
configurable: true,
|
|
79
|
+
writable: true,
|
|
80
|
+
value: (event) => this.emit(event.type, event)
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
emit(type, ...args) {
|
|
84
|
+
if (typeof type !== "string") {
|
|
85
|
+
return super.emit(type, ...args);
|
|
86
|
+
}
|
|
87
|
+
if (args.length === 0) {
|
|
88
|
+
return super.emit(type, new Event(type));
|
|
89
|
+
}
|
|
90
|
+
const [event, ...rest] = args;
|
|
91
|
+
if (event && typeof event === "object" && !("type" in event)) {
|
|
92
|
+
try {
|
|
93
|
+
Object.defineProperty(event, "type", {
|
|
94
|
+
configurable: true,
|
|
95
|
+
enumerable: true,
|
|
96
|
+
value: type,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return super.emit(type, { type, ...event }, ...rest);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return super.emit(type, event, ...rest);
|
|
72
104
|
}
|
|
73
105
|
}
|
|
74
106
|
exports.EventTarget = EventTarget;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../../../src/helper.ts"],"names":[],"mappings":";;;AAEA,8BAEC;AAED,wBAGC;AATD,6CAA2C;AAE3C,SAAgB,SAAS,CAAI,GAAQ;IACnC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,SAAgB,MAAM,CAAC,IAAY,EAAE,KAAa;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,MAAa,YAAY;IAAzB;QACE;;;;mBAA6D,EAAE;WAAC;QAChE;;;;mBAAU,KAAK;WAAC;QAEhB;;;;mBAAO,CAAC,OAA2B,EAAE,EAAE,CACrC,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE;gBACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;gBACtC,IAAI,CAAC,IAAI,CAAC,OAAO;oBAAE,IAAI,CAAC,GAAG,EAAE,CAAC;YAChC,CAAC,CAAC;WAAC;IAcP,CAAC;IAZS,KAAK,CAAC,GAAG;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,EAAE,CAAC;YAEZ,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;CACF;AAtBD,oCAsBC;AAED,MAAa,WAAY,SAAQ,0BAAY;IAA7C;;
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../../../src/helper.ts"],"names":[],"mappings":";;;AAEA,8BAEC;AAED,wBAGC;AATD,6CAA2C;AAE3C,SAAgB,SAAS,CAAI,GAAQ;IACnC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,SAAgB,MAAM,CAAC,IAAY,EAAE,KAAa;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,MAAa,YAAY;IAAzB;QACE;;;;mBAA6D,EAAE;WAAC;QAChE;;;;mBAAU,KAAK;WAAC;QAEhB;;;;mBAAO,CAAC,OAA2B,EAAE,EAAE,CACrC,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE;gBACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;gBACtC,IAAI,CAAC,IAAI,CAAC,OAAO;oBAAE,IAAI,CAAC,GAAG,EAAE,CAAC;YAChC,CAAC,CAAC;WAAC;IAcP,CAAC;IAZS,KAAK,CAAC,GAAG;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,EAAE,CAAC;YAEZ,IAAI,CAAC,GAAG,EAAE,CAAC;QACb,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;CACF;AAtBD,oCAsBC;AAED,MAAa,WAAY,SAAQ,0BAAY;IAA7C;;QA0BE;;;;mBAAmB,CACjB,IAAY,EACZ,QAAkC,EAClC,OAAsC,EACtC,EAAE;gBACF,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;oBACjD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;oBAC1B,OAAO;gBACT,CAAC;gBACD,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACnC,CAAC;WAAC;QAEF;;;;mBAAsB,CAAC,IAAY,EAAE,QAAkC,EAAE,EAAE;gBACzE,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACtC,CAAC;WAAC;QAEF;;;;mBAAgB,CAAC,KAAY,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;WAAC;IACjE,CAAC;IA1CU,IAAI,CAAC,IAAqB,EAAE,GAAG,IAAW;QACjD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;QAC9B,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC;YAC7D,IAAI,CAAC;gBACH,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE;oBACnC,YAAY,EAAE,IAAI;oBAClB,UAAU,EAAE,IAAI;oBAChB,KAAK,EAAE,IAAI;iBACZ,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,CAAC;CAmBF;AA3CD,kCA2CC","sourcesContent":["import { EventEmitter } from \"node:events\";\n\nexport function enumerate<T>(arr: T[]): [number, T][] {\n return arr.map((v, i) => [i, v]);\n}\n\nexport function divide(from: string, split: string): [string, string] {\n const arr = from.split(split);\n return [arr[0], arr.slice(1).join(split)];\n}\n\nexport class PromiseQueue {\n queue: { promise: () => Promise<any>; done: () => void }[] = [];\n running = false;\n\n push = (promise: () => Promise<any>) =>\n new Promise<void>((r) => {\n this.queue.push({ promise, done: r });\n if (!this.running) this.run();\n });\n\n private async run() {\n const task = this.queue.shift();\n if (task) {\n this.running = true;\n await task.promise();\n task.done();\n\n this.run();\n } else {\n this.running = false;\n }\n }\n}\n\nexport class EventTarget extends EventEmitter {\n override emit(type: string | symbol, ...args: any[]) {\n if (typeof type !== \"string\") {\n return super.emit(type, ...args);\n }\n\n if (args.length === 0) {\n return super.emit(type, new Event(type));\n }\n\n const [event, ...rest] = args;\n if (event && typeof event === \"object\" && !(\"type\" in event)) {\n try {\n Object.defineProperty(event, \"type\", {\n configurable: true,\n enumerable: true,\n value: type,\n });\n } catch {\n return super.emit(type, { type, ...event }, ...rest);\n }\n }\n\n return super.emit(type, event, ...rest);\n }\n\n addEventListener = (\n type: string,\n listener: (...args: any[]) => void,\n options?: boolean | { once?: boolean },\n ) => {\n if (typeof options === \"object\" && options?.once) {\n this.once(type, listener);\n return;\n }\n this.addListener(type, listener);\n };\n\n removeEventListener = (type: string, listener: (...args: any[]) => void) => {\n this.removeListener(type, listener);\n };\n\n dispatchEvent = (event: Event) => this.emit(event.type, event);\n}\n"]}
|
|
@@ -4,7 +4,10 @@ export declare class StreamStatistics {
|
|
|
4
4
|
max_seq?: number;
|
|
5
5
|
cycles: number;
|
|
6
6
|
packets_received: number;
|
|
7
|
-
|
|
7
|
+
bytesReceived: number;
|
|
8
|
+
headerBytesReceived: number;
|
|
9
|
+
lastPacketReceivedTimestamp?: number;
|
|
10
|
+
readonly clockRate: number;
|
|
8
11
|
jitter_q4: number;
|
|
9
12
|
private last_arrival?;
|
|
10
13
|
private last_timestamp?;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StreamStatistics = void 0;
|
|
4
4
|
const common_1 = require("../../imports/common");
|
|
5
|
+
const stats_1 = require("../stats");
|
|
5
6
|
// from aiortc
|
|
6
7
|
class StreamStatistics {
|
|
7
8
|
constructor(clockRate) {
|
|
@@ -29,6 +30,24 @@ class StreamStatistics {
|
|
|
29
30
|
writable: true,
|
|
30
31
|
value: 0
|
|
31
32
|
});
|
|
33
|
+
Object.defineProperty(this, "bytesReceived", {
|
|
34
|
+
enumerable: true,
|
|
35
|
+
configurable: true,
|
|
36
|
+
writable: true,
|
|
37
|
+
value: 0
|
|
38
|
+
});
|
|
39
|
+
Object.defineProperty(this, "headerBytesReceived", {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
configurable: true,
|
|
42
|
+
writable: true,
|
|
43
|
+
value: 0
|
|
44
|
+
});
|
|
45
|
+
Object.defineProperty(this, "lastPacketReceivedTimestamp", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
configurable: true,
|
|
48
|
+
writable: true,
|
|
49
|
+
value: void 0
|
|
50
|
+
});
|
|
32
51
|
// # jitter
|
|
33
52
|
Object.defineProperty(this, "clockRate", {
|
|
34
53
|
enumerable: true,
|
|
@@ -73,6 +92,9 @@ class StreamStatistics {
|
|
|
73
92
|
const inOrder = this.max_seq == undefined ||
|
|
74
93
|
(0, common_1.uint16Gt)(packet.header.sequenceNumber, this.max_seq);
|
|
75
94
|
this.packets_received++;
|
|
95
|
+
this.bytesReceived += packet.payload.length;
|
|
96
|
+
this.headerBytesReceived += packet.header.serializeSize;
|
|
97
|
+
this.lastPacketReceivedTimestamp = (0, stats_1.getStatsTimestamp)();
|
|
76
98
|
if (this.base_seq == undefined) {
|
|
77
99
|
this.base_seq = packet.header.sequenceNumber;
|
|
78
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statistics.js","sourceRoot":"","sources":["../../../../../src/media/receiver/statistics.ts"],"names":[],"mappings":";;;AAAA,iDAAqD;
|
|
1
|
+
{"version":3,"file":"statistics.js","sourceRoot":"","sources":["../../../../../src/media/receiver/statistics.ts"],"names":[],"mappings":"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","sourcesContent":["import { int, uint16Gt } from \"../../imports/common\";\nimport type { RtpPacket } from \"../../imports/rtp\";\nimport { getStatsTimestamp } from \"../stats\";\n\n// from aiortc\n\nexport class StreamStatistics {\n base_seq?: number;\n max_seq?: number;\n cycles = 0;\n packets_received = 0;\n bytesReceived = 0;\n headerBytesReceived = 0;\n lastPacketReceivedTimestamp?: number;\n\n // # jitter\n readonly clockRate: number;\n jitter_q4 = 0;\n private last_arrival?: number;\n private last_timestamp?: number;\n\n // # fraction lost\n expected_prior = 0;\n received_prior = 0;\n\n constructor(clockRate: number) {\n this.clockRate = clockRate;\n }\n\n add(packet: RtpPacket, now: number = Date.now() / 1000) {\n const inOrder =\n this.max_seq == undefined ||\n uint16Gt(packet.header.sequenceNumber, this.max_seq);\n this.packets_received++;\n this.bytesReceived += packet.payload.length;\n this.headerBytesReceived += packet.header.serializeSize;\n this.lastPacketReceivedTimestamp = getStatsTimestamp();\n\n if (this.base_seq == undefined) {\n this.base_seq = packet.header.sequenceNumber;\n }\n\n if (inOrder) {\n const arrival = int(now * this.clockRate);\n\n if (\n this.max_seq != undefined &&\n packet.header.sequenceNumber < this.max_seq\n ) {\n this.cycles += 1 << 16;\n }\n this.max_seq = packet.header.sequenceNumber;\n\n if (\n packet.header.timestamp !== this.last_timestamp &&\n this.packets_received > 1\n ) {\n const diff = Math.abs(\n arrival -\n (this.last_arrival ?? 0) -\n (packet.header.timestamp - (this.last_timestamp ?? 0)),\n );\n this.jitter_q4 += diff - ((this.jitter_q4 + 8) >> 4);\n }\n\n this.last_arrival = arrival;\n this.last_timestamp = packet.header.timestamp;\n }\n }\n\n get fraction_lost() {\n const expected_interval = this.packets_expected - this.expected_prior;\n this.expected_prior = this.packets_expected;\n const received_interval = this.packets_received - this.received_prior;\n this.received_prior = this.packets_received;\n const lost_interval = expected_interval - received_interval;\n if (expected_interval == 0 || lost_interval <= 0) {\n return 0;\n } else {\n return Math.floor((lost_interval << 8) / expected_interval);\n }\n }\n\n get jitter() {\n return this.jitter_q4 >> 4;\n }\n\n get packets_expected() {\n return this.cycles + (this.max_seq ?? 0) - (this.base_seq ?? 0) + 1;\n }\n\n get packets_lost() {\n const lost = this.packets_expected - this.packets_received;\n return lost < 0 ? 0 : lost;\n }\n}\n"]}
|
|
@@ -5,13 +5,14 @@ import type { RTCDtlsTransport } from "../transport/dtls";
|
|
|
5
5
|
import type { Kind } from "../types/domain";
|
|
6
6
|
import type { RTCRtpReceiveParameters } from "./parameters";
|
|
7
7
|
import { ReceiverTWCC } from "./receiver/receiverTwcc";
|
|
8
|
-
import { type RTCStats } from "./stats";
|
|
8
|
+
import { type RTCStats, type RTCStatsReport } from "./stats";
|
|
9
9
|
import { MediaStreamTrack } from "./track";
|
|
10
10
|
export declare class RTCRtpReceiver {
|
|
11
11
|
readonly config: PeerConfig;
|
|
12
12
|
kind: Kind;
|
|
13
13
|
rtcpSsrc: number;
|
|
14
14
|
private readonly codecs;
|
|
15
|
+
private readonly defaultTrack;
|
|
15
16
|
private get codecArray();
|
|
16
17
|
private readonly ssrcByRtx;
|
|
17
18
|
private readonly nack;
|
|
@@ -44,11 +45,19 @@ export declare class RTCRtpReceiver {
|
|
|
44
45
|
receiverTWCC?: ReceiverTWCC;
|
|
45
46
|
stopped: boolean;
|
|
46
47
|
remoteStreamId?: string;
|
|
48
|
+
remoteStreamIds: string[];
|
|
47
49
|
remoteTrackId?: string;
|
|
48
50
|
rtcpRunning: boolean;
|
|
49
51
|
private rtcpCancel;
|
|
50
52
|
private remoteStreams;
|
|
53
|
+
private senderReportsReceivedBySsrc;
|
|
54
|
+
private remoteTimestampsBySsrc;
|
|
55
|
+
private remotePacketCountBySsrc;
|
|
56
|
+
private remoteOctetCountBySsrc;
|
|
57
|
+
private nackCountBySsrc;
|
|
58
|
+
private pliCountBySsrc;
|
|
51
59
|
constructor(config: PeerConfig, kind: Kind, rtcpSsrc: number);
|
|
60
|
+
get transport(): RTCDtlsTransport;
|
|
52
61
|
setDtlsTransport(dtls: RTCDtlsTransport): void;
|
|
53
62
|
get track(): MediaStreamTrack;
|
|
54
63
|
get nackEnabled(): import("./parameters").RTCPFB | undefined;
|
|
@@ -62,7 +71,11 @@ export declare class RTCRtpReceiver {
|
|
|
62
71
|
addTrack(track: MediaStreamTrack): boolean;
|
|
63
72
|
stop(): void;
|
|
64
73
|
runRtcp(): Promise<void>;
|
|
65
|
-
|
|
74
|
+
private getInboundRtpStatsId;
|
|
75
|
+
private getRemoteOutboundRtpStatsId;
|
|
76
|
+
getStatsRootIds(selector?: MediaStreamTrack): string[];
|
|
77
|
+
collectStats(timestamp: number): RTCStats[];
|
|
78
|
+
getStats(): Promise<RTCStatsReport>;
|
|
66
79
|
sendRtcpPLI(mediaSsrc: number): Promise<void>;
|
|
67
80
|
handleRtcpPacket(packet: RtcpPacket): void;
|
|
68
81
|
handleRtpBySsrc: (packet: RtpPacket, extensions: Extensions) => void;
|
|
@@ -43,6 +43,12 @@ class RTCRtpReceiver {
|
|
|
43
43
|
writable: true,
|
|
44
44
|
value: {}
|
|
45
45
|
});
|
|
46
|
+
Object.defineProperty(this, "defaultTrack", {
|
|
47
|
+
enumerable: true,
|
|
48
|
+
configurable: true,
|
|
49
|
+
writable: true,
|
|
50
|
+
value: void 0
|
|
51
|
+
});
|
|
46
52
|
Object.defineProperty(this, "ssrcByRtx", {
|
|
47
53
|
enumerable: true,
|
|
48
54
|
configurable: true,
|
|
@@ -161,6 +167,12 @@ class RTCRtpReceiver {
|
|
|
161
167
|
writable: true,
|
|
162
168
|
value: void 0
|
|
163
169
|
});
|
|
170
|
+
Object.defineProperty(this, "remoteStreamIds", {
|
|
171
|
+
enumerable: true,
|
|
172
|
+
configurable: true,
|
|
173
|
+
writable: true,
|
|
174
|
+
value: []
|
|
175
|
+
});
|
|
164
176
|
Object.defineProperty(this, "remoteTrackId", {
|
|
165
177
|
enumerable: true,
|
|
166
178
|
configurable: true,
|
|
@@ -185,6 +197,42 @@ class RTCRtpReceiver {
|
|
|
185
197
|
writable: true,
|
|
186
198
|
value: {}
|
|
187
199
|
});
|
|
200
|
+
Object.defineProperty(this, "senderReportsReceivedBySsrc", {
|
|
201
|
+
enumerable: true,
|
|
202
|
+
configurable: true,
|
|
203
|
+
writable: true,
|
|
204
|
+
value: {}
|
|
205
|
+
});
|
|
206
|
+
Object.defineProperty(this, "remoteTimestampsBySsrc", {
|
|
207
|
+
enumerable: true,
|
|
208
|
+
configurable: true,
|
|
209
|
+
writable: true,
|
|
210
|
+
value: {}
|
|
211
|
+
});
|
|
212
|
+
Object.defineProperty(this, "remotePacketCountBySsrc", {
|
|
213
|
+
enumerable: true,
|
|
214
|
+
configurable: true,
|
|
215
|
+
writable: true,
|
|
216
|
+
value: {}
|
|
217
|
+
});
|
|
218
|
+
Object.defineProperty(this, "remoteOctetCountBySsrc", {
|
|
219
|
+
enumerable: true,
|
|
220
|
+
configurable: true,
|
|
221
|
+
writable: true,
|
|
222
|
+
value: {}
|
|
223
|
+
});
|
|
224
|
+
Object.defineProperty(this, "nackCountBySsrc", {
|
|
225
|
+
enumerable: true,
|
|
226
|
+
configurable: true,
|
|
227
|
+
writable: true,
|
|
228
|
+
value: {}
|
|
229
|
+
});
|
|
230
|
+
Object.defineProperty(this, "pliCountBySsrc", {
|
|
231
|
+
enumerable: true,
|
|
232
|
+
configurable: true,
|
|
233
|
+
writable: true,
|
|
234
|
+
value: {}
|
|
235
|
+
});
|
|
188
236
|
Object.defineProperty(this, "handleRtpBySsrc", {
|
|
189
237
|
enumerable: true,
|
|
190
238
|
configurable: true,
|
|
@@ -206,13 +254,21 @@ class RTCRtpReceiver {
|
|
|
206
254
|
this.handleRTP(packet, extensions, track);
|
|
207
255
|
}
|
|
208
256
|
});
|
|
257
|
+
this.defaultTrack = new track_1.MediaStreamTrack({ kind, remote: true });
|
|
258
|
+
this.onPacketLost.subscribe((nack) => {
|
|
259
|
+
this.nackCountBySsrc[nack.mediaSourceSsrc] =
|
|
260
|
+
(this.nackCountBySsrc[nack.mediaSourceSsrc] ?? 0) + 1;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
get transport() {
|
|
264
|
+
return this.dtlsTransport ?? null;
|
|
209
265
|
}
|
|
210
266
|
setDtlsTransport(dtls) {
|
|
211
267
|
this.dtlsTransport = dtls;
|
|
212
268
|
}
|
|
213
269
|
// todo fix
|
|
214
270
|
get track() {
|
|
215
|
-
return this.tracks[0] ??
|
|
271
|
+
return this.tracks[0] ?? this.defaultTrack;
|
|
216
272
|
}
|
|
217
273
|
get nackEnabled() {
|
|
218
274
|
return this.codecArray[0]?.rtcpFeedback.find((f) => f.type === "nack");
|
|
@@ -313,56 +369,108 @@ class RTCRtpReceiver {
|
|
|
313
369
|
}
|
|
314
370
|
catch (error) { }
|
|
315
371
|
}
|
|
316
|
-
|
|
317
|
-
|
|
372
|
+
getInboundRtpStatsId(track) {
|
|
373
|
+
return (0, stats_1.generateStatsId)("inbound-rtp", track.id ?? track.uuid);
|
|
374
|
+
}
|
|
375
|
+
getRemoteOutboundRtpStatsId(track) {
|
|
376
|
+
return (0, stats_1.generateStatsId)("remote-outbound-rtp", track.id ?? track.uuid);
|
|
377
|
+
}
|
|
378
|
+
getStatsRootIds(selector) {
|
|
379
|
+
return this.tracks
|
|
380
|
+
.filter((track) => (!selector ? true : track === selector))
|
|
381
|
+
.filter((track) => track.ssrc)
|
|
382
|
+
.map((track) => this.getInboundRtpStatsId(track));
|
|
383
|
+
}
|
|
384
|
+
collectStats(timestamp) {
|
|
318
385
|
const stats = [];
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const
|
|
386
|
+
const transportId = this.dtlsTransport
|
|
387
|
+
? (0, stats_1.generateStatsId)("transport", this.dtlsTransport.id)
|
|
388
|
+
: undefined;
|
|
389
|
+
const activeCodec = this.codecArray[0];
|
|
390
|
+
const emittedCodecIds = new Set();
|
|
323
391
|
// Collect stats for each track
|
|
324
392
|
for (const track of this.tracks) {
|
|
325
393
|
if (!track.ssrc)
|
|
326
394
|
continue;
|
|
327
395
|
const streamStats = this.remoteStreams[track.ssrc];
|
|
328
|
-
if (!streamStats)
|
|
329
|
-
continue;
|
|
330
396
|
// Inbound RTP stats
|
|
397
|
+
const hasRemoteTimestamp = this.remoteTimestampsBySsrc[track.ssrc] !== undefined;
|
|
398
|
+
const remoteId = this.lastSRtimestamp[track.ssrc] !== undefined || hasRemoteTimestamp
|
|
399
|
+
? this.getRemoteOutboundRtpStatsId(track)
|
|
400
|
+
: undefined;
|
|
401
|
+
const codecId = activeCodec && transportId
|
|
402
|
+
? (0, stats_1.generateCodecStatsId)(transportId, activeCodec.payloadType, track.id ?? track.uuid)
|
|
403
|
+
: undefined;
|
|
404
|
+
if (activeCodec &&
|
|
405
|
+
transportId &&
|
|
406
|
+
codecId &&
|
|
407
|
+
!emittedCodecIds.has(codecId)) {
|
|
408
|
+
emittedCodecIds.add(codecId);
|
|
409
|
+
const codecStats = {
|
|
410
|
+
type: "codec",
|
|
411
|
+
id: codecId,
|
|
412
|
+
timestamp,
|
|
413
|
+
payloadType: activeCodec.payloadType,
|
|
414
|
+
transportId,
|
|
415
|
+
mimeType: activeCodec.mimeType,
|
|
416
|
+
clockRate: activeCodec.clockRate,
|
|
417
|
+
channels: activeCodec.channels,
|
|
418
|
+
sdpFmtpLine: activeCodec.parameters,
|
|
419
|
+
};
|
|
420
|
+
stats.push(codecStats);
|
|
421
|
+
}
|
|
331
422
|
const inboundRtpStats = {
|
|
332
423
|
type: "inbound-rtp",
|
|
333
|
-
id:
|
|
424
|
+
id: this.getInboundRtpStatsId(track),
|
|
334
425
|
timestamp,
|
|
335
426
|
ssrc: track.ssrc,
|
|
336
427
|
kind: this.kind,
|
|
337
428
|
transportId,
|
|
338
|
-
codecId
|
|
339
|
-
? (0, stats_1.generateStatsId)("codec", this.codecs[0].payloadType, transportId)
|
|
340
|
-
: undefined,
|
|
429
|
+
codecId,
|
|
341
430
|
mid: this.sdesMid,
|
|
342
|
-
trackIdentifier: track.id,
|
|
343
|
-
packetsReceived: streamStats
|
|
344
|
-
|
|
345
|
-
|
|
431
|
+
trackIdentifier: track.id ?? track.uuid,
|
|
432
|
+
packetsReceived: streamStats?.packets_received ?? 0,
|
|
433
|
+
bytesReceived: streamStats?.bytesReceived ?? 0,
|
|
434
|
+
headerBytesReceived: streamStats?.headerBytesReceived ?? 0,
|
|
435
|
+
packetsLost: streamStats?.packets_lost ?? 0,
|
|
436
|
+
jitter: streamStats?.clockRate
|
|
437
|
+
? streamStats.jitter / streamStats.clockRate
|
|
438
|
+
: undefined,
|
|
439
|
+
lastPacketReceivedTimestamp: streamStats?.lastPacketReceivedTimestamp,
|
|
440
|
+
remoteId,
|
|
441
|
+
nackCount: this.nackCountBySsrc[track.ssrc] || undefined,
|
|
442
|
+
pliCount: this.pliCountBySsrc[track.ssrc] || undefined,
|
|
346
443
|
};
|
|
347
444
|
stats.push(inboundRtpStats);
|
|
348
445
|
// Remote outbound RTP stats (if we have SR info)
|
|
349
|
-
if (
|
|
446
|
+
if (remoteId) {
|
|
350
447
|
const remoteOutboundStats = {
|
|
351
448
|
type: "remote-outbound-rtp",
|
|
352
|
-
id:
|
|
449
|
+
id: this.getRemoteOutboundRtpStatsId(track),
|
|
353
450
|
timestamp,
|
|
354
451
|
ssrc: track.ssrc,
|
|
355
452
|
kind: this.kind,
|
|
356
453
|
transportId,
|
|
357
454
|
codecId: inboundRtpStats.codecId,
|
|
358
455
|
localId: inboundRtpStats.id,
|
|
359
|
-
remoteTimestamp: this.
|
|
456
|
+
remoteTimestamp: this.remoteTimestampsBySsrc[track.ssrc],
|
|
457
|
+
reportsSent: this.senderReportsReceivedBySsrc[track.ssrc] ?? 0,
|
|
458
|
+
packetsSent: this.remotePacketCountBySsrc[track.ssrc],
|
|
459
|
+
bytesSent: this.remoteOctetCountBySsrc[track.ssrc],
|
|
360
460
|
};
|
|
361
461
|
stats.push(remoteOutboundStats);
|
|
362
462
|
}
|
|
363
463
|
}
|
|
364
464
|
return stats;
|
|
365
465
|
}
|
|
466
|
+
async getStats() {
|
|
467
|
+
const timestamp = (0, stats_1.getStatsTimestamp)();
|
|
468
|
+
const stats = this.collectStats(timestamp);
|
|
469
|
+
if (this.dtlsTransport) {
|
|
470
|
+
stats.push(...(await this.dtlsTransport.getStats(timestamp)));
|
|
471
|
+
}
|
|
472
|
+
return (0, stats_1.buildStatsReport)(stats, this.getStatsRootIds());
|
|
473
|
+
}
|
|
366
474
|
async sendRtcpPLI(mediaSsrc) {
|
|
367
475
|
if (!this.pliEnabled) {
|
|
368
476
|
log("pli not supported", { mediaSsrc });
|
|
@@ -379,6 +487,8 @@ class RTCRtpReceiver {
|
|
|
379
487
|
}),
|
|
380
488
|
});
|
|
381
489
|
try {
|
|
490
|
+
this.pliCountBySsrc[mediaSsrc] =
|
|
491
|
+
(this.pliCountBySsrc[mediaSsrc] ?? 0) + 1;
|
|
382
492
|
await this.dtlsTransport.sendRtcp([packet]);
|
|
383
493
|
}
|
|
384
494
|
catch (error) {
|
|
@@ -392,6 +502,11 @@ class RTCRtpReceiver {
|
|
|
392
502
|
const sr = packet;
|
|
393
503
|
this.lastSRtimestamp[sr.ssrc] = (0, utils_1.compactNtp)(sr.senderInfo.ntpTimestamp);
|
|
394
504
|
this.receiveLastSRTimestamp[sr.ssrc] = (0, utils_1.timestampSeconds)();
|
|
505
|
+
this.senderReportsReceivedBySsrc[sr.ssrc] =
|
|
506
|
+
(this.senderReportsReceivedBySsrc[sr.ssrc] ?? 0) + 1;
|
|
507
|
+
this.remoteTimestampsBySsrc[sr.ssrc] = (0, utils_1.ntpTimeToEpochMs)(sr.senderInfo.ntpTimestamp);
|
|
508
|
+
this.remotePacketCountBySsrc[sr.ssrc] = sr.senderInfo.packetCount;
|
|
509
|
+
this.remoteOctetCountBySsrc[sr.ssrc] = sr.senderInfo.octetCount;
|
|
395
510
|
const track = this.trackBySSRC[packet.ssrc];
|
|
396
511
|
if (track) {
|
|
397
512
|
track.onReceiveRtcp.execute(packet);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rtpReceiver.js","sourceRoot":"","sources":["../../../../src/media/rtpReceiver.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"crypto\";\nimport { setTimeout } from \"timers/promises\";\nimport { Event, int } from \"../imports/common\";\n\nimport {\n type Extensions,\n PictureLossIndication,\n RTP_EXTENSION_URI,\n Red,\n RedHandler,\n type RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpReceiverInfo,\n RtcpRrPacket,\n RtcpSrPacket,\n type RtpPacket,\n type TransportWideCCPayload,\n debug,\n unwrapRtx,\n} from \"../imports/rtp\";\nimport type { PeerConfig } from \"../peerConnection\";\nimport type { RTCDtlsTransport } from \"../transport/dtls\";\nimport type { Kind } from \"../types/domain\";\nimport { compactNtp, timestampSeconds } from \"../utils\";\nimport type {\n RTCRtpCodecParameters,\n RTCRtpReceiveParameters,\n} from \"./parameters\";\nimport { NackHandler } from \"./receiver/nack\";\nimport { ReceiverTWCC } from \"./receiver/receiverTwcc\";\nimport { StreamStatistics } from \"./receiver/statistics\";\n\nimport { codecParametersFromString } from \"../sdp\";\nimport { usePLI, useTWCC } from \"./extension/rtcpFeedback\";\nimport {\n type RTCInboundRtpStreamStats,\n type RTCRemoteOutboundRtpStreamStats,\n type RTCStats,\n generateStatsId,\n getStatsTimestamp,\n} from \"./stats\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/rtpReceiver.ts\");\n\nexport class RTCRtpReceiver {\n private readonly codecs: { [pt: number]: RTCRtpCodecParameters } = {};\n private get codecArray() {\n return Object.values(this.codecs).sort(\n (a, b) => a.payloadType - b.payloadType,\n );\n }\n private readonly ssrcByRtx: { [rtxSsrc: number]: number } = {};\n private readonly nack = new NackHandler(this);\n private readonly audioRedHandler = new RedHandler();\n\n readonly type = \"receiver\";\n readonly uuid = randomUUID().toString();\n readonly tracks: MediaStreamTrack[] = [];\n readonly trackBySSRC: { [ssrc: string]: MediaStreamTrack } = {};\n readonly trackByRID: { [rid: string]: MediaStreamTrack } = {};\n /**last sender Report Timestamp\n * compactNtp\n */\n readonly lastSRtimestamp: { [ssrc: number]: number } = {};\n /**seconds */\n readonly receiveLastSRTimestamp: { [ssrc: number]: number } = {};\n readonly onPacketLost = this.nack.onPacketLost;\n readonly onRtcp = new Event<[RtcpPacket]>();\n\n dtlsTransport!: RTCDtlsTransport;\n sdesMid?: string;\n latestRid?: string;\n latestRepairedRid?: string;\n\n receiverTWCC?: ReceiverTWCC;\n stopped = false;\n remoteStreamId?: string;\n remoteTrackId?: string;\n\n rtcpRunning = false;\n private rtcpCancel = new AbortController();\n private remoteStreams: { [ssrc: number]: StreamStatistics } = {};\n\n constructor(\n readonly config: PeerConfig,\n public kind: Kind,\n public rtcpSsrc: number,\n ) {}\n\n setDtlsTransport(dtls: RTCDtlsTransport) {\n this.dtlsTransport = dtls;\n }\n\n // todo fix\n get track() {\n return this.tracks[0] ?? new MediaStreamTrack({ kind: this.kind });\n }\n\n get nackEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find((f) => f.type === \"nack\");\n }\n\n get twccEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find(\n (f) => f.type === useTWCC().type,\n );\n }\n\n get pliEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find(\n (f) => f.type === usePLI().type,\n );\n }\n\n prepareReceive(params: RTCRtpReceiveParameters) {\n params.codecs.forEach((c) => {\n this.codecs[c.payloadType] = c;\n });\n params.encodings.forEach((e) => {\n if (e.rtx) {\n this.ssrcByRtx[e.rtx.ssrc] = e.ssrc;\n }\n });\n }\n\n /**\n * setup TWCC if supported\n */\n setupTWCC(mediaSourceSsrc: number) {\n if (this.twccEnabled && !this.receiverTWCC) {\n this.receiverTWCC = new ReceiverTWCC(\n this.dtlsTransport,\n this.rtcpSsrc,\n mediaSourceSsrc,\n );\n }\n }\n\n addTrack(track: MediaStreamTrack) {\n const exist = this.tracks.find((t) => {\n if (t.rid) {\n return t.rid === track.rid;\n }\n if (t.ssrc) {\n return t.ssrc === track.ssrc;\n }\n });\n if (exist) {\n return false;\n }\n this.tracks.push(track);\n if (track.ssrc) {\n this.trackBySSRC[track.ssrc] = track;\n }\n if (track.rid) {\n this.trackByRID[track.rid] = track;\n }\n return true;\n }\n\n stop() {\n this.stopped = true;\n this.rtcpRunning = false;\n this.rtcpCancel.abort();\n\n if (this.receiverTWCC) this.receiverTWCC.twccRunning = false;\n this.nack.close();\n }\n\n async runRtcp() {\n if (this.rtcpRunning || this.stopped) return;\n this.rtcpRunning = true;\n\n try {\n while (this.rtcpRunning) {\n await setTimeout(500 + Math.random() * 1000, undefined, {\n signal: this.rtcpCancel.signal,\n });\n\n const reports = Object.entries(this.remoteStreams).map(\n ([ssrc, stream]) => {\n let lastSRtimestamp = 0,\n delaySinceLastSR = 0;\n if (this.lastSRtimestamp[ssrc]) {\n lastSRtimestamp = this.lastSRtimestamp[ssrc];\n const delaySeconds =\n timestampSeconds() - this.receiveLastSRTimestamp[ssrc];\n if (delaySeconds > 0 && delaySeconds < 65536) {\n delaySinceLastSR = int(delaySeconds * 65536);\n }\n }\n\n return new RtcpReceiverInfo({\n ssrc: Number(ssrc),\n fractionLost: stream.fraction_lost,\n packetsLost: stream.packets_lost,\n highestSequence: stream.max_seq,\n jitter: stream.jitter,\n lsr: lastSRtimestamp,\n dlsr: delaySinceLastSR,\n });\n },\n );\n\n const packet = new RtcpRrPacket({ ssrc: this.rtcpSsrc, reports });\n\n try {\n if (this.config.debug.receiverReportDelay) {\n await setTimeout(this.config.debug.receiverReportDelay);\n }\n await this.dtlsTransport.sendRtcp([packet]);\n } catch (error) {\n log(\"sendRtcp failed\", error);\n await setTimeout(500 + Math.random() * 1000);\n }\n }\n } catch (error) {}\n }\n\n async getStats(): Promise<RTCStats[]> {\n const timestamp = getStatsTimestamp();\n const stats: RTCStats[] = [];\n\n if (!this.dtlsTransport) {\n return stats;\n }\n\n const transportId = generateStatsId(\"transport\", this.dtlsTransport.id);\n\n // Collect stats for each track\n for (const track of this.tracks) {\n if (!track.ssrc) continue;\n\n const streamStats = this.remoteStreams[track.ssrc];\n if (!streamStats) continue;\n\n // Inbound RTP stats\n const inboundRtpStats: RTCInboundRtpStreamStats = {\n type: \"inbound-rtp\",\n id: generateStatsId(\"inbound-rtp\", track.ssrc),\n timestamp,\n ssrc: track.ssrc,\n kind: this.kind,\n transportId,\n codecId: this.codecs[0]\n ? generateStatsId(\"codec\", this.codecs[0].payloadType, transportId)\n : undefined,\n mid: this.sdesMid,\n trackIdentifier: track.id,\n packetsReceived: streamStats.packets_received,\n packetsLost: streamStats.packets_lost,\n jitter: streamStats.jitter,\n };\n stats.push(inboundRtpStats);\n\n // Remote outbound RTP stats (if we have SR info)\n if (this.lastSRtimestamp[track.ssrc]) {\n const remoteOutboundStats: RTCRemoteOutboundRtpStreamStats = {\n type: \"remote-outbound-rtp\",\n id: generateStatsId(\"remote-outbound-rtp\", track.ssrc),\n timestamp,\n ssrc: track.ssrc,\n kind: this.kind,\n transportId,\n codecId: inboundRtpStats.codecId,\n localId: inboundRtpStats.id,\n remoteTimestamp: this.receiveLastSRTimestamp[track.ssrc] * 1000, // Convert to ms\n };\n stats.push(remoteOutboundStats);\n }\n }\n\n return stats;\n }\n\n async sendRtcpPLI(mediaSsrc: number) {\n if (!this.pliEnabled) {\n log(\"pli not supported\", { mediaSsrc });\n return;\n }\n\n if (this.stopped) {\n return;\n }\n\n log(\"sendRtcpPLI\", { mediaSsrc });\n\n const packet = new RtcpPayloadSpecificFeedback({\n feedback: new PictureLossIndication({\n senderSsrc: this.rtcpSsrc,\n mediaSsrc,\n }),\n });\n try {\n await this.dtlsTransport.sendRtcp([packet]);\n } catch (error) {\n log(error);\n }\n }\n\n handleRtcpPacket(packet: RtcpPacket) {\n switch (packet.type) {\n case RtcpSrPacket.type:\n {\n const sr = packet as RtcpSrPacket;\n this.lastSRtimestamp[sr.ssrc] = compactNtp(\n sr.senderInfo.ntpTimestamp,\n );\n this.receiveLastSRTimestamp[sr.ssrc] = timestampSeconds();\n\n const track = this.trackBySSRC[packet.ssrc];\n if (track) {\n track.onReceiveRtcp.execute(packet);\n }\n }\n break;\n }\n this.onRtcp.execute(packet);\n }\n\n handleRtpBySsrc = (packet: RtpPacket, extensions: Extensions) => {\n const track = this.trackBySSRC[packet.header.ssrc];\n\n this.handleRTP(packet, extensions, track);\n };\n\n handleRtpByRid = (packet: RtpPacket, rid: string, extensions: Extensions) => {\n const track = this.trackByRID[rid];\n if (!this.trackBySSRC[packet.header.ssrc]) {\n this.trackBySSRC[packet.header.ssrc] = track;\n }\n\n this.handleRTP(packet, extensions, track);\n };\n\n private handleRTP(\n packet: RtpPacket,\n extensions: Extensions,\n track?: MediaStreamTrack,\n ) {\n if (this.stopped) {\n return;\n }\n\n const codec = this.codecs[packet.header.payloadType];\n if (!codec) {\n // log(\"unknown codec \" + packet.header.payloadType);\n return;\n }\n\n this.remoteStreams[packet.header.ssrc] =\n this.remoteStreams[packet.header.ssrc] ??\n new StreamStatistics(codec.clockRate);\n this.remoteStreams[packet.header.ssrc].add(packet);\n\n if (this.receiverTWCC) {\n const transportSequenceNumber = extensions[\n RTP_EXTENSION_URI.transportWideCC\n ] as TransportWideCCPayload;\n\n if (!transportSequenceNumber == undefined) {\n throw new Error(\"undefined\");\n }\n\n this.receiverTWCC.handleTWCC(transportSequenceNumber);\n } else if (this.twccEnabled) {\n this.setupTWCC(packet.header.ssrc);\n }\n\n if (codec.name.toLowerCase() === \"rtx\") {\n const originalSsrc = this.ssrcByRtx[packet.header.ssrc];\n const codecParams = codecParametersFromString(codec.parameters ?? \"\");\n const rtxCodec = this.codecs[codecParams[\"apt\"]];\n if (packet.payload.length < 2) return;\n\n packet = unwrapRtx(packet, rtxCodec.payloadType, originalSsrc);\n track = this.trackBySSRC[originalSsrc];\n }\n\n let red: Red | undefined;\n if (codec.name.toLowerCase() === \"red\") {\n red = Red.deSerialize(packet.payload);\n if (\n !Object.keys(this.codecs).includes(\n red.header.fields[0].blockPT.toString(),\n )\n ) {\n return;\n }\n }\n\n if (track?.kind === \"video\" && this.nackEnabled) {\n this.nack.addPacket(packet);\n }\n\n if (track) {\n if (red) {\n if (track.kind === \"audio\") {\n const payloads = this.audioRedHandler.push(red, packet);\n for (const packet of payloads) {\n track.onReceiveRtp.execute(packet.clone(), extensions);\n }\n } else {\n }\n } else {\n track.onReceiveRtp.execute(packet.clone(), extensions);\n }\n }\n\n this.runRtcp();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rtpReceiver.js","sourceRoot":"","sources":["../../../../src/media/rtpReceiver.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"crypto\";\nimport { setTimeout } from \"timers/promises\";\nimport { Event, int } from \"../imports/common\";\n\nimport {\n type Extensions,\n PictureLossIndication,\n RTP_EXTENSION_URI,\n Red,\n RedHandler,\n type RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpReceiverInfo,\n RtcpRrPacket,\n RtcpSrPacket,\n type RtpPacket,\n type TransportWideCCPayload,\n debug,\n unwrapRtx,\n} from \"../imports/rtp\";\nimport type { PeerConfig } from \"../peerConnection\";\nimport type { RTCDtlsTransport } from \"../transport/dtls\";\nimport type { Kind } from \"../types/domain\";\nimport { compactNtp, ntpTimeToEpochMs, timestampSeconds } from \"../utils\";\nimport type {\n RTCRtpCodecParameters,\n RTCRtpReceiveParameters,\n} from \"./parameters\";\nimport { NackHandler } from \"./receiver/nack\";\nimport { ReceiverTWCC } from \"./receiver/receiverTwcc\";\nimport { StreamStatistics } from \"./receiver/statistics\";\n\nimport { codecParametersFromString } from \"../sdp\";\nimport { usePLI, useTWCC } from \"./extension/rtcpFeedback\";\nimport {\n type RTCCodecStats,\n type RTCInboundRtpStreamStats,\n type RTCRemoteOutboundRtpStreamStats,\n type RTCStats,\n type RTCStatsReport,\n buildStatsReport,\n generateCodecStatsId,\n generateStatsId,\n getStatsTimestamp,\n} from \"./stats\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/rtpReceiver.ts\");\n\nexport class RTCRtpReceiver {\n private readonly codecs: { [pt: number]: RTCRtpCodecParameters } = {};\n private readonly defaultTrack: MediaStreamTrack;\n private get codecArray() {\n return Object.values(this.codecs).sort(\n (a, b) => a.payloadType - b.payloadType,\n );\n }\n private readonly ssrcByRtx: { [rtxSsrc: number]: number } = {};\n private readonly nack = new NackHandler(this);\n private readonly audioRedHandler = new RedHandler();\n\n readonly type = \"receiver\";\n readonly uuid = randomUUID().toString();\n readonly tracks: MediaStreamTrack[] = [];\n readonly trackBySSRC: { [ssrc: string]: MediaStreamTrack } = {};\n readonly trackByRID: { [rid: string]: MediaStreamTrack } = {};\n /**last sender Report Timestamp\n * compactNtp\n */\n readonly lastSRtimestamp: { [ssrc: number]: number } = {};\n /**seconds */\n readonly receiveLastSRTimestamp: { [ssrc: number]: number } = {};\n readonly onPacketLost = this.nack.onPacketLost;\n readonly onRtcp = new Event<[RtcpPacket]>();\n\n dtlsTransport!: RTCDtlsTransport;\n sdesMid?: string;\n latestRid?: string;\n latestRepairedRid?: string;\n\n receiverTWCC?: ReceiverTWCC;\n stopped = false;\n remoteStreamId?: string;\n remoteStreamIds: string[] = [];\n remoteTrackId?: string;\n\n rtcpRunning = false;\n private rtcpCancel = new AbortController();\n private remoteStreams: { [ssrc: number]: StreamStatistics } = {};\n private senderReportsReceivedBySsrc: { [ssrc: number]: number } = {};\n private remoteTimestampsBySsrc: { [ssrc: number]: number } = {};\n private remotePacketCountBySsrc: { [ssrc: number]: number } = {};\n private remoteOctetCountBySsrc: { [ssrc: number]: number } = {};\n private nackCountBySsrc: { [ssrc: number]: number } = {};\n private pliCountBySsrc: { [ssrc: number]: number } = {};\n\n constructor(\n readonly config: PeerConfig,\n public kind: Kind,\n public rtcpSsrc: number,\n ) {\n this.defaultTrack = new MediaStreamTrack({ kind, remote: true });\n this.onPacketLost.subscribe((nack) => {\n this.nackCountBySsrc[nack.mediaSourceSsrc] =\n (this.nackCountBySsrc[nack.mediaSourceSsrc] ?? 0) + 1;\n });\n }\n\n get transport() {\n return this.dtlsTransport ?? null;\n }\n\n setDtlsTransport(dtls: RTCDtlsTransport) {\n this.dtlsTransport = dtls;\n }\n\n // todo fix\n get track() {\n return this.tracks[0] ?? this.defaultTrack;\n }\n\n get nackEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find((f) => f.type === \"nack\");\n }\n\n get twccEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find(\n (f) => f.type === useTWCC().type,\n );\n }\n\n get pliEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find(\n (f) => f.type === usePLI().type,\n );\n }\n\n prepareReceive(params: RTCRtpReceiveParameters) {\n params.codecs.forEach((c) => {\n this.codecs[c.payloadType] = c;\n });\n params.encodings.forEach((e) => {\n if (e.rtx) {\n this.ssrcByRtx[e.rtx.ssrc] = e.ssrc;\n }\n });\n }\n\n /**\n * setup TWCC if supported\n */\n setupTWCC(mediaSourceSsrc: number) {\n if (this.twccEnabled && !this.receiverTWCC) {\n this.receiverTWCC = new ReceiverTWCC(\n this.dtlsTransport,\n this.rtcpSsrc,\n mediaSourceSsrc,\n );\n }\n }\n\n addTrack(track: MediaStreamTrack) {\n const exist = this.tracks.find((t) => {\n if (t.rid) {\n return t.rid === track.rid;\n }\n if (t.ssrc) {\n return t.ssrc === track.ssrc;\n }\n });\n if (exist) {\n return false;\n }\n this.tracks.push(track);\n if (track.ssrc) {\n this.trackBySSRC[track.ssrc] = track;\n }\n if (track.rid) {\n this.trackByRID[track.rid] = track;\n }\n return true;\n }\n\n stop() {\n this.stopped = true;\n this.rtcpRunning = false;\n this.rtcpCancel.abort();\n\n if (this.receiverTWCC) this.receiverTWCC.twccRunning = false;\n this.nack.close();\n }\n\n async runRtcp() {\n if (this.rtcpRunning || this.stopped) return;\n this.rtcpRunning = true;\n\n try {\n while (this.rtcpRunning) {\n await setTimeout(500 + Math.random() * 1000, undefined, {\n signal: this.rtcpCancel.signal,\n });\n\n const reports = Object.entries(this.remoteStreams).map(\n ([ssrc, stream]) => {\n let lastSRtimestamp = 0,\n delaySinceLastSR = 0;\n if (this.lastSRtimestamp[ssrc]) {\n lastSRtimestamp = this.lastSRtimestamp[ssrc];\n const delaySeconds =\n timestampSeconds() - this.receiveLastSRTimestamp[ssrc];\n if (delaySeconds > 0 && delaySeconds < 65536) {\n delaySinceLastSR = int(delaySeconds * 65536);\n }\n }\n\n return new RtcpReceiverInfo({\n ssrc: Number(ssrc),\n fractionLost: stream.fraction_lost,\n packetsLost: stream.packets_lost,\n highestSequence: stream.max_seq,\n jitter: stream.jitter,\n lsr: lastSRtimestamp,\n dlsr: delaySinceLastSR,\n });\n },\n );\n\n const packet = new RtcpRrPacket({ ssrc: this.rtcpSsrc, reports });\n\n try {\n if (this.config.debug.receiverReportDelay) {\n await setTimeout(this.config.debug.receiverReportDelay);\n }\n await this.dtlsTransport.sendRtcp([packet]);\n } catch (error) {\n log(\"sendRtcp failed\", error);\n await setTimeout(500 + Math.random() * 1000);\n }\n }\n } catch (error) {}\n }\n\n private getInboundRtpStatsId(track: MediaStreamTrack) {\n return generateStatsId(\"inbound-rtp\", track.id ?? track.uuid);\n }\n\n private getRemoteOutboundRtpStatsId(track: MediaStreamTrack) {\n return generateStatsId(\"remote-outbound-rtp\", track.id ?? track.uuid);\n }\n\n getStatsRootIds(selector?: MediaStreamTrack) {\n return this.tracks\n .filter((track) => (!selector ? true : track === selector))\n .filter((track) => track.ssrc)\n .map((track) => this.getInboundRtpStatsId(track));\n }\n\n collectStats(timestamp: number): RTCStats[] {\n const stats: RTCStats[] = [];\n const transportId = this.dtlsTransport\n ? generateStatsId(\"transport\", this.dtlsTransport.id)\n : undefined;\n const activeCodec = this.codecArray[0];\n const emittedCodecIds = new Set<string>();\n\n // Collect stats for each track\n for (const track of this.tracks) {\n if (!track.ssrc) continue;\n\n const streamStats = this.remoteStreams[track.ssrc];\n\n // Inbound RTP stats\n const hasRemoteTimestamp =\n this.remoteTimestampsBySsrc[track.ssrc] !== undefined;\n const remoteId =\n this.lastSRtimestamp[track.ssrc] !== undefined || hasRemoteTimestamp\n ? this.getRemoteOutboundRtpStatsId(track)\n : undefined;\n const codecId =\n activeCodec && transportId\n ? generateCodecStatsId(\n transportId,\n activeCodec.payloadType,\n track.id ?? track.uuid,\n )\n : undefined;\n\n if (\n activeCodec &&\n transportId &&\n codecId &&\n !emittedCodecIds.has(codecId)\n ) {\n emittedCodecIds.add(codecId);\n const codecStats: RTCCodecStats = {\n type: \"codec\",\n id: codecId,\n timestamp,\n payloadType: activeCodec.payloadType,\n transportId,\n mimeType: activeCodec.mimeType,\n clockRate: activeCodec.clockRate,\n channels: activeCodec.channels,\n sdpFmtpLine: activeCodec.parameters,\n };\n stats.push(codecStats);\n }\n\n const inboundRtpStats: RTCInboundRtpStreamStats = {\n type: \"inbound-rtp\",\n id: this.getInboundRtpStatsId(track),\n timestamp,\n ssrc: track.ssrc,\n kind: this.kind,\n transportId,\n codecId,\n mid: this.sdesMid,\n trackIdentifier: track.id ?? track.uuid,\n packetsReceived: streamStats?.packets_received ?? 0,\n bytesReceived: streamStats?.bytesReceived ?? 0,\n headerBytesReceived: streamStats?.headerBytesReceived ?? 0,\n packetsLost: streamStats?.packets_lost ?? 0,\n jitter: streamStats?.clockRate\n ? streamStats.jitter / streamStats.clockRate\n : undefined,\n lastPacketReceivedTimestamp: streamStats?.lastPacketReceivedTimestamp,\n remoteId,\n nackCount: this.nackCountBySsrc[track.ssrc] || undefined,\n pliCount: this.pliCountBySsrc[track.ssrc] || undefined,\n };\n stats.push(inboundRtpStats);\n\n // Remote outbound RTP stats (if we have SR info)\n if (remoteId) {\n const remoteOutboundStats: RTCRemoteOutboundRtpStreamStats = {\n type: \"remote-outbound-rtp\",\n id: this.getRemoteOutboundRtpStatsId(track),\n timestamp,\n ssrc: track.ssrc,\n kind: this.kind,\n transportId,\n codecId: inboundRtpStats.codecId,\n localId: inboundRtpStats.id,\n remoteTimestamp: this.remoteTimestampsBySsrc[track.ssrc],\n reportsSent: this.senderReportsReceivedBySsrc[track.ssrc] ?? 0,\n packetsSent: this.remotePacketCountBySsrc[track.ssrc],\n bytesSent: this.remoteOctetCountBySsrc[track.ssrc],\n };\n stats.push(remoteOutboundStats);\n }\n }\n\n return stats;\n }\n\n async getStats(): Promise<RTCStatsReport> {\n const timestamp = getStatsTimestamp();\n const stats = this.collectStats(timestamp);\n\n if (this.dtlsTransport) {\n stats.push(...(await this.dtlsTransport.getStats(timestamp)));\n }\n\n return buildStatsReport(stats, this.getStatsRootIds());\n }\n\n async sendRtcpPLI(mediaSsrc: number) {\n if (!this.pliEnabled) {\n log(\"pli not supported\", { mediaSsrc });\n return;\n }\n\n if (this.stopped) {\n return;\n }\n\n log(\"sendRtcpPLI\", { mediaSsrc });\n\n const packet = new RtcpPayloadSpecificFeedback({\n feedback: new PictureLossIndication({\n senderSsrc: this.rtcpSsrc,\n mediaSsrc,\n }),\n });\n try {\n this.pliCountBySsrc[mediaSsrc] =\n (this.pliCountBySsrc[mediaSsrc] ?? 0) + 1;\n await this.dtlsTransport.sendRtcp([packet]);\n } catch (error) {\n log(error);\n }\n }\n\n handleRtcpPacket(packet: RtcpPacket) {\n switch (packet.type) {\n case RtcpSrPacket.type:\n {\n const sr = packet as RtcpSrPacket;\n this.lastSRtimestamp[sr.ssrc] = compactNtp(\n sr.senderInfo.ntpTimestamp,\n );\n this.receiveLastSRTimestamp[sr.ssrc] = timestampSeconds();\n this.senderReportsReceivedBySsrc[sr.ssrc] =\n (this.senderReportsReceivedBySsrc[sr.ssrc] ?? 0) + 1;\n this.remoteTimestampsBySsrc[sr.ssrc] = ntpTimeToEpochMs(\n sr.senderInfo.ntpTimestamp,\n );\n this.remotePacketCountBySsrc[sr.ssrc] = sr.senderInfo.packetCount;\n this.remoteOctetCountBySsrc[sr.ssrc] = sr.senderInfo.octetCount;\n\n const track = this.trackBySSRC[packet.ssrc];\n if (track) {\n track.onReceiveRtcp.execute(packet);\n }\n }\n break;\n }\n this.onRtcp.execute(packet);\n }\n\n handleRtpBySsrc = (packet: RtpPacket, extensions: Extensions) => {\n const track = this.trackBySSRC[packet.header.ssrc];\n\n this.handleRTP(packet, extensions, track);\n };\n\n handleRtpByRid = (packet: RtpPacket, rid: string, extensions: Extensions) => {\n const track = this.trackByRID[rid];\n if (!this.trackBySSRC[packet.header.ssrc]) {\n this.trackBySSRC[packet.header.ssrc] = track;\n }\n\n this.handleRTP(packet, extensions, track);\n };\n\n private handleRTP(\n packet: RtpPacket,\n extensions: Extensions,\n track?: MediaStreamTrack,\n ) {\n if (this.stopped) {\n return;\n }\n\n const codec = this.codecs[packet.header.payloadType];\n if (!codec) {\n // log(\"unknown codec \" + packet.header.payloadType);\n return;\n }\n\n this.remoteStreams[packet.header.ssrc] =\n this.remoteStreams[packet.header.ssrc] ??\n new StreamStatistics(codec.clockRate);\n this.remoteStreams[packet.header.ssrc].add(packet);\n\n if (this.receiverTWCC) {\n const transportSequenceNumber = extensions[\n RTP_EXTENSION_URI.transportWideCC\n ] as TransportWideCCPayload;\n\n if (!transportSequenceNumber == undefined) {\n throw new Error(\"undefined\");\n }\n\n this.receiverTWCC.handleTWCC(transportSequenceNumber);\n } else if (this.twccEnabled) {\n this.setupTWCC(packet.header.ssrc);\n }\n\n if (codec.name.toLowerCase() === \"rtx\") {\n const originalSsrc = this.ssrcByRtx[packet.header.ssrc];\n const codecParams = codecParametersFromString(codec.parameters ?? \"\");\n const rtxCodec = this.codecs[codecParams[\"apt\"]];\n if (packet.payload.length < 2) return;\n\n packet = unwrapRtx(packet, rtxCodec.payloadType, originalSsrc);\n track = this.trackBySSRC[originalSsrc];\n }\n\n let red: Red | undefined;\n if (codec.name.toLowerCase() === \"red\") {\n red = Red.deSerialize(packet.payload);\n if (\n !Object.keys(this.codecs).includes(\n red.header.fields[0].blockPT.toString(),\n )\n ) {\n return;\n }\n }\n\n if (track?.kind === \"video\" && this.nackEnabled) {\n this.nack.addPacket(packet);\n }\n\n if (track) {\n if (red) {\n if (track.kind === \"audio\") {\n const payloads = this.audioRedHandler.push(red, packet);\n for (const packet of payloads) {\n track.onReceiveRtp.execute(packet.clone(), extensions);\n }\n } else {\n }\n } else {\n track.onReceiveRtp.execute(packet.clone(), extensions);\n }\n }\n\n this.runRtcp();\n }\n}\n"]}
|
|
@@ -25,15 +25,14 @@ import type { RTCDtlsTransport } from "../transport/dtls";
|
|
|
25
25
|
import type { Kind } from "../types/domain";
|
|
26
26
|
import type { RTCRtpCodecParameters, RTCRtpSendParameters } from "./parameters";
|
|
27
27
|
import { SenderBandwidthEstimator } from "./sender/senderBWE";
|
|
28
|
-
import { type RTCStats } from "./stats";
|
|
29
|
-
import type { MediaStreamTrack } from "./track";
|
|
28
|
+
import { type RTCStats, type RTCStatsReport } from "./stats";
|
|
29
|
+
import type { MediaStream, MediaStreamTrack } from "./track";
|
|
30
30
|
export declare class RTCRtpSender {
|
|
31
31
|
trackOrKind: Kind | MediaStreamTrack;
|
|
32
32
|
readonly type = "sender";
|
|
33
33
|
readonly kind: Kind;
|
|
34
34
|
readonly ssrc: number;
|
|
35
35
|
readonly rtxSsrc: number;
|
|
36
|
-
streamId: string;
|
|
37
36
|
readonly trackId: string;
|
|
38
37
|
readonly onReady: Event<any[]>;
|
|
39
38
|
readonly onRtcp: Event<[RtcpPacket]>;
|
|
@@ -51,13 +50,24 @@ export declare class RTCRtpSender {
|
|
|
51
50
|
redEncoder: RedEncoder;
|
|
52
51
|
private headerExtensions;
|
|
53
52
|
private disposeTrack?;
|
|
53
|
+
private sendEncodings;
|
|
54
54
|
private lastSRtimestamp?;
|
|
55
55
|
private lastSentSRTimestamp?;
|
|
56
56
|
private ntpTimestamp;
|
|
57
57
|
private rtpTimestamp;
|
|
58
58
|
private octetCount;
|
|
59
59
|
private packetCount;
|
|
60
|
+
private headerBytesSent;
|
|
60
61
|
private rtt?;
|
|
62
|
+
private totalRoundTripTime;
|
|
63
|
+
private roundTripTimeMeasurements;
|
|
64
|
+
private retransmittedPacketsSent;
|
|
65
|
+
private retransmittedBytesSent;
|
|
66
|
+
private nackCount;
|
|
67
|
+
private pliCount;
|
|
68
|
+
private firCount;
|
|
69
|
+
private remotePacketsLost?;
|
|
70
|
+
private remoteFractionLost?;
|
|
61
71
|
receiverEstimatedMaxBitrate: bigint;
|
|
62
72
|
private sequenceNumber?;
|
|
63
73
|
private timestamp?;
|
|
@@ -67,16 +77,22 @@ export declare class RTCRtpSender {
|
|
|
67
77
|
codec?: RTCRtpCodecParameters;
|
|
68
78
|
dtlsTransport: RTCDtlsTransport;
|
|
69
79
|
private dtlsDisposer;
|
|
70
|
-
track
|
|
80
|
+
track: MediaStreamTrack | null;
|
|
81
|
+
streamIds: string[];
|
|
71
82
|
stopped: boolean;
|
|
72
83
|
rtcpRunning: boolean;
|
|
73
84
|
private rtcpCancel;
|
|
74
85
|
constructor(trackOrKind: Kind | MediaStreamTrack);
|
|
86
|
+
get transport(): RTCDtlsTransport;
|
|
87
|
+
get streamId(): string | undefined;
|
|
88
|
+
set streamId(value: string | undefined);
|
|
75
89
|
setDtlsTransport(dtlsTransport: RTCDtlsTransport): void;
|
|
76
90
|
get redDistance(): number;
|
|
77
91
|
set redDistance(n: number);
|
|
78
92
|
prepareSend(params: RTCRtpSendParameters): void;
|
|
79
93
|
registerTrack(track: MediaStreamTrack): void;
|
|
94
|
+
setStreams(streams?: MediaStream[]): void;
|
|
95
|
+
setSendEncodings(encodings?: Array<Record<string, unknown>>): void;
|
|
80
96
|
replaceTrack(track: MediaStreamTrack | null): Promise<void>;
|
|
81
97
|
stop(): void;
|
|
82
98
|
runRtcp(): Promise<void>;
|
|
@@ -84,8 +100,17 @@ export declare class RTCRtpSender {
|
|
|
84
100
|
sendRtp(rtp: Buffer | RtpPacket): Promise<void>;
|
|
85
101
|
handleRtcpPacket(rtcpPacket: RtcpPacket): void;
|
|
86
102
|
getParameters(): {
|
|
87
|
-
encodings:
|
|
103
|
+
encodings: {
|
|
104
|
+
[x: string]: unknown;
|
|
105
|
+
}[];
|
|
88
106
|
};
|
|
89
|
-
setParameters(params:
|
|
90
|
-
|
|
107
|
+
setParameters(params: {
|
|
108
|
+
encodings?: Array<Record<string, unknown>>;
|
|
109
|
+
}): void;
|
|
110
|
+
private get outboundRtpStatsId();
|
|
111
|
+
private get mediaSourceStatsId();
|
|
112
|
+
private get remoteInboundRtpStatsId();
|
|
113
|
+
getStatsRootIds(): string[];
|
|
114
|
+
collectStats(timestamp: number): RTCStats[];
|
|
115
|
+
getStats(): Promise<RTCStatsReport>;
|
|
91
116
|
}
|