werift 0.24.4 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -113
- package/lib/common/src/transport.d.ts +22 -2
- package/lib/common/src/transport.js +84 -26
- package/lib/common/src/transport.js.map +1 -1
- package/lib/ice/src/exceptions.d.ts +9 -0
- package/lib/ice/src/exceptions.js +23 -1
- package/lib/ice/src/exceptions.js.map +1 -1
- package/lib/ice/src/ice.d.ts +40 -0
- package/lib/ice/src/ice.js +194 -28
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/iceBase.d.ts +26 -0
- package/lib/ice/src/iceBase.js.map +1 -1
- package/lib/ice/src/stun/const.d.ts +7 -0
- package/lib/ice/src/stun/const.js +8 -0
- package/lib/ice/src/stun/const.js.map +1 -1
- package/lib/ice/src/stun/protocol.js +1 -4
- package/lib/ice/src/stun/protocol.js.map +1 -1
- package/lib/ice/src/stun/tcpProtocol.d.ts +7 -1
- package/lib/ice/src/stun/tcpProtocol.js +65 -14
- package/lib/ice/src/stun/tcpProtocol.js.map +1 -1
- package/lib/ice/src/stun/transaction.d.ts +12 -1
- package/lib/ice/src/stun/transaction.js +37 -4
- package/lib/ice/src/stun/transaction.js.map +1 -1
- package/lib/ice/src/turn/protocol.d.ts +40 -15
- package/lib/ice/src/turn/protocol.js +141 -32
- package/lib/ice/src/turn/protocol.js.map +1 -1
- package/lib/ice/src/types/model.d.ts +8 -0
- package/lib/ice/src/types/model.js.map +1 -1
- package/lib/index.mjs +6175 -4073
- package/lib/nonstandard/index.mjs +286 -1003
- package/lib/polyfill/dom.mjs +23794 -0
- package/lib/polyfill/index.mjs +23794 -0
- package/lib/rtp/src/extra/container/mp4/container.js +12 -4
- package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4.js +8 -3
- package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4Callback.js +3 -1
- package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
- package/lib/sctp/src/chunk.d.ts +5 -0
- package/lib/sctp/src/chunk.js +16 -11
- package/lib/sctp/src/chunk.js.map +1 -1
- package/lib/sctp/src/index.d.ts +3 -1
- package/lib/sctp/src/index.js +10 -1
- package/lib/sctp/src/index.js.map +1 -1
- package/lib/sctp/src/sctp.d.ts +12 -3
- package/lib/sctp/src/sctp.js +51 -18
- package/lib/sctp/src/sctp.js.map +1 -1
- package/lib/webrtc/src/const.js +2 -0
- package/lib/webrtc/src/const.js.map +1 -1
- package/lib/webrtc/src/errors.d.ts +9 -1
- package/lib/webrtc/src/errors.js +19 -0
- package/lib/webrtc/src/errors.js.map +1 -1
- package/lib/webrtc/src/media/codec.d.ts +5 -0
- package/lib/webrtc/src/media/codec.js +21 -0
- package/lib/webrtc/src/media/codec.js.map +1 -1
- package/lib/webrtc/src/media/codecCompatibility.d.ts +23 -0
- package/lib/webrtc/src/media/codecCompatibility.js +138 -0
- package/lib/webrtc/src/media/codecCompatibility.js.map +1 -0
- package/lib/webrtc/src/media/index.d.ts +1 -0
- package/lib/webrtc/src/media/index.js +1 -0
- package/lib/webrtc/src/media/index.js.map +1 -1
- package/lib/webrtc/src/media/router.d.ts +2 -0
- package/lib/webrtc/src/media/router.js +23 -3
- package/lib/webrtc/src/media/router.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.d.ts +12 -0
- package/lib/webrtc/src/media/rtpReceiver.js +35 -0
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpSender.d.ts +65 -4
- package/lib/webrtc/src/media/rtpSender.js +264 -35
- package/lib/webrtc/src/media/rtpSender.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +42 -0
- package/lib/webrtc/src/media/rtpTransceiver.js +157 -4
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/media/track.d.ts +29 -1
- package/lib/webrtc/src/media/track.js +164 -5
- package/lib/webrtc/src/media/track.js.map +1 -1
- package/lib/webrtc/src/nonstandard/index.d.ts +0 -1
- package/lib/webrtc/src/nonstandard/index.js +0 -1
- package/lib/webrtc/src/nonstandard/index.js.map +1 -1
- package/lib/webrtc/src/nonstandard/recorder/writer/webm.js +2 -1
- package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia.d.ts +1 -2
- package/lib/webrtc/src/nonstandard/userMedia.js +30 -14
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +126 -5
- package/lib/webrtc/src/peerConnection.js +609 -136
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/polyfill/api.d.ts +14 -0
- package/lib/webrtc/src/polyfill/api.js +23 -0
- package/lib/webrtc/src/polyfill/api.js.map +1 -0
- package/lib/webrtc/src/polyfill/browserIdentity.d.ts +11 -0
- package/lib/webrtc/src/polyfill/browserIdentity.js +59 -0
- package/lib/webrtc/src/polyfill/browserIdentity.js.map +1 -0
- package/lib/webrtc/src/polyfill/dom.d.ts +11 -0
- package/lib/webrtc/src/polyfill/dom.js +18 -0
- package/lib/webrtc/src/polyfill/dom.js.map +1 -0
- package/lib/webrtc/src/polyfill/existingMediaDevices.d.ts +2 -0
- package/lib/webrtc/src/polyfill/existingMediaDevices.js +22 -0
- package/lib/webrtc/src/polyfill/existingMediaDevices.js.map +1 -0
- package/lib/webrtc/src/polyfill/globals.d.ts +28 -0
- package/lib/webrtc/src/polyfill/globals.js +3 -0
- package/lib/webrtc/src/polyfill/globals.js.map +1 -0
- package/lib/webrtc/src/polyfill/index.d.ts +2 -0
- package/lib/webrtc/src/polyfill/index.js +19 -0
- package/lib/webrtc/src/polyfill/index.js.map +1 -0
- package/lib/webrtc/src/polyfill/install.d.ts +13 -0
- package/lib/webrtc/src/polyfill/install.js +266 -0
- package/lib/webrtc/src/polyfill/install.js.map +1 -0
- package/lib/webrtc/src/polyfill/mediaDevices.d.ts +38 -0
- package/lib/webrtc/src/polyfill/mediaDevices.js +228 -0
- package/lib/webrtc/src/polyfill/mediaDevices.js.map +1 -0
- package/lib/webrtc/src/polyfill/mediaRegister.d.ts +51 -0
- package/lib/webrtc/src/polyfill/mediaRegister.js +14 -0
- package/lib/webrtc/src/polyfill/mediaRegister.js.map +1 -0
- package/lib/webrtc/src/polyfill/peerConnectionConfig.d.ts +3 -0
- package/lib/webrtc/src/polyfill/peerConnectionConfig.js +52 -0
- package/lib/webrtc/src/polyfill/peerConnectionConfig.js.map +1 -0
- package/lib/webrtc/src/polyfill/registers/callback.d.ts +16 -0
- package/lib/webrtc/src/polyfill/registers/callback.js +57 -0
- package/lib/webrtc/src/polyfill/registers/callback.js.map +1 -0
- package/lib/webrtc/src/polyfill/registers/empty.d.ts +2 -0
- package/lib/webrtc/src/polyfill/registers/empty.js +28 -0
- package/lib/webrtc/src/polyfill/registers/empty.js.map +1 -0
- package/lib/webrtc/src/polyfill/registers/mp4Webm.d.ts +36 -0
- package/lib/webrtc/src/polyfill/registers/mp4Webm.js +242 -0
- package/lib/webrtc/src/polyfill/registers/mp4Webm.js.map +1 -0
- package/lib/webrtc/src/polyfill/registers/rtpRtcp.d.ts +17 -0
- package/lib/webrtc/src/polyfill/registers/rtpRtcp.js +143 -0
- package/lib/webrtc/src/polyfill/registers/rtpRtcp.js.map +1 -0
- package/lib/webrtc/src/polyfill/rtcSessionDescription.d.ts +18 -0
- package/lib/webrtc/src/polyfill/rtcSessionDescription.js +36 -0
- package/lib/webrtc/src/polyfill/rtcSessionDescription.js.map +1 -0
- package/lib/webrtc/src/polyfill/rtpCodec.d.ts +17 -0
- package/lib/webrtc/src/polyfill/rtpCodec.js +93 -0
- package/lib/webrtc/src/polyfill/rtpCodec.js.map +1 -0
- package/lib/webrtc/src/polyfill/selectSettings.d.ts +31 -0
- package/lib/webrtc/src/polyfill/selectSettings.js +156 -0
- package/lib/webrtc/src/polyfill/selectSettings.js.map +1 -0
- package/lib/webrtc/src/polyfill/sourceIo.d.ts +21 -0
- package/lib/webrtc/src/polyfill/sourceIo.js +298 -0
- package/lib/webrtc/src/polyfill/sourceIo.js.map +1 -0
- package/lib/webrtc/src/polyfill/trackStop.d.ts +4 -0
- package/lib/webrtc/src/polyfill/trackStop.js +16 -0
- package/lib/webrtc/src/polyfill/trackStop.js.map +1 -0
- package/lib/webrtc/src/sctpManager.d.ts +2 -1
- package/lib/webrtc/src/sctpManager.js +5 -2
- package/lib/webrtc/src/sctpManager.js.map +1 -1
- package/lib/webrtc/src/sdp.d.ts +1 -1
- package/lib/webrtc/src/sdp.js +5 -6
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/sdpManager.d.ts +38 -1
- package/lib/webrtc/src/sdpManager.js +236 -30
- package/lib/webrtc/src/sdpManager.js.map +1 -1
- package/lib/webrtc/src/secureTransportManager.d.ts +43 -12
- package/lib/webrtc/src/secureTransportManager.js +123 -47
- package/lib/webrtc/src/secureTransportManager.js.map +1 -1
- package/lib/webrtc/src/transceiverManager.d.ts +91 -6
- package/lib/webrtc/src/transceiverManager.js +477 -62
- package/lib/webrtc/src/transceiverManager.js.map +1 -1
- package/lib/webrtc/src/transport/ice.d.ts +8 -0
- package/lib/webrtc/src/transport/ice.js +17 -1
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.d.ts +3 -2
- package/lib/webrtc/src/transport/sctp.js +8 -2
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/package.json +13 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../../../src/media/codec.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../../../src/media/codec.ts"],"names":[],"mappings":"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","sourcesContent":["import { useNACK, usePLI, useREMB } from \"./extension/rtcpFeedback\";\nimport { RTCRtpCodecParameters } from \"./parameters\";\n\nexport const useH264 = (props: Partial<RTCRtpCodecParameters> = {}) =>\n new RTCRtpCodecParameters({\n mimeType: \"video/h264\",\n clockRate: 90000,\n rtcpFeedback: [useNACK(), usePLI(), useREMB()],\n parameters:\n \"profile-level-id=42e01f;packetization-mode=1;level-asymmetry-allowed=1\",\n ...props,\n });\n\nexport const useVP8 = (props: Partial<RTCRtpCodecParameters> = {}) =>\n new RTCRtpCodecParameters({\n mimeType: \"video/VP8\",\n clockRate: 90000,\n rtcpFeedback: [useNACK(), usePLI(), useREMB()],\n ...props,\n });\n\nexport const useVP9 = (props: Partial<RTCRtpCodecParameters> = {}) =>\n new RTCRtpCodecParameters({\n mimeType: \"video/VP9\",\n clockRate: 90000,\n rtcpFeedback: [useNACK(), usePLI(), useREMB()],\n ...props,\n });\n\nexport const useAV1X = (props: Partial<RTCRtpCodecParameters> = {}) =>\n new RTCRtpCodecParameters({\n mimeType: \"video/AV1X\",\n clockRate: 90000,\n rtcpFeedback: [useNACK(), usePLI(), useREMB()],\n ...props,\n });\n\nexport const useOPUS = (props: Partial<RTCRtpCodecParameters> = {}) =>\n new RTCRtpCodecParameters({\n mimeType: \"audio/OPUS\",\n clockRate: 48000,\n channels: 2,\n ...props,\n });\n\nexport const usePCMU = (props: Partial<RTCRtpCodecParameters> = {}) =>\n new RTCRtpCodecParameters({\n mimeType: \"audio/PCMU\",\n clockRate: 8000,\n channels: 1,\n payloadType: 0,\n ...props,\n });\n\nexport function defaultCodecs() {\n return {\n audio: [useOPUS(), usePCMU()],\n video: [useVP8()],\n };\n}\n\nexport function cloneCodecParameters(codec: RTCRtpCodecParameters) {\n return new RTCRtpCodecParameters({\n mimeType: codec.mimeType,\n clockRate: codec.clockRate,\n ...(codec.channels != undefined ? { channels: codec.channels } : {}),\n ...(codec.payloadType != undefined\n ? { payloadType: codec.payloadType }\n : {}),\n rtcpFeedback: codec.rtcpFeedback.map((feedback) => ({ ...feedback })),\n ...(codec.parameters != undefined ? { parameters: codec.parameters } : {}),\n direction: codec.direction,\n });\n}\n\nexport const supportedCodecs = [\n useAV1X(),\n useVP9(),\n useVP8(),\n useH264(),\n useOPUS(),\n usePCMU(),\n].map((codec) => codec.mimeType);\n\nexport const supportedVideoCodecs = supportedCodecs.filter((codec) =>\n codec.toLowerCase().startsWith(\"video/\"),\n);\n\nexport const supportedAudioCodecs = supportedCodecs.filter((codec) =>\n codec.toLowerCase().startsWith(\"audio/\"),\n);\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Kind } from "../types/domain";
|
|
2
|
+
import type { RTCRtpCodecParameters } from "./parameters";
|
|
3
|
+
export declare function isCodecCompatible(source: RTCRtpCodecParameters, configured: RTCRtpCodecParameters): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* remote track が実際に配信する codec を返す。
|
|
6
|
+
* audio の RED は RTCRtpReceiver が primary へ展開してから track へ渡すため、
|
|
7
|
+
* RED が参照する primary codec (不明なら先頭の primary) を track の codec とする。
|
|
8
|
+
*/
|
|
9
|
+
export declare function deliveredTrackCodec(kind: string, codec: RTCRtpCodecParameters | undefined, negotiated: readonly RTCRtpCodecParameters[]): RTCRtpCodecParameters | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* RTX / RED を除く primary codec に MIME 一致が 1 つでもあるか。
|
|
12
|
+
* remote m-line を local capability で扱えるかの判定 (Issue #705) に使う。
|
|
13
|
+
*/
|
|
14
|
+
export declare function hasCommonPrimaryMimeType(local: readonly RTCRtpCodecParameters[], remote: readonly RTCRtpCodecParameters[]): boolean;
|
|
15
|
+
export declare function intersectCodecs(configured: RTCRtpCodecParameters[], source: readonly RTCRtpCodecParameters[]): RTCRtpCodecParameters[];
|
|
16
|
+
export declare function applyCodecPreferences(configured: RTCRtpCodecParameters[], preferences: readonly RTCRtpCodecParameters[] | undefined): RTCRtpCodecParameters[];
|
|
17
|
+
export declare function resolveCodecs(configured: RTCRtpCodecParameters[], source: readonly RTCRtpCodecParameters[] | undefined, preferences: readonly RTCRtpCodecParameters[] | undefined): RTCRtpCodecParameters[];
|
|
18
|
+
export declare function assertCodecsSupported(options: {
|
|
19
|
+
kind: Kind;
|
|
20
|
+
configured: RTCRtpCodecParameters[];
|
|
21
|
+
source: readonly RTCRtpCodecParameters[] | undefined;
|
|
22
|
+
preferences: readonly RTCRtpCodecParameters[] | undefined;
|
|
23
|
+
}): RTCRtpCodecParameters[];
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isCodecCompatible = isCodecCompatible;
|
|
4
|
+
exports.deliveredTrackCodec = deliveredTrackCodec;
|
|
5
|
+
exports.hasCommonPrimaryMimeType = hasCommonPrimaryMimeType;
|
|
6
|
+
exports.intersectCodecs = intersectCodecs;
|
|
7
|
+
exports.applyCodecPreferences = applyCodecPreferences;
|
|
8
|
+
exports.resolveCodecs = resolveCodecs;
|
|
9
|
+
exports.assertCodecsSupported = assertCodecsSupported;
|
|
10
|
+
const errors_1 = require("../errors");
|
|
11
|
+
const sdp_1 = require("../sdp");
|
|
12
|
+
function codecName(codec) {
|
|
13
|
+
return codec.name.toLowerCase();
|
|
14
|
+
}
|
|
15
|
+
function optionalEqual(left, right) {
|
|
16
|
+
return left == undefined || right == undefined || left === right;
|
|
17
|
+
}
|
|
18
|
+
function h264Parameters(codec) {
|
|
19
|
+
const parameters = (0, sdp_1.codecParametersFromString)(codec.parameters ?? "");
|
|
20
|
+
return {
|
|
21
|
+
packetizationMode: parameters["packetization-mode"],
|
|
22
|
+
profileLevelId: parameters["profile-level-id"]?.toString().toLowerCase(),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function isCodecCompatible(source, configured) {
|
|
26
|
+
if (source.mimeType.toLowerCase() !== configured.mimeType.toLowerCase()) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
if (source.clockRate !== configured.clockRate)
|
|
30
|
+
return false;
|
|
31
|
+
if (!optionalEqual(source.channels, configured.channels))
|
|
32
|
+
return false;
|
|
33
|
+
if (codecName(source) !== "h264")
|
|
34
|
+
return true;
|
|
35
|
+
const sourceParameters = h264Parameters(source);
|
|
36
|
+
const configuredParameters = h264Parameters(configured);
|
|
37
|
+
if (!optionalEqual(sourceParameters.packetizationMode, configuredParameters.packetizationMode)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return optionalEqual(sourceParameters.profileLevelId, configuredParameters.profileLevelId);
|
|
41
|
+
}
|
|
42
|
+
function isAuxiliary(codec) {
|
|
43
|
+
return ["rtx", "red"].includes(codecName(codec));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* remote track が実際に配信する codec を返す。
|
|
47
|
+
* audio の RED は RTCRtpReceiver が primary へ展開してから track へ渡すため、
|
|
48
|
+
* RED が参照する primary codec (不明なら先頭の primary) を track の codec とする。
|
|
49
|
+
*/
|
|
50
|
+
function deliveredTrackCodec(kind, codec, negotiated) {
|
|
51
|
+
if (kind !== "audio" || codec == undefined || codecName(codec) !== "red") {
|
|
52
|
+
return codec;
|
|
53
|
+
}
|
|
54
|
+
const [primaryPayloadType] = referencedPayloadTypes(codec);
|
|
55
|
+
return (negotiated.find((candidate) => !isAuxiliary(candidate) && candidate.payloadType === primaryPayloadType) ??
|
|
56
|
+
negotiated.find((candidate) => !isAuxiliary(candidate)) ??
|
|
57
|
+
codec);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* RTX / RED を除く primary codec に MIME 一致が 1 つでもあるか。
|
|
61
|
+
* remote m-line を local capability で扱えるかの判定 (Issue #705) に使う。
|
|
62
|
+
*/
|
|
63
|
+
function hasCommonPrimaryMimeType(local, remote) {
|
|
64
|
+
return local.some((localCodec) => !isAuxiliary(localCodec) &&
|
|
65
|
+
remote.some((remoteCodec) => remoteCodec.mimeType.toLowerCase() ===
|
|
66
|
+
localCodec.mimeType.toLowerCase()));
|
|
67
|
+
}
|
|
68
|
+
function referencedPayloadTypes(codec) {
|
|
69
|
+
const parameters = codec.parameters ?? "";
|
|
70
|
+
if (codecName(codec) === "rtx") {
|
|
71
|
+
const apt = Number((0, sdp_1.codecParametersFromString)(parameters).apt);
|
|
72
|
+
return Number.isNaN(apt) ? [] : [apt];
|
|
73
|
+
}
|
|
74
|
+
if (codecName(codec) === "red") {
|
|
75
|
+
return parameters
|
|
76
|
+
.split("/")
|
|
77
|
+
.map(Number)
|
|
78
|
+
.filter((value) => !Number.isNaN(value));
|
|
79
|
+
}
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
function withAuxiliaryCodecs(configured, primary) {
|
|
83
|
+
const keptPayloadTypes = new Set(primary.map((codec) => codec.payloadType));
|
|
84
|
+
const auxiliary = configured.filter((codec) => {
|
|
85
|
+
if (!isAuxiliary(codec))
|
|
86
|
+
return false;
|
|
87
|
+
const referenced = referencedPayloadTypes(codec);
|
|
88
|
+
return (referenced.length > 0 &&
|
|
89
|
+
referenced.every((payloadType) => keptPayloadTypes.has(payloadType)));
|
|
90
|
+
});
|
|
91
|
+
return configured.filter((codec) => primary.includes(codec) || auxiliary.includes(codec));
|
|
92
|
+
}
|
|
93
|
+
function intersectCodecs(configured, source) {
|
|
94
|
+
const primary = configured.filter((codec) => !isAuxiliary(codec) &&
|
|
95
|
+
source.some((sourceCodec) => isCodecCompatible(sourceCodec, codec)));
|
|
96
|
+
return withAuxiliaryCodecs(configured, primary);
|
|
97
|
+
}
|
|
98
|
+
function matchesPreference(candidate, preference) {
|
|
99
|
+
return (candidate.mimeType.toLowerCase() === preference.mimeType.toLowerCase() &&
|
|
100
|
+
optionalEqual(candidate.clockRate, preference.clockRate));
|
|
101
|
+
}
|
|
102
|
+
function applyCodecPreferences(configured, preferences) {
|
|
103
|
+
if (preferences == undefined)
|
|
104
|
+
return configured;
|
|
105
|
+
const preferred = preferences.flatMap((preference) => {
|
|
106
|
+
const match = configured.find((codec) => matchesPreference(codec, preference));
|
|
107
|
+
return match ? [match] : [];
|
|
108
|
+
});
|
|
109
|
+
const uniquePreferred = [...new Set(preferred)];
|
|
110
|
+
const referencedByPreferredAuxiliary = new Set(uniquePreferred.filter(isAuxiliary).flatMap(referencedPayloadTypes));
|
|
111
|
+
const primary = configured.filter((codec) => !isAuxiliary(codec) &&
|
|
112
|
+
(uniquePreferred.includes(codec) ||
|
|
113
|
+
referencedByPreferredAuxiliary.has(codec.payloadType)));
|
|
114
|
+
const allowed = withAuxiliaryCodecs(configured, primary);
|
|
115
|
+
return [
|
|
116
|
+
...uniquePreferred.filter((codec) => allowed.includes(codec)),
|
|
117
|
+
...allowed.filter((codec) => !uniquePreferred.includes(codec)),
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
function resolveCodecs(configured, source, preferences) {
|
|
121
|
+
return applyCodecPreferences(source == undefined ? configured : intersectCodecs(configured, source), preferences);
|
|
122
|
+
}
|
|
123
|
+
function list(codecs) {
|
|
124
|
+
return codecs?.map((codec) => codec.mimeType).join(", ") || "(none)";
|
|
125
|
+
}
|
|
126
|
+
function assertCodecsSupported(options) {
|
|
127
|
+
const { kind, configured, source, preferences } = options;
|
|
128
|
+
const sourceCompatible = source == undefined ? configured : intersectCodecs(configured, source);
|
|
129
|
+
if (source != undefined && sourceCompatible.length === 0) {
|
|
130
|
+
throw (0, errors_1.createWebRtcDomException)("NotSupportedError", `Track codec ${list(source)} is not supported by this RTCPeerConnection. Configured ${kind} codecs: ${list(configured)}`);
|
|
131
|
+
}
|
|
132
|
+
const effective = applyCodecPreferences(sourceCompatible, preferences);
|
|
133
|
+
if (effective.length === 0) {
|
|
134
|
+
throw (0, errors_1.createWebRtcDomException)("NotSupportedError", `No codec remains after applying codec preferences. Source codecs: ${list(source)} Configured codecs: ${list(configured)} Preferred codecs: ${list(preferences)}`);
|
|
135
|
+
}
|
|
136
|
+
return effective;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=codecCompatibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codecCompatibility.js","sourceRoot":"","sources":["../../../../src/media/codecCompatibility.ts"],"names":[],"mappings":"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","sourcesContent":["import { createWebRtcDomException } from \"../errors\";\nimport { codecParametersFromString } from \"../sdp\";\nimport type { Kind } from \"../types/domain\";\nimport type { RTCRtpCodecParameters } from \"./parameters\";\n\nfunction codecName(codec: RTCRtpCodecParameters) {\n return codec.name.toLowerCase();\n}\n\nfunction optionalEqual<T>(left: T | undefined, right: T | undefined) {\n return left == undefined || right == undefined || left === right;\n}\n\nfunction h264Parameters(codec: RTCRtpCodecParameters) {\n const parameters = codecParametersFromString(codec.parameters ?? \"\");\n return {\n packetizationMode: parameters[\"packetization-mode\"],\n profileLevelId: parameters[\"profile-level-id\"]?.toString().toLowerCase(),\n };\n}\n\nexport function isCodecCompatible(\n source: RTCRtpCodecParameters,\n configured: RTCRtpCodecParameters,\n) {\n if (source.mimeType.toLowerCase() !== configured.mimeType.toLowerCase()) {\n return false;\n }\n if (source.clockRate !== configured.clockRate) return false;\n if (!optionalEqual(source.channels, configured.channels)) return false;\n if (codecName(source) !== \"h264\") return true;\n\n const sourceParameters = h264Parameters(source);\n const configuredParameters = h264Parameters(configured);\n if (\n !optionalEqual(\n sourceParameters.packetizationMode,\n configuredParameters.packetizationMode,\n )\n ) {\n return false;\n }\n return optionalEqual(\n sourceParameters.profileLevelId,\n configuredParameters.profileLevelId,\n );\n}\n\nfunction isAuxiliary(codec: RTCRtpCodecParameters) {\n return [\"rtx\", \"red\"].includes(codecName(codec));\n}\n\n/**\n * remote track が実際に配信する codec を返す。\n * audio の RED は RTCRtpReceiver が primary へ展開してから track へ渡すため、\n * RED が参照する primary codec (不明なら先頭の primary) を track の codec とする。\n */\nexport function deliveredTrackCodec(\n kind: string,\n codec: RTCRtpCodecParameters | undefined,\n negotiated: readonly RTCRtpCodecParameters[],\n) {\n if (kind !== \"audio\" || codec == undefined || codecName(codec) !== \"red\") {\n return codec;\n }\n const [primaryPayloadType] = referencedPayloadTypes(codec);\n return (\n negotiated.find(\n (candidate) =>\n !isAuxiliary(candidate) && candidate.payloadType === primaryPayloadType,\n ) ??\n negotiated.find((candidate) => !isAuxiliary(candidate)) ??\n codec\n );\n}\n\n/**\n * RTX / RED を除く primary codec に MIME 一致が 1 つでもあるか。\n * remote m-line を local capability で扱えるかの判定 (Issue #705) に使う。\n */\nexport function hasCommonPrimaryMimeType(\n local: readonly RTCRtpCodecParameters[],\n remote: readonly RTCRtpCodecParameters[],\n) {\n return local.some(\n (localCodec) =>\n !isAuxiliary(localCodec) &&\n remote.some(\n (remoteCodec) =>\n remoteCodec.mimeType.toLowerCase() ===\n localCodec.mimeType.toLowerCase(),\n ),\n );\n}\n\nfunction referencedPayloadTypes(codec: RTCRtpCodecParameters) {\n const parameters = codec.parameters ?? \"\";\n if (codecName(codec) === \"rtx\") {\n const apt = Number(codecParametersFromString(parameters).apt);\n return Number.isNaN(apt) ? [] : [apt];\n }\n if (codecName(codec) === \"red\") {\n return parameters\n .split(\"/\")\n .map(Number)\n .filter((value) => !Number.isNaN(value));\n }\n return [];\n}\n\nfunction withAuxiliaryCodecs(\n configured: RTCRtpCodecParameters[],\n primary: RTCRtpCodecParameters[],\n) {\n const keptPayloadTypes = new Set(primary.map((codec) => codec.payloadType));\n const auxiliary = configured.filter((codec) => {\n if (!isAuxiliary(codec)) return false;\n const referenced = referencedPayloadTypes(codec);\n return (\n referenced.length > 0 &&\n referenced.every((payloadType) => keptPayloadTypes.has(payloadType))\n );\n });\n return configured.filter(\n (codec) => primary.includes(codec) || auxiliary.includes(codec),\n );\n}\n\nexport function intersectCodecs(\n configured: RTCRtpCodecParameters[],\n source: readonly RTCRtpCodecParameters[],\n) {\n const primary = configured.filter(\n (codec) =>\n !isAuxiliary(codec) &&\n source.some((sourceCodec) => isCodecCompatible(sourceCodec, codec)),\n );\n return withAuxiliaryCodecs(configured, primary);\n}\n\nfunction matchesPreference(\n candidate: RTCRtpCodecParameters,\n preference: RTCRtpCodecParameters,\n) {\n return (\n candidate.mimeType.toLowerCase() === preference.mimeType.toLowerCase() &&\n optionalEqual(candidate.clockRate, preference.clockRate)\n );\n}\n\nexport function applyCodecPreferences(\n configured: RTCRtpCodecParameters[],\n preferences: readonly RTCRtpCodecParameters[] | undefined,\n) {\n if (preferences == undefined) return configured;\n const preferred = preferences.flatMap((preference) => {\n const match = configured.find((codec) =>\n matchesPreference(codec, preference),\n );\n return match ? [match] : [];\n });\n const uniquePreferred = [...new Set(preferred)];\n const referencedByPreferredAuxiliary = new Set(\n uniquePreferred.filter(isAuxiliary).flatMap(referencedPayloadTypes),\n );\n const primary = configured.filter(\n (codec) =>\n !isAuxiliary(codec) &&\n (uniquePreferred.includes(codec) ||\n referencedByPreferredAuxiliary.has(codec.payloadType)),\n );\n const allowed = withAuxiliaryCodecs(configured, primary);\n return [\n ...uniquePreferred.filter((codec) => allowed.includes(codec)),\n ...allowed.filter((codec) => !uniquePreferred.includes(codec)),\n ];\n}\n\nexport function resolveCodecs(\n configured: RTCRtpCodecParameters[],\n source: readonly RTCRtpCodecParameters[] | undefined,\n preferences: readonly RTCRtpCodecParameters[] | undefined,\n) {\n return applyCodecPreferences(\n source == undefined ? configured : intersectCodecs(configured, source),\n preferences,\n );\n}\n\nfunction list(codecs: readonly RTCRtpCodecParameters[] | undefined) {\n return codecs?.map((codec) => codec.mimeType).join(\", \") || \"(none)\";\n}\n\nexport function assertCodecsSupported(options: {\n kind: Kind;\n configured: RTCRtpCodecParameters[];\n source: readonly RTCRtpCodecParameters[] | undefined;\n preferences: readonly RTCRtpCodecParameters[] | undefined;\n}) {\n const { kind, configured, source, preferences } = options;\n const sourceCompatible =\n source == undefined ? configured : intersectCodecs(configured, source);\n if (source != undefined && sourceCompatible.length === 0) {\n throw createWebRtcDomException(\n \"NotSupportedError\",\n `Track codec ${list(source)} is not supported by this RTCPeerConnection. Configured ${kind} codecs: ${list(configured)}`,\n );\n }\n const effective = applyCodecPreferences(sourceCompatible, preferences);\n if (effective.length === 0) {\n throw createWebRtcDomException(\n \"NotSupportedError\",\n `No codec remains after applying codec preferences. Source codecs: ${list(source)} Configured codecs: ${list(configured)} Preferred codecs: ${list(preferences)}`,\n );\n }\n return effective;\n}\n"]}
|
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./codec"), exports);
|
|
18
|
+
__exportStar(require("./codecCompatibility"), exports);
|
|
18
19
|
__exportStar(require("./extension/rtcpFeedback"), exports);
|
|
19
20
|
__exportStar(require("./extension/rtpExtension"), exports);
|
|
20
21
|
__exportStar(require("./parameters"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/media/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,2DAAyC;AACzC,2DAAyC;AACzC,+CAA6B;AAC7B,2CAAyB;AACzB,gDAA8B;AAC9B,8CAA4B;AAC5B,mDAAiC;AACjC,0CAAwB;AACxB,wDAAsC;AACtC,0CAAwB","sourcesContent":["export * from \"./codec\";\nexport * from \"./extension/rtcpFeedback\";\nexport * from \"./extension/rtpExtension\";\nexport * from \"./parameters\";\nexport * from \"./router\";\nexport * from \"./rtpReceiver\";\nexport * from \"./rtpSender\";\nexport * from \"./rtpTransceiver\";\nexport * from \"./stats\";\nexport * from \"../transceiverManager\";\nexport * from \"./track\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/media/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,uDAAqC;AACrC,2DAAyC;AACzC,2DAAyC;AACzC,+CAA6B;AAC7B,2CAAyB;AACzB,gDAA8B;AAC9B,8CAA4B;AAC5B,mDAAiC;AACjC,0CAAwB;AACxB,wDAAsC;AACtC,0CAAwB","sourcesContent":["export * from \"./codec\";\nexport * from \"./codecCompatibility\";\nexport * from \"./extension/rtcpFeedback\";\nexport * from \"./extension/rtpExtension\";\nexport * from \"./parameters\";\nexport * from \"./router\";\nexport * from \"./rtpReceiver\";\nexport * from \"./rtpSender\";\nexport * from \"./rtpTransceiver\";\nexport * from \"./stats\";\nexport * from \"../transceiverManager\";\nexport * from \"./track\";\n"]}
|
|
@@ -18,6 +18,8 @@ export declare class RtpRouter {
|
|
|
18
18
|
private registerRtpReceiver;
|
|
19
19
|
registerRtpReceiverBySsrc(transceiver: RTCRtpTransceiver, params: RTCRtpReceiveParameters): void;
|
|
20
20
|
registerRtpReceiverByRid(transceiver: RTCRtpTransceiver, param: RTCRtpSimulcastParameters, params: RTCRtpReceiveParameters): void;
|
|
21
|
+
/**停止した transceiver の SSRC / RID 登録を解除する */
|
|
22
|
+
unregisterTransceiver(transceiver: RTCRtpTransceiver): void;
|
|
21
23
|
routeRtp: (packet: RtpPacket) => void;
|
|
22
24
|
routeRtcp: (packet: RtcpPacket) => void;
|
|
23
25
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RtpRouter = void 0;
|
|
4
4
|
const rtp_1 = require("../imports/rtp");
|
|
5
|
+
const codecCompatibility_1 = require("./codecCompatibility");
|
|
5
6
|
const rtpReceiver_1 = require("./rtpReceiver");
|
|
6
7
|
const track_1 = require("./track");
|
|
7
8
|
const log = (0, rtp_1.debug)("werift:packages/webrtc/src/media/router.ts");
|
|
@@ -35,8 +36,10 @@ class RtpRouter {
|
|
|
35
36
|
const rid = extensions[rtp_1.RTP_EXTENSION_URI.sdesRTPStreamID];
|
|
36
37
|
if (typeof rid === "string") {
|
|
37
38
|
rtpReceiver = this.ridTable[rid];
|
|
38
|
-
rtpReceiver
|
|
39
|
-
|
|
39
|
+
if (rtpReceiver) {
|
|
40
|
+
rtpReceiver.latestRid = rid;
|
|
41
|
+
rtpReceiver.handleRtpByRid(packet, rid, extensions);
|
|
42
|
+
}
|
|
40
43
|
}
|
|
41
44
|
else if (rtpReceiver) {
|
|
42
45
|
rtpReceiver.handleRtpBySsrc(packet, extensions);
|
|
@@ -145,7 +148,7 @@ class RtpRouter {
|
|
|
145
148
|
kind: transceiver.kind,
|
|
146
149
|
id: transceiver.sender.trackId,
|
|
147
150
|
remote: true,
|
|
148
|
-
codec: params.codecs[i],
|
|
151
|
+
codec: (0, codecCompatibility_1.deliveredTrackCodec)(transceiver.kind, params.codecs[i], params.codecs),
|
|
149
152
|
}));
|
|
150
153
|
if (encode.rtx) {
|
|
151
154
|
this.registerRtpReceiver(transceiver.receiver, encode.rtx.ssrc);
|
|
@@ -168,6 +171,23 @@ class RtpRouter {
|
|
|
168
171
|
}));
|
|
169
172
|
this.ridTable[param.rid] = transceiver.receiver;
|
|
170
173
|
}
|
|
174
|
+
/**停止した transceiver の SSRC / RID 登録を解除する */
|
|
175
|
+
unregisterTransceiver(transceiver) {
|
|
176
|
+
const owners = [
|
|
177
|
+
transceiver.sender,
|
|
178
|
+
transceiver.receiver,
|
|
179
|
+
];
|
|
180
|
+
for (const [ssrc, owner] of Object.entries(this.ssrcTable)) {
|
|
181
|
+
if (owners.includes(owner)) {
|
|
182
|
+
delete this.ssrcTable[Number(ssrc)];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
for (const [rid, owner] of Object.entries(this.ridTable)) {
|
|
186
|
+
if (owners.includes(owner)) {
|
|
187
|
+
delete this.ridTable[rid];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
171
191
|
}
|
|
172
192
|
exports.RtpRouter = RtpRouter;
|
|
173
193
|
//# sourceMappingURL=router.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/media/router.ts"],"names":[],"mappings":";;;AAAA,wCAawB;AAKxB,+CAA+C;AAG/C,mCAA2C;AAE3C,MAAM,GAAG,GAAG,IAAA,WAAK,EAAC,4CAA4C,CAAC,CAAC;AAEhE,MAAa,SAAS;IAKpB;QAJA;;;;mBAA+D,EAAE;WAAC;QAClE;;;;mBAA6D,EAAE;WAAC;QAChE;;;;mBAAwC,EAAE;WAAC;QA+D3C;;;;mBAAW,CAAC,MAAiB,EAAE,EAAE;gBAC/B,MAAM,UAAU,GAAe,IAAA,+BAAyB,EACtD,MAAM,CAAC,MAAM,CAAC,UAAU,EACxB,IAAI,CAAC,WAAW,CACjB,CAAC;gBAEF,IAAI,WAAW,GAA+B,IAAI,CAAC,SAAS,CAC1D,MAAM,CAAC,MAAM,CAAC,IAAI,CACD,CAAC;gBAEpB,MAAM,GAAG,GAAG,UAAU,CAAC,uBAAiB,CAAC,eAAe,CAAC,CAAC;gBAC1D,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBAC5B,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAmB,CAAC;oBACnD,WAAW,CAAC,SAAS,GAAG,GAAG,CAAC;oBAC5B,WAAW,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;gBACtD,CAAC;qBAAM,IAAI,WAAW,EAAE,CAAC;oBACvB,WAAW,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACN,uCAAuC;oBACvC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;yBACvC,MAAM,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,YAAY,4BAAc,CAAC;yBAC/D,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;oBAClD,IAAI,WAAW,EAAE,CAAC;wBAChB,GAAG,CAAC,qCAAqC,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;wBAC/D,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;wBAC1D,WAAW,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;oBAClD,CAAC;yBAAM,CAAC;wBACN,MAAM;oBACR,CAAC;gBACH,CAAC;gBAED,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,GAAG,CAAC,wBAAwB,CAAC,CAAC;oBAC9B,OAAO;gBACT,CAAC;gBAED,MAAM,OAAO,GAAG,UAAU,CAAC,uBAAiB,CAAC,OAAO,CAAC,CAAC;gBACtD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;oBAChC,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC;gBAChC,CAAC;gBAED,MAAM,WAAW,GAAG,UAAU,CAC5B,uBAAiB,CAAC,mBAAmB,CAC5B,CAAC;gBACZ,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;oBACpC,WAAW,CAAC,iBAAiB,GAAG,WAAW,CAAC;gBAC9C,CAAC;YACH,CAAC;WAAC;QAEF;;;;mBAAY,CAAC,MAAkB,EAAE,EAAE;gBACjC,MAAM,UAAU,GAAsC,EAAE,CAAC;gBAEzD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;oBACpB,KAAK,kBAAY,CAAC,IAAI;wBACpB,CAAC;4BACC,MAAM,GAAG,MAAsB,CAAC;4BAChC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;wBAC/C,CAAC;wBACD,MAAM;oBACR,KAAK,kBAAY,CAAC,IAAI;wBACpB,CAAC;4BACC,MAAM,GAAG,MAAsB,CAAC;4BAChC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gCAChC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;4BAC/C,CAAC,CAAC,CAAC;wBACL,CAAC;wBACD,MAAM;oBACR,KAAK,iCAA2B,CAAC,IAAI;wBACnC,CAAC;4BACC,MAAM,IAAI,GAAG,MAAqC,CAAC;4BACnD,4CAA4C;wBAC9C,CAAC;wBACD,MAAM;oBACR,KAAK,gCAA0B,CAAC,IAAI;wBAClC,CAAC;4BACC,MAAM,KAAK,GAAG,MAAoC,CAAC;4BACnD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gCACnB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;4BAClE,CAAC;wBACH,CAAC;wBACD,MAAM;oBACR,KAAK,iCAA2B,CAAC,IAAI;wBACnC,CAAC;4BACC,MAAM,IAAI,GAAG,MAAqC,CAAC;4BACnD,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;gCAC5B,KAAK,iCAA2B,CAAC,KAAK;oCACpC,CAAC;wCACC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAuC,CAAC;wCAC1D,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oCACzD,CAAC;oCACD,MAAM;gCACR;oCACE,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;wCACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAC1C,CAAC;4BACN,CAAC;wBACH,CAAC;wBACD,MAAM;gBACV,CAAC;gBACD,UAAU;qBACP,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,iBAAiB;qBAClC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;YAChE,CAAC;WAAC;IApKa,CAAC;IAEhB,iBAAiB,CAAC,MAAoB;QACpC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IACvC,CAAC;IAEO,mBAAmB,CAAC,QAAwB,EAAE,IAAY;QAChE,GAAG,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;IAClC,CAAC;IAED,yBAAyB,CACvB,WAA8B,EAC9B,MAA+B;QAE/B,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;QAEzC,MAAM,CAAC,SAAS;aACb,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,WAAW;aAC9C,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrB,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5D,WAAW,CAAC,QAAQ,CAClB,IAAI,wBAAgB,CAAC;gBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO;gBAC9B,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;aACxB,CAAC,CACH,CAAC;YACF,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;gBACf,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClE,CAAC;QACH,CAAC,CAAC,CAAC;QAEL,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAC5C,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,wBAAwB,CACtB,WAA8B,EAC9B,KAAgC,EAChC,MAA+B;QAE/B,mDAAmD;QACnD,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAE9B,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;QACvC,WAAW,CAAC,QAAQ,CAClB,IAAI,wBAAgB,CAAC;YACnB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO;YAC9B,MAAM,EAAE,IAAI;YACZ,KAAK;SACN,CAAC,CACH,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC;IAClD,CAAC;CA0GF;AA1KD,8BA0KC","sourcesContent":["import {\n type Extensions,\n RTP_EXTENSION_URI,\n ReceiverEstimatedMaxBitrate,\n type RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpRrPacket,\n RtcpSourceDescriptionPacket,\n RtcpSrPacket,\n RtcpTransportLayerFeedback,\n type RtpPacket,\n debug,\n rtpHeaderExtensionsParser,\n} from \"../imports/rtp\";\nimport type {\n RTCRtpReceiveParameters,\n RTCRtpSimulcastParameters,\n} from \"./parameters\";\nimport { RTCRtpReceiver } from \"./rtpReceiver\";\nimport type { RTCRtpSender } from \"./rtpSender\";\nimport type { RTCRtpTransceiver } from \"./rtpTransceiver\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/router.ts\");\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 log(\"registerRtpReceiver\", ssrc);\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 routeRtp = (packet: RtpPacket) => {\n const extensions: Extensions = rtpHeaderExtensionsParser(\n packet.header.extensions,\n this.extIdUriMap,\n );\n\n let rtpReceiver: 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 rtpReceiver = this.ridTable[rid] as RTCRtpReceiver;\n rtpReceiver.latestRid = rid;\n rtpReceiver.handleRtpByRid(packet, rid, extensions);\n } else if (rtpReceiver) {\n rtpReceiver.handleRtpBySsrc(packet, extensions);\n } else {\n // simulcast after send receiver report\n rtpReceiver = Object.values(this.ridTable)\n .filter((r): r is RTCRtpReceiver => r instanceof RTCRtpReceiver)\n .find((r) => r.trackBySSRC[packet.header.ssrc]);\n if (rtpReceiver) {\n log(\"simulcast register receiver by ssrc\", packet.header.ssrc);\n this.registerRtpReceiver(rtpReceiver, packet.header.ssrc);\n rtpReceiver.handleRtpBySsrc(packet, extensions);\n } else {\n // bug\n }\n }\n\n if (!rtpReceiver) {\n log(\"ssrcReceiver not found\");\n return;\n }\n\n const sdesMid = extensions[RTP_EXTENSION_URI.sdesMid];\n if (typeof sdesMid === \"string\") {\n rtpReceiver.sdesMid = sdesMid;\n }\n\n const repairedRid = extensions[\n RTP_EXTENSION_URI.repairedRtpStreamId\n ] as string;\n if (typeof repairedRid === \"string\") {\n rtpReceiver.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 {\n const remb = psfb.feedback as ReceiverEstimatedMaxBitrate;\n recipients.push(this.ssrcTable[remb.ssrcFeedbacks[0]]);\n }\n break;\n default:\n recipients.push(\n this.ssrcTable[psfb.feedback.senderSsrc] ||\n this.ssrcTable[psfb.feedback.mediaSsrc],\n );\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":";;;AAAA,wCAawB;AACxB,6DAA2D;AAK3D,+CAA+C;AAG/C,mCAA2C;AAE3C,MAAM,GAAG,GAAG,IAAA,WAAK,EAAC,4CAA4C,CAAC,CAAC;AAEhE,MAAa,SAAS;IAKpB;QAJA;;;;mBAA+D,EAAE;WAAC;QAClE;;;;mBAA6D,EAAE;WAAC;QAChE;;;;mBAAwC,EAAE;WAAC;QAqF3C;;;;mBAAW,CAAC,MAAiB,EAAE,EAAE;gBAC/B,MAAM,UAAU,GAAe,IAAA,+BAAyB,EACtD,MAAM,CAAC,MAAM,CAAC,UAAU,EACxB,IAAI,CAAC,WAAW,CACjB,CAAC;gBAEF,IAAI,WAAW,GAA+B,IAAI,CAAC,SAAS,CAC1D,MAAM,CAAC,MAAM,CAAC,IAAI,CACD,CAAC;gBAEpB,MAAM,GAAG,GAAG,UAAU,CAAC,uBAAiB,CAAC,eAAe,CAAC,CAAC;gBAC1D,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBAC5B,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAA+B,CAAC;oBAC/D,IAAI,WAAW,EAAE,CAAC;wBAChB,WAAW,CAAC,SAAS,GAAG,GAAG,CAAC;wBAC5B,WAAW,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;oBACtD,CAAC;gBACH,CAAC;qBAAM,IAAI,WAAW,EAAE,CAAC;oBACvB,WAAW,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACN,uCAAuC;oBACvC,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;yBACvC,MAAM,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,YAAY,4BAAc,CAAC;yBAC/D,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;oBAClD,IAAI,WAAW,EAAE,CAAC;wBAChB,GAAG,CAAC,qCAAqC,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;wBAC/D,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;wBAC1D,WAAW,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;oBAClD,CAAC;yBAAM,CAAC;wBACN,MAAM;oBACR,CAAC;gBACH,CAAC;gBAED,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,GAAG,CAAC,wBAAwB,CAAC,CAAC;oBAC9B,OAAO;gBACT,CAAC;gBAED,MAAM,OAAO,GAAG,UAAU,CAAC,uBAAiB,CAAC,OAAO,CAAC,CAAC;gBACtD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;oBAChC,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC;gBAChC,CAAC;gBAED,MAAM,WAAW,GAAG,UAAU,CAC5B,uBAAiB,CAAC,mBAAmB,CAC5B,CAAC;gBACZ,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;oBACpC,WAAW,CAAC,iBAAiB,GAAG,WAAW,CAAC;gBAC9C,CAAC;YACH,CAAC;WAAC;QAEF;;;;mBAAY,CAAC,MAAkB,EAAE,EAAE;gBACjC,MAAM,UAAU,GAAsC,EAAE,CAAC;gBAEzD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;oBACpB,KAAK,kBAAY,CAAC,IAAI;wBACpB,CAAC;4BACC,MAAM,GAAG,MAAsB,CAAC;4BAChC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;wBAC/C,CAAC;wBACD,MAAM;oBACR,KAAK,kBAAY,CAAC,IAAI;wBACpB,CAAC;4BACC,MAAM,GAAG,MAAsB,CAAC;4BAChC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gCAChC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;4BAC/C,CAAC,CAAC,CAAC;wBACL,CAAC;wBACD,MAAM;oBACR,KAAK,iCAA2B,CAAC,IAAI;wBACnC,CAAC;4BACC,MAAM,IAAI,GAAG,MAAqC,CAAC;4BACnD,4CAA4C;wBAC9C,CAAC;wBACD,MAAM;oBACR,KAAK,gCAA0B,CAAC,IAAI;wBAClC,CAAC;4BACC,MAAM,KAAK,GAAG,MAAoC,CAAC;4BACnD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gCACnB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;4BAClE,CAAC;wBACH,CAAC;wBACD,MAAM;oBACR,KAAK,iCAA2B,CAAC,IAAI;wBACnC,CAAC;4BACC,MAAM,IAAI,GAAG,MAAqC,CAAC;4BACnD,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;gCAC5B,KAAK,iCAA2B,CAAC,KAAK;oCACpC,CAAC;wCACC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAuC,CAAC;wCAC1D,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oCACzD,CAAC;oCACD,MAAM;gCACR;oCACE,UAAU,CAAC,IAAI,CACb,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;wCACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAC1C,CAAC;4BACN,CAAC;wBACH,CAAC;wBACD,MAAM;gBACV,CAAC;gBACD,UAAU;qBACP,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,iBAAiB;qBAClC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;YAChE,CAAC;WAAC;IA5La,CAAC;IAEhB,iBAAiB,CAAC,MAAoB;QACpC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IACvC,CAAC;IAEO,mBAAmB,CAAC,QAAwB,EAAE,IAAY;QAChE,GAAG,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;IAClC,CAAC;IAED,yBAAyB,CACvB,WAA8B,EAC9B,MAA+B;QAE/B,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;QAEzC,MAAM,CAAC,SAAS;aACb,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,WAAW;aAC9C,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrB,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5D,WAAW,CAAC,QAAQ,CAClB,IAAI,wBAAgB,CAAC;gBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO;gBAC9B,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,IAAA,wCAAmB,EACxB,WAAW,CAAC,IAAI,EAChB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAChB,MAAM,CAAC,MAAM,CACd;aACF,CAAC,CACH,CAAC;YACF,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;gBACf,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClE,CAAC;QACH,CAAC,CAAC,CAAC;QAEL,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAC5C,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,wBAAwB,CACtB,WAA8B,EAC9B,KAAgC,EAChC,MAA+B;QAE/B,mDAAmD;QACnD,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAE9B,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;QACvC,WAAW,CAAC,QAAQ,CAClB,IAAI,wBAAgB,CAAC;YACnB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO;YAC9B,MAAM,EAAE,IAAI;YACZ,KAAK;SACN,CAAC,CACH,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC;IAClD,CAAC;IAED,2CAA2C;IAC3C,qBAAqB,CAAC,WAA8B;QAClD,MAAM,MAAM,GAAsC;YAChD,WAAW,CAAC,MAAM;YAClB,WAAW,CAAC,QAAQ;SACrB,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3D,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzD,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;CA4GF;AAlMD,8BAkMC","sourcesContent":["import {\n type Extensions,\n RTP_EXTENSION_URI,\n ReceiverEstimatedMaxBitrate,\n type RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpRrPacket,\n RtcpSourceDescriptionPacket,\n RtcpSrPacket,\n RtcpTransportLayerFeedback,\n type RtpPacket,\n debug,\n rtpHeaderExtensionsParser,\n} from \"../imports/rtp\";\nimport { deliveredTrackCodec } from \"./codecCompatibility\";\nimport type {\n RTCRtpReceiveParameters,\n RTCRtpSimulcastParameters,\n} from \"./parameters\";\nimport { RTCRtpReceiver } from \"./rtpReceiver\";\nimport type { RTCRtpSender } from \"./rtpSender\";\nimport type { RTCRtpTransceiver } from \"./rtpTransceiver\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/router.ts\");\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 log(\"registerRtpReceiver\", ssrc);\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: deliveredTrackCodec(\n transceiver.kind,\n params.codecs[i],\n params.codecs,\n ),\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 /**停止した transceiver の SSRC / RID 登録を解除する */\n unregisterTransceiver(transceiver: RTCRtpTransceiver) {\n const owners: (RTCRtpReceiver | RTCRtpSender)[] = [\n transceiver.sender,\n transceiver.receiver,\n ];\n for (const [ssrc, owner] of Object.entries(this.ssrcTable)) {\n if (owners.includes(owner)) {\n delete this.ssrcTable[Number(ssrc)];\n }\n }\n for (const [rid, owner] of Object.entries(this.ridTable)) {\n if (owners.includes(owner)) {\n delete this.ridTable[rid];\n }\n }\n }\n\n routeRtp = (packet: RtpPacket) => {\n const extensions: Extensions = rtpHeaderExtensionsParser(\n packet.header.extensions,\n this.extIdUriMap,\n );\n\n let rtpReceiver: 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 rtpReceiver = this.ridTable[rid] as RTCRtpReceiver | undefined;\n if (rtpReceiver) {\n rtpReceiver.latestRid = rid;\n rtpReceiver.handleRtpByRid(packet, rid, extensions);\n }\n } else if (rtpReceiver) {\n rtpReceiver.handleRtpBySsrc(packet, extensions);\n } else {\n // simulcast after send receiver report\n rtpReceiver = Object.values(this.ridTable)\n .filter((r): r is RTCRtpReceiver => r instanceof RTCRtpReceiver)\n .find((r) => r.trackBySSRC[packet.header.ssrc]);\n if (rtpReceiver) {\n log(\"simulcast register receiver by ssrc\", packet.header.ssrc);\n this.registerRtpReceiver(rtpReceiver, packet.header.ssrc);\n rtpReceiver.handleRtpBySsrc(packet, extensions);\n } else {\n // bug\n }\n }\n\n if (!rtpReceiver) {\n log(\"ssrcReceiver not found\");\n return;\n }\n\n const sdesMid = extensions[RTP_EXTENSION_URI.sdesMid];\n if (typeof sdesMid === \"string\") {\n rtpReceiver.sdesMid = sdesMid;\n }\n\n const repairedRid = extensions[\n RTP_EXTENSION_URI.repairedRtpStreamId\n ] as string;\n if (typeof repairedRid === \"string\") {\n rtpReceiver.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 {\n const remb = psfb.feedback as ReceiverEstimatedMaxBitrate;\n recipients.push(this.ssrcTable[remb.ssrcFeedbacks[0]]);\n }\n break;\n default:\n recipients.push(\n this.ssrcTable[psfb.feedback.senderSsrc] ||\n this.ssrcTable[psfb.feedback.mediaSsrc],\n );\n }\n }\n break;\n }\n recipients\n .filter((v) => v) // todo simulcast\n .forEach((recipient) => recipient.handleRtcpPacket(packet));\n };\n}\n"]}
|
|
@@ -64,12 +64,24 @@ export declare class RTCRtpReceiver {
|
|
|
64
64
|
get twccEnabled(): import("./parameters").RTCPFB | undefined;
|
|
65
65
|
get pliEnabled(): import("./parameters").RTCPFB | undefined;
|
|
66
66
|
prepareReceive(params: RTCRtpReceiveParameters): void;
|
|
67
|
+
/**
|
|
68
|
+
* negotiated codec と receiver の実処理状態を再同期する。
|
|
69
|
+
* codec map と RTX mapping を置換し、既存 remote track の codec
|
|
70
|
+
* metadata も新しい先頭 codec に更新する。
|
|
71
|
+
* 既存の receiverTWCC は破棄し、新しい codec が transport-cc を持ち
|
|
72
|
+
* remote SSRC が分かる場合だけ再生成する。
|
|
73
|
+
* setCodecPreferences() 後の createAnswer() 再解決や remote からの
|
|
74
|
+
* 再交渉では、除外された payload type の RTP を受け付けないようにする。
|
|
75
|
+
*/
|
|
76
|
+
resyncCodecs(params: RTCRtpReceiveParameters, mediaSourceSsrc?: number): void;
|
|
67
77
|
/**
|
|
68
78
|
* setup TWCC if supported
|
|
69
79
|
*/
|
|
70
80
|
setupTWCC(mediaSourceSsrc: number): void;
|
|
71
81
|
addTrack(track: MediaStreamTrack): boolean;
|
|
72
82
|
stop(): void;
|
|
83
|
+
/**transceiver の停止確定時に remote track を ended にする */
|
|
84
|
+
endTracks(): void;
|
|
73
85
|
runRtcp(): Promise<void>;
|
|
74
86
|
private getInboundRtpStatsId;
|
|
75
87
|
private getRemoteOutboundRtpStatsId;
|
|
@@ -6,6 +6,7 @@ const promises_1 = require("timers/promises");
|
|
|
6
6
|
const common_1 = require("../imports/common");
|
|
7
7
|
const rtp_1 = require("../imports/rtp");
|
|
8
8
|
const utils_1 = require("../utils");
|
|
9
|
+
const codecCompatibility_1 = require("./codecCompatibility");
|
|
9
10
|
const nack_1 = require("./receiver/nack");
|
|
10
11
|
const receiverTwcc_1 = require("./receiver/receiverTwcc");
|
|
11
12
|
const statistics_1 = require("./receiver/statistics");
|
|
@@ -289,6 +290,34 @@ class RTCRtpReceiver {
|
|
|
289
290
|
}
|
|
290
291
|
});
|
|
291
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* negotiated codec と receiver の実処理状態を再同期する。
|
|
295
|
+
* codec map と RTX mapping を置換し、既存 remote track の codec
|
|
296
|
+
* metadata も新しい先頭 codec に更新する。
|
|
297
|
+
* 既存の receiverTWCC は破棄し、新しい codec が transport-cc を持ち
|
|
298
|
+
* remote SSRC が分かる場合だけ再生成する。
|
|
299
|
+
* setCodecPreferences() 後の createAnswer() 再解決や remote からの
|
|
300
|
+
* 再交渉では、除外された payload type の RTP を受け付けないようにする。
|
|
301
|
+
*/
|
|
302
|
+
resyncCodecs(params, mediaSourceSsrc) {
|
|
303
|
+
for (const key of Object.keys(this.codecs)) {
|
|
304
|
+
delete this.codecs[Number(key)];
|
|
305
|
+
}
|
|
306
|
+
for (const key of Object.keys(this.ssrcByRtx)) {
|
|
307
|
+
delete this.ssrcByRtx[Number(key)];
|
|
308
|
+
}
|
|
309
|
+
this.prepareReceive(params);
|
|
310
|
+
const codec = (0, codecCompatibility_1.deliveredTrackCodec)(this.kind, params.codecs[0], params.codecs);
|
|
311
|
+
if (codec) {
|
|
312
|
+
for (const track of this.tracks) {
|
|
313
|
+
track.codec = codec;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
this.receiverTWCC = undefined;
|
|
317
|
+
if (mediaSourceSsrc != undefined) {
|
|
318
|
+
this.setupTWCC(mediaSourceSsrc);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
292
321
|
/**
|
|
293
322
|
* setup TWCC if supported
|
|
294
323
|
*/
|
|
@@ -326,6 +355,12 @@ class RTCRtpReceiver {
|
|
|
326
355
|
this.receiverTWCC.twccRunning = false;
|
|
327
356
|
this.nack.close();
|
|
328
357
|
}
|
|
358
|
+
/**transceiver の停止確定時に remote track を ended にする */
|
|
359
|
+
endTracks() {
|
|
360
|
+
for (const track of [...this.tracks, this.defaultTrack]) {
|
|
361
|
+
track.stop();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
329
364
|
async runRtcp() {
|
|
330
365
|
if (this.rtcpRunning || this.stopped)
|
|
331
366
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rtpReceiver.js","sourceRoot":"","sources":["../../../../src/media/rtpReceiver.ts"],"names":[],"mappings":";;;AAAA,mCAAoC;AACpC,8CAA6C;AAC7C,8CAA+C;AAE/C,wCAewB;AAIxB,oCAA0E;AAK1E,0CAA8C;AAC9C,0DAAuD;AACvD,sDAAyD;AAEzD,gCAAmD;AACnD,2DAA2D;AAC3D,mCAUiB;AACjB,mCAA2C;AAE3C,MAAM,GAAG,GAAG,IAAA,WAAK,EAAC,iDAAiD,CAAC,CAAC;AAErE,MAAa,cAAc;IAGzB,IAAY,UAAU;QACpB,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CACxC,CAAC;IACJ,CAAC;IAwCD,YACW,MAAkB,EACpB,IAAU,EACV,QAAgB;QAFvB;;;;mBAAS,MAAM;WAAY;QAC3B;;;;mBAAO,IAAI;WAAM;QACjB;;;;mBAAO,QAAQ;WAAQ;QAjDR;;;;mBAAkD,EAAE;WAAC;QACrD;;;;;WAA+B;QAM/B;;;;mBAA2C,EAAE;WAAC;QAC9C;;;;mBAAO,IAAI,kBAAW,CAAC,IAAI,CAAC;WAAC;QAC7B;;;;mBAAkB,IAAI,gBAAU,EAAE;WAAC;QAE3C;;;;mBAAO,UAAU;WAAC;QAClB;;;;mBAAO,IAAA,mBAAU,GAAE,CAAC,QAAQ,EAAE;WAAC;QAC/B;;;;mBAA6B,EAAE;WAAC;QAChC;;;;mBAAoD,EAAE;WAAC;QACvD;;;;mBAAkD,EAAE;WAAC;QAC9D;;WAEG;QACM;;;;mBAA8C,EAAE;WAAC;QAC1D,aAAa;QACJ;;;;mBAAqD,EAAE;WAAC;QACxD;;;;mBAAe,IAAI,CAAC,IAAI,CAAC,YAAY;WAAC;QACtC;;;;mBAAS,IAAI,cAAK,EAAgB;WAAC;QAE5C;;;;;WAAiC;QACjC;;;;;WAAiB;QACjB;;;;;WAAmB;QACnB;;;;;WAA2B;QAE3B;;;;;WAA4B;QAC5B;;;;mBAAU,KAAK;WAAC;QAChB;;;;;WAAwB;QACxB;;;;mBAA4B,EAAE;WAAC;QAC/B;;;;;WAAuB;QAEvB;;;;mBAAc,KAAK;WAAC;QACZ;;;;mBAAa,IAAI,eAAe,EAAE;WAAC;QACnC;;;;mBAAsD,EAAE;WAAC;QACzD;;;;mBAA0D,EAAE;WAAC;QAC7D;;;;mBAAqD,EAAE;WAAC;QACxD;;;;mBAAsD,EAAE;WAAC;QACzD;;;;mBAAqD,EAAE;WAAC;QACxD;;;;mBAA8C,EAAE;WAAC;QACjD;;;;mBAA6C,EAAE;WAAC;QAsUxD;;;;mBAAkB,CAAC,MAAiB,EAAE,UAAsB,EAAE,EAAE;gBAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAEnD,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;YAC5C,CAAC;WAAC;QAEF;;;;mBAAiB,CAAC,MAAiB,EAAE,GAAW,EAAE,UAAsB,EAAE,EAAE;gBAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBACnC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;gBAC/C,CAAC;gBAED,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;YAC5C,CAAC;WAAC;QA5UA,IAAI,CAAC,YAAY,GAAG,IAAI,wBAAgB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;YACnC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC;gBACxC,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC;IACpC,CAAC;IAED,gBAAgB,CAAC,IAAsB;QACrC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,WAAW;IACX,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC;IAC7C,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IACzE,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAA,sBAAO,GAAE,CAAC,IAAI,CACjC,CAAC;IACJ,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAA,qBAAM,GAAE,CAAC,IAAI,CAChC,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,MAA+B;QAC5C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YAC1B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YAC7B,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;gBACV,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACtC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,eAAuB;QAC/B,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC3C,IAAI,CAAC,YAAY,GAAG,IAAI,2BAAY,CAClC,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,QAAQ,EACb,eAAe,CAChB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,KAAuB;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YACnC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;gBACV,OAAO,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC;YAC7B,CAAC;YACD,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBACX,OAAO,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACvC,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAExB,IAAI,IAAI,CAAC,YAAY;YAAE,IAAI,CAAC,YAAY,CAAC,WAAW,GAAG,KAAK,CAAC;QAC7D,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QAC7C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;gBACxB,MAAM,IAAA,qBAAU,EAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE;oBACtD,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM;iBAC/B,CAAC,CAAC;gBAEH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,CACpD,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;oBACjB,IAAI,eAAe,GAAG,CAAC,EACrB,gBAAgB,GAAG,CAAC,CAAC;oBACvB,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC/B,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;wBAC7C,MAAM,YAAY,GAChB,IAAA,wBAAgB,GAAE,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;wBACzD,IAAI,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,KAAK,EAAE,CAAC;4BAC7C,gBAAgB,GAAG,IAAA,YAAG,EAAC,YAAY,GAAG,KAAK,CAAC,CAAC;wBAC/C,CAAC;oBACH,CAAC;oBAED,OAAO,IAAI,sBAAgB,CAAC;wBAC1B,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;wBAClB,YAAY,EAAE,MAAM,CAAC,aAAa;wBAClC,WAAW,EAAE,MAAM,CAAC,YAAY;wBAChC,eAAe,EAAE,MAAM,CAAC,OAAO;wBAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;wBACrB,GAAG,EAAE,eAAe;wBACpB,IAAI,EAAE,gBAAgB;qBACvB,CAAC,CAAC;gBACL,CAAC,CACF,CAAC;gBAEF,MAAM,MAAM,GAAG,IAAI,kBAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;gBAElE,IAAI,CAAC;oBACH,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;wBAC1C,MAAM,IAAA,qBAAU,EAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;oBAC1D,CAAC;oBACD,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC9C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,GAAG,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;oBAC9B,MAAM,IAAA,qBAAU,EAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC,CAAA,CAAC;IACpB,CAAC;IAEO,oBAAoB,CAAC,KAAuB;QAClD,OAAO,IAAA,uBAAe,EAAC,aAAa,EAAE,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;IAEO,2BAA2B,CAAC,KAAuB;QACzD,OAAO,IAAA,uBAAe,EAAC,qBAAqB,EAAE,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IAED,eAAe,CAAC,QAA2B;QACzC,OAAO,IAAI,CAAC,MAAM;aACf,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC;aAC1D,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;aAC7B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,YAAY,CAAC,SAAiB;QAC5B,MAAM,KAAK,GAAe,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa;YACpC,CAAC,CAAC,IAAA,uBAAe,EAAC,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YACrD,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;QAE1C,+BAA+B;QAC/B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,IAAI;gBAAE,SAAS;YAE1B,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEnD,oBAAoB;YACpB,MAAM,kBAAkB,GACtB,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC;YACxD,MAAM,QAAQ,GACZ,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,kBAAkB;gBAClE,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC;gBACzC,CAAC,CAAC,SAAS,CAAC;YAChB,MAAM,OAAO,GACX,WAAW,IAAI,WAAW;gBACxB,CAAC,CAAC,IAAA,4BAAoB,EAClB,WAAW,EACX,WAAW,CAAC,WAAW,EACvB,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI,CACvB;gBACH,CAAC,CAAC,SAAS,CAAC;YAEhB,IACE,WAAW;gBACX,WAAW;gBACX,OAAO;gBACP,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAC7B,CAAC;gBACD,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC7B,MAAM,UAAU,GAAkB;oBAChC,IAAI,EAAE,OAAO;oBACb,EAAE,EAAE,OAAO;oBACX,SAAS;oBACT,WAAW,EAAE,WAAW,CAAC,WAAW;oBACpC,WAAW;oBACX,QAAQ,EAAE,WAAW,CAAC,QAAQ;oBAC9B,SAAS,EAAE,WAAW,CAAC,SAAS;oBAChC,QAAQ,EAAE,WAAW,CAAC,QAAQ;oBAC9B,WAAW,EAAE,WAAW,CAAC,UAAU;iBACpC,CAAC;gBACF,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACzB,CAAC;YAED,MAAM,eAAe,GAA6B;gBAChD,IAAI,EAAE,aAAa;gBACnB,EAAE,EAAE,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;gBACpC,SAAS;gBACT,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW;gBACX,OAAO;gBACP,GAAG,EAAE,IAAI,CAAC,OAAO;gBACjB,eAAe,EAAE,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,IAAI;gBACvC,eAAe,EAAE,WAAW,EAAE,gBAAgB,IAAI,CAAC;gBACnD,aAAa,EAAE,WAAW,EAAE,aAAa,IAAI,CAAC;gBAC9C,mBAAmB,EAAE,WAAW,EAAE,mBAAmB,IAAI,CAAC;gBAC1D,WAAW,EAAE,WAAW,EAAE,YAAY,IAAI,CAAC;gBAC3C,MAAM,EAAE,WAAW,EAAE,SAAS;oBAC5B,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,WAAW,CAAC,SAAS;oBAC5C,CAAC,CAAC,SAAS;gBACb,2BAA2B,EAAE,WAAW,EAAE,2BAA2B;gBACrE,QAAQ;gBACR,SAAS,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS;gBACxD,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS;aACvD,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAE5B,iDAAiD;YACjD,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,mBAAmB,GAAoC;oBAC3D,IAAI,EAAE,qBAAqB;oBAC3B,EAAE,EAAE,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC;oBAC3C,SAAS;oBACT,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,WAAW;oBACX,OAAO,EAAE,eAAe,CAAC,OAAO;oBAChC,OAAO,EAAE,eAAe,CAAC,EAAE;oBAC3B,eAAe,EAAE,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC;oBACxD,WAAW,EAAE,IAAI,CAAC,2BAA2B,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;oBAC9D,WAAW,EAAE,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,IAAI,CAAC;oBACrD,SAAS,EAAE,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC;iBACnD,CAAC;gBACF,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,SAAS,GAAG,IAAA,yBAAiB,GAAE,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAE3C,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;QAED,OAAO,IAAA,wBAAgB,EAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,SAAiB;QACjC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,GAAG,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,GAAG,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,IAAI,iCAA2B,CAAC;YAC7C,QAAQ,EAAE,IAAI,2BAAqB,CAAC;gBAClC,UAAU,EAAE,IAAI,CAAC,QAAQ;gBACzB,SAAS;aACV,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC;YACH,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;gBAC5B,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAC5C,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IAED,gBAAgB,CAAC,MAAkB;QACjC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,kBAAY,CAAC,IAAI;gBACpB,CAAC;oBACC,MAAM,EAAE,GAAG,MAAsB,CAAC;oBAClC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,IAAA,kBAAU,EACxC,EAAE,CAAC,UAAU,CAAC,YAAY,CAC3B,CAAC;oBACF,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,IAAA,wBAAgB,GAAE,CAAC;oBAC1D,IAAI,CAAC,2BAA2B,CAAC,EAAE,CAAC,IAAI,CAAC;wBACvC,CAAC,IAAI,CAAC,2BAA2B,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;oBACvD,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,IAAA,wBAAgB,EACrD,EAAE,CAAC,UAAU,CAAC,YAAY,CAC3B,CAAC;oBACF,IAAI,CAAC,uBAAuB,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;oBAClE,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;oBAEhE,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oBAC5C,IAAI,KAAK,EAAE,CAAC;wBACV,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;oBACtC,CAAC;gBACH,CAAC;gBACD,MAAM;QACV,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAiBO,SAAS,CACf,MAAiB,EACjB,UAAsB,EACtB,KAAwB;QAExB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACrD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,qDAAqD;YACrD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;YACpC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBACtC,IAAI,6BAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAEnD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,MAAM,uBAAuB,GAAG,UAAU,CACxC,uBAAiB,CAAC,eAAe,CACR,CAAC;YAE5B,IAAI,CAAC,uBAAuB,IAAI,SAAS,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;YAC/B,CAAC;YAED,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC5B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;YACvC,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACxD,MAAM,WAAW,GAAG,IAAA,+BAAyB,EAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;YACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YACjD,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO;YAEtC,MAAM,GAAG,IAAA,eAAS,EAAC,MAAM,EAAE,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YAC/D,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QACzC,CAAC;QAED,IAAI,GAAoB,CAAC;QACzB,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;YACvC,GAAG,GAAG,SAAG,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACtC,IACE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAChC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CACxC,EACD,CAAC;gBACD,OAAO;YACT,CAAC;QACH,CAAC;QAED,IAAI,KAAK,EAAE,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,GAAG,EAAE,CAAC;gBACR,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;oBACxD,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;wBAC9B,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC;oBACzD,CAAC;gBACH,CAAC;qBAAM,CAAC;gBACR,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QAED,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;CACF;AA9cD,wCA8cC","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"]}
|
|
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 { deliveredTrackCodec } from \"./codecCompatibility\";\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 * negotiated codec と receiver の実処理状態を再同期する。\n * codec map と RTX mapping を置換し、既存 remote track の codec\n * metadata も新しい先頭 codec に更新する。\n * 既存の receiverTWCC は破棄し、新しい codec が transport-cc を持ち\n * remote SSRC が分かる場合だけ再生成する。\n * setCodecPreferences() 後の createAnswer() 再解決や remote からの\n * 再交渉では、除外された payload type の RTP を受け付けないようにする。\n */\n resyncCodecs(params: RTCRtpReceiveParameters, mediaSourceSsrc?: number) {\n for (const key of Object.keys(this.codecs)) {\n delete this.codecs[Number(key)];\n }\n for (const key of Object.keys(this.ssrcByRtx)) {\n delete this.ssrcByRtx[Number(key)];\n }\n this.prepareReceive(params);\n const codec = deliveredTrackCodec(\n this.kind,\n params.codecs[0],\n params.codecs,\n );\n if (codec) {\n for (const track of this.tracks) {\n track.codec = codec;\n }\n }\n this.receiverTWCC = undefined;\n if (mediaSourceSsrc != undefined) {\n this.setupTWCC(mediaSourceSsrc);\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 /**transceiver の停止確定時に remote track を ended にする */\n endTracks() {\n for (const track of [...this.tracks, this.defaultTrack]) {\n track.stop();\n }\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"]}
|