werift 0.24.4 → 0.25.0-alpha.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
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type MediaKind = "audio" | "video";
|
|
2
|
+
export declare const polyfillSupportedConstraints: {
|
|
3
|
+
readonly deviceId: true;
|
|
4
|
+
readonly groupId: true;
|
|
5
|
+
readonly mimeType: true;
|
|
6
|
+
};
|
|
7
|
+
export type PolyfillConstraintName = keyof typeof polyfillSupportedConstraints;
|
|
8
|
+
export interface MediaRegisterCandidate {
|
|
9
|
+
deviceId: string;
|
|
10
|
+
groupId?: string;
|
|
11
|
+
mimeType: string;
|
|
12
|
+
kinds: readonly MediaKind[];
|
|
13
|
+
}
|
|
14
|
+
type ConstrainDomString = string | string[] | {
|
|
15
|
+
exact?: string | string[];
|
|
16
|
+
ideal?: string | string[];
|
|
17
|
+
};
|
|
18
|
+
export interface PolyfillTrackConstraintSet {
|
|
19
|
+
deviceId?: ConstrainDomString;
|
|
20
|
+
groupId?: ConstrainDomString;
|
|
21
|
+
mimeType?: ConstrainDomString;
|
|
22
|
+
}
|
|
23
|
+
export interface PolyfillTrackConstraints extends PolyfillTrackConstraintSet {
|
|
24
|
+
advanced?: PolyfillTrackConstraintSet[];
|
|
25
|
+
}
|
|
26
|
+
export declare function assertRequestedMediaTypes(constraints: {
|
|
27
|
+
audio?: unknown;
|
|
28
|
+
video?: unknown;
|
|
29
|
+
}): void;
|
|
30
|
+
export declare function selectRegisterForKind(kind: MediaKind, trackConstraints: boolean | PolyfillTrackConstraints, candidates: readonly MediaRegisterCandidate[]): MediaRegisterCandidate;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.polyfillSupportedConstraints = void 0;
|
|
4
|
+
exports.assertRequestedMediaTypes = assertRequestedMediaTypes;
|
|
5
|
+
exports.selectRegisterForKind = selectRegisterForKind;
|
|
6
|
+
const errors_1 = require("../errors");
|
|
7
|
+
exports.polyfillSupportedConstraints = {
|
|
8
|
+
deviceId: true,
|
|
9
|
+
groupId: true,
|
|
10
|
+
mimeType: true,
|
|
11
|
+
};
|
|
12
|
+
const CONSTRAINT_NAMES = [
|
|
13
|
+
"deviceId",
|
|
14
|
+
"groupId",
|
|
15
|
+
"mimeType",
|
|
16
|
+
];
|
|
17
|
+
function assertRequestedMediaTypes(constraints) {
|
|
18
|
+
if (!constraints.audio && !constraints.video) {
|
|
19
|
+
throw (0, errors_1.createWebRtcTypeError)("Failed to execute 'getUserMedia' on 'MediaDevices': At least one of audio and video must be requested");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function selectRegisterForKind(kind, trackConstraints, candidates) {
|
|
23
|
+
const ofKind = candidates.filter((candidate) => candidate.kinds.includes(kind));
|
|
24
|
+
if (ofKind.length === 0) {
|
|
25
|
+
throw (0, errors_1.createWebRtcDomException)("NotFoundError", `Requested device not found (${kind})`);
|
|
26
|
+
}
|
|
27
|
+
if (trackConstraints === false) {
|
|
28
|
+
throw (0, errors_1.createWebRtcTypeError)("selectRegisterForKind was called for a kind that was not requested");
|
|
29
|
+
}
|
|
30
|
+
const constraintSet = trackConstraints === true ? {} : stripUnsupported(trackConstraints);
|
|
31
|
+
const { advanced = [], ...basic } = constraintSet;
|
|
32
|
+
const selected = selectSettings(ofKind, basic, advanced);
|
|
33
|
+
if (!selected) {
|
|
34
|
+
throw new errors_1.OverconstrainedError(findFailedConstraint(ofKind, basic) ?? "", "Cannot satisfy required constraints");
|
|
35
|
+
}
|
|
36
|
+
return selected;
|
|
37
|
+
}
|
|
38
|
+
function stripUnsupported(constraints) {
|
|
39
|
+
const next = {};
|
|
40
|
+
for (const name of CONSTRAINT_NAMES) {
|
|
41
|
+
if (constraints[name] != undefined) {
|
|
42
|
+
next[name] = constraints[name];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (constraints.advanced) {
|
|
46
|
+
next.advanced = constraints.advanced.map((entry) => {
|
|
47
|
+
const stripped = {};
|
|
48
|
+
for (const name of CONSTRAINT_NAMES) {
|
|
49
|
+
if (entry[name] != undefined) {
|
|
50
|
+
stripped[name] = entry[name];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return stripped;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return next;
|
|
57
|
+
}
|
|
58
|
+
function selectSettings(candidates, basic, advanced) {
|
|
59
|
+
let remaining = candidates.filter((candidate) => fitnessDistance(candidate, basic, "ideal") < Number.POSITIVE_INFINITY);
|
|
60
|
+
if (remaining.length === 0) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
for (const constraintSet of advanced) {
|
|
64
|
+
const narrowed = remaining.filter((candidate) => fitnessDistance(candidate, constraintSet, "exact") <
|
|
65
|
+
Number.POSITIVE_INFINITY);
|
|
66
|
+
if (narrowed.length > 0) {
|
|
67
|
+
remaining = narrowed;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
let best = remaining[0];
|
|
71
|
+
let bestDistance = fitnessDistance(best, basic, "ideal");
|
|
72
|
+
for (const candidate of remaining.slice(1)) {
|
|
73
|
+
const distance = fitnessDistance(candidate, basic, "ideal");
|
|
74
|
+
if (distance < bestDistance) {
|
|
75
|
+
best = candidate;
|
|
76
|
+
bestDistance = distance;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return best;
|
|
80
|
+
}
|
|
81
|
+
function findFailedConstraint(candidates, basic) {
|
|
82
|
+
for (const name of CONSTRAINT_NAMES) {
|
|
83
|
+
const constraint = basic[name];
|
|
84
|
+
if (!isRequired(constraint)) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const anyFinite = candidates.some((candidate) => fitnessDistance(candidate, { [name]: constraint }, "ideal") <
|
|
88
|
+
Number.POSITIVE_INFINITY);
|
|
89
|
+
if (!anyFinite) {
|
|
90
|
+
return name;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
function fitnessDistance(candidate, constraintSet, bareMode) {
|
|
96
|
+
let distance = 0;
|
|
97
|
+
for (const name of CONSTRAINT_NAMES) {
|
|
98
|
+
const constraint = constraintSet[name];
|
|
99
|
+
if (constraint == undefined) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const actual = readSetting(candidate, name);
|
|
103
|
+
const next = constrainDomStringDistance(actual, constraint, bareMode);
|
|
104
|
+
if (next === Number.POSITIVE_INFINITY) {
|
|
105
|
+
return Number.POSITIVE_INFINITY;
|
|
106
|
+
}
|
|
107
|
+
distance += next;
|
|
108
|
+
}
|
|
109
|
+
return distance;
|
|
110
|
+
}
|
|
111
|
+
function readSetting(candidate, name) {
|
|
112
|
+
switch (name) {
|
|
113
|
+
case "deviceId":
|
|
114
|
+
return candidate.deviceId;
|
|
115
|
+
case "groupId":
|
|
116
|
+
return candidate.groupId;
|
|
117
|
+
case "mimeType":
|
|
118
|
+
return candidate.mimeType;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function constrainDomStringDistance(actual, constraint, bareMode) {
|
|
122
|
+
const { exact, ideal } = normalizeConstrainDomString(constraint, bareMode);
|
|
123
|
+
if (exact && !matchesDomString(actual, exact)) {
|
|
124
|
+
return Number.POSITIVE_INFINITY;
|
|
125
|
+
}
|
|
126
|
+
if (!ideal) {
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
return matchesDomString(actual, ideal) ? 0 : 1;
|
|
130
|
+
}
|
|
131
|
+
function normalizeConstrainDomString(constraint, bareMode) {
|
|
132
|
+
if (typeof constraint === "string" || Array.isArray(constraint)) {
|
|
133
|
+
const values = toStringList(constraint);
|
|
134
|
+
return bareMode === "exact" ? { exact: values } : { ideal: values };
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
exact: constraint.exact ? toStringList(constraint.exact) : undefined,
|
|
138
|
+
ideal: constraint.ideal ? toStringList(constraint.ideal) : undefined,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function toStringList(value) {
|
|
142
|
+
return Array.isArray(value) ? value : [value];
|
|
143
|
+
}
|
|
144
|
+
function matchesDomString(actual, expected) {
|
|
145
|
+
return actual != undefined && expected.includes(actual);
|
|
146
|
+
}
|
|
147
|
+
function isRequired(constraint) {
|
|
148
|
+
if (constraint == undefined) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
if (typeof constraint === "string" || Array.isArray(constraint)) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
return constraint.exact != undefined;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=selectSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selectSettings.js","sourceRoot":"","sources":["../../../../src/polyfill/selectSettings.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n OverconstrainedError,\n createWebRtcDomException,\n createWebRtcTypeError,\n} from \"../errors\";\n\nexport type MediaKind = \"audio\" | \"video\";\n\nexport const polyfillSupportedConstraints = {\n deviceId: true,\n groupId: true,\n mimeType: true,\n} as const;\n\nexport type PolyfillConstraintName = keyof typeof polyfillSupportedConstraints;\n\nexport interface MediaRegisterCandidate {\n deviceId: string;\n groupId?: string;\n mimeType: string;\n kinds: readonly MediaKind[];\n}\n\ntype ConstrainDomString =\n | string\n | string[]\n | {\n exact?: string | string[];\n ideal?: string | string[];\n };\n\nexport interface PolyfillTrackConstraintSet {\n deviceId?: ConstrainDomString;\n groupId?: ConstrainDomString;\n mimeType?: ConstrainDomString;\n}\n\nexport interface PolyfillTrackConstraints extends PolyfillTrackConstraintSet {\n advanced?: PolyfillTrackConstraintSet[];\n}\n\nconst CONSTRAINT_NAMES: PolyfillConstraintName[] = [\n \"deviceId\",\n \"groupId\",\n \"mimeType\",\n];\n\nexport function assertRequestedMediaTypes(constraints: {\n audio?: unknown;\n video?: unknown;\n}) {\n if (!constraints.audio && !constraints.video) {\n throw createWebRtcTypeError(\n \"Failed to execute 'getUserMedia' on 'MediaDevices': At least one of audio and video must be requested\",\n );\n }\n}\n\nexport function selectRegisterForKind(\n kind: MediaKind,\n trackConstraints: boolean | PolyfillTrackConstraints,\n candidates: readonly MediaRegisterCandidate[],\n): MediaRegisterCandidate {\n const ofKind = candidates.filter((candidate) =>\n candidate.kinds.includes(kind),\n );\n if (ofKind.length === 0) {\n throw createWebRtcDomException(\n \"NotFoundError\",\n `Requested device not found (${kind})`,\n );\n }\n\n if (trackConstraints === false) {\n throw createWebRtcTypeError(\n \"selectRegisterForKind was called for a kind that was not requested\",\n );\n }\n\n const constraintSet =\n trackConstraints === true ? {} : stripUnsupported(trackConstraints);\n const { advanced = [], ...basic } = constraintSet;\n\n const selected = selectSettings(ofKind, basic, advanced);\n if (!selected) {\n throw new OverconstrainedError(\n findFailedConstraint(ofKind, basic) ?? \"\",\n \"Cannot satisfy required constraints\",\n );\n }\n return selected;\n}\n\nfunction stripUnsupported(\n constraints: PolyfillTrackConstraints,\n): PolyfillTrackConstraints {\n const next: PolyfillTrackConstraints = {};\n for (const name of CONSTRAINT_NAMES) {\n if (constraints[name] != undefined) {\n next[name] = constraints[name];\n }\n }\n if (constraints.advanced) {\n next.advanced = constraints.advanced.map((entry) => {\n const stripped: PolyfillTrackConstraintSet = {};\n for (const name of CONSTRAINT_NAMES) {\n if (entry[name] != undefined) {\n stripped[name] = entry[name];\n }\n }\n return stripped;\n });\n }\n return next;\n}\n\nfunction selectSettings(\n candidates: readonly MediaRegisterCandidate[],\n basic: PolyfillTrackConstraintSet,\n advanced: PolyfillTrackConstraintSet[],\n): MediaRegisterCandidate | undefined {\n let remaining = candidates.filter(\n (candidate) =>\n fitnessDistance(candidate, basic, \"ideal\") < Number.POSITIVE_INFINITY,\n );\n if (remaining.length === 0) {\n return undefined;\n }\n\n for (const constraintSet of advanced) {\n const narrowed = remaining.filter(\n (candidate) =>\n fitnessDistance(candidate, constraintSet, \"exact\") <\n Number.POSITIVE_INFINITY,\n );\n if (narrowed.length > 0) {\n remaining = narrowed;\n }\n }\n\n let best = remaining[0];\n let bestDistance = fitnessDistance(best, basic, \"ideal\");\n for (const candidate of remaining.slice(1)) {\n const distance = fitnessDistance(candidate, basic, \"ideal\");\n if (distance < bestDistance) {\n best = candidate;\n bestDistance = distance;\n }\n }\n return best;\n}\n\nfunction findFailedConstraint(\n candidates: readonly MediaRegisterCandidate[],\n basic: PolyfillTrackConstraintSet,\n): string | undefined {\n for (const name of CONSTRAINT_NAMES) {\n const constraint = basic[name];\n if (!isRequired(constraint)) {\n continue;\n }\n const anyFinite = candidates.some(\n (candidate) =>\n fitnessDistance(candidate, { [name]: constraint }, \"ideal\") <\n Number.POSITIVE_INFINITY,\n );\n if (!anyFinite) {\n return name;\n }\n }\n return undefined;\n}\n\nfunction fitnessDistance(\n candidate: MediaRegisterCandidate,\n constraintSet: PolyfillTrackConstraintSet,\n bareMode: \"ideal\" | \"exact\",\n): number {\n let distance = 0;\n for (const name of CONSTRAINT_NAMES) {\n const constraint = constraintSet[name];\n if (constraint == undefined) {\n continue;\n }\n const actual = readSetting(candidate, name);\n const next = constrainDomStringDistance(actual, constraint, bareMode);\n if (next === Number.POSITIVE_INFINITY) {\n return Number.POSITIVE_INFINITY;\n }\n distance += next;\n }\n return distance;\n}\n\nfunction readSetting(\n candidate: MediaRegisterCandidate,\n name: PolyfillConstraintName,\n): string | undefined {\n switch (name) {\n case \"deviceId\":\n return candidate.deviceId;\n case \"groupId\":\n return candidate.groupId;\n case \"mimeType\":\n return candidate.mimeType;\n }\n}\n\nfunction constrainDomStringDistance(\n actual: string | undefined,\n constraint: ConstrainDomString,\n bareMode: \"ideal\" | \"exact\",\n): number {\n const { exact, ideal } = normalizeConstrainDomString(constraint, bareMode);\n if (exact && !matchesDomString(actual, exact)) {\n return Number.POSITIVE_INFINITY;\n }\n if (!ideal) {\n return 0;\n }\n return matchesDomString(actual, ideal) ? 0 : 1;\n}\n\nfunction normalizeConstrainDomString(\n constraint: ConstrainDomString,\n bareMode: \"ideal\" | \"exact\",\n): { exact?: string[]; ideal?: string[] } {\n if (typeof constraint === \"string\" || Array.isArray(constraint)) {\n const values = toStringList(constraint);\n return bareMode === \"exact\" ? { exact: values } : { ideal: values };\n }\n return {\n exact: constraint.exact ? toStringList(constraint.exact) : undefined,\n ideal: constraint.ideal ? toStringList(constraint.ideal) : undefined,\n };\n}\n\nfunction toStringList(value: string | string[]): string[] {\n return Array.isArray(value) ? value : [value];\n}\n\nfunction matchesDomString(actual: string | undefined, expected: string[]) {\n return actual != undefined && expected.includes(actual);\n}\n\nfunction isRequired(constraint: ConstrainDomString | undefined) {\n if (constraint == undefined) {\n return false;\n }\n if (typeof constraint === \"string\" || Array.isArray(constraint)) {\n return false;\n }\n return constraint.exact != undefined;\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Socket } from "dgram";
|
|
2
|
+
import { Readable } from "stream";
|
|
3
|
+
export type BinaryLike = Buffer | ArrayBuffer | ArrayBufferView;
|
|
4
|
+
export type UdpOrStreamSource = {
|
|
5
|
+
udp: {
|
|
6
|
+
port: number;
|
|
7
|
+
address?: string;
|
|
8
|
+
};
|
|
9
|
+
stream?: never;
|
|
10
|
+
} | {
|
|
11
|
+
udp?: never;
|
|
12
|
+
stream: Readable | ReadableStream<Uint8Array>;
|
|
13
|
+
};
|
|
14
|
+
export declare function toBuffer(value: BinaryLike | string): Buffer;
|
|
15
|
+
export declare function openPacketSource(source: UdpOrStreamSource, onPacket: (packet: Buffer) => void, onError?: (error: DOMException) => void, signal?: AbortSignal, onClose?: () => void): Promise<() => void>;
|
|
16
|
+
export declare function throwIfAborted(signal?: AbortSignal): void;
|
|
17
|
+
export type UdpSocketFactory = () => Socket;
|
|
18
|
+
export declare function setUdpSocketFactory(factory?: UdpSocketFactory): void;
|
|
19
|
+
export declare function encodeLengthPrefixed(packet: Buffer): Buffer<ArrayBuffer>;
|
|
20
|
+
export declare function readEntireStream(stream: Readable | ReadableStream<Uint8Array>, signal?: AbortSignal): Promise<Buffer<ArrayBuffer>>;
|
|
21
|
+
export declare function isWebmContainer(buffer: Buffer): boolean;
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toBuffer = toBuffer;
|
|
4
|
+
exports.openPacketSource = openPacketSource;
|
|
5
|
+
exports.throwIfAborted = throwIfAborted;
|
|
6
|
+
exports.setUdpSocketFactory = setUdpSocketFactory;
|
|
7
|
+
exports.encodeLengthPrefixed = encodeLengthPrefixed;
|
|
8
|
+
exports.readEntireStream = readEntireStream;
|
|
9
|
+
exports.isWebmContainer = isWebmContainer;
|
|
10
|
+
const dgram_1 = require("dgram");
|
|
11
|
+
const stream_1 = require("stream");
|
|
12
|
+
const errors_1 = require("../errors");
|
|
13
|
+
function toBuffer(value) {
|
|
14
|
+
if (Buffer.isBuffer(value)) {
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
if (typeof value === "string") {
|
|
18
|
+
return Buffer.from(value);
|
|
19
|
+
}
|
|
20
|
+
if (ArrayBuffer.isView(value)) {
|
|
21
|
+
return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
22
|
+
}
|
|
23
|
+
return Buffer.from(new Uint8Array(value));
|
|
24
|
+
}
|
|
25
|
+
async function openPacketSource(source, onPacket, onError, signal, onClose) {
|
|
26
|
+
throwIfAborted(signal);
|
|
27
|
+
if ("udp" in source && source.udp) {
|
|
28
|
+
return bindUdp(source.udp, onPacket, onError, signal);
|
|
29
|
+
}
|
|
30
|
+
return openSharedStreamSource(source.stream, onPacket, onError, signal, onClose);
|
|
31
|
+
}
|
|
32
|
+
function throwIfAborted(signal) {
|
|
33
|
+
if (signal?.aborted) {
|
|
34
|
+
throw (0, errors_1.createWebRtcDomException)("AbortError", "The operation was aborted");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
let udpSocketFactory = () => (0, dgram_1.createSocket)("udp4");
|
|
38
|
+
function setUdpSocketFactory(factory) {
|
|
39
|
+
udpSocketFactory = factory ?? (() => (0, dgram_1.createSocket)("udp4"));
|
|
40
|
+
}
|
|
41
|
+
async function bindUdp(udp, onPacket, onError, signal) {
|
|
42
|
+
const socket = udpSocketFactory();
|
|
43
|
+
try {
|
|
44
|
+
await new Promise((resolve, reject) => {
|
|
45
|
+
const onBindError = (error) => {
|
|
46
|
+
cleanup();
|
|
47
|
+
reject(error);
|
|
48
|
+
};
|
|
49
|
+
const onListening = () => {
|
|
50
|
+
cleanup();
|
|
51
|
+
resolve();
|
|
52
|
+
};
|
|
53
|
+
const onAbort = () => {
|
|
54
|
+
cleanup();
|
|
55
|
+
socket.close();
|
|
56
|
+
reject((0, errors_1.createWebRtcDomException)("AbortError", "The operation was aborted"));
|
|
57
|
+
};
|
|
58
|
+
const cleanup = () => {
|
|
59
|
+
socket.off("error", onBindError);
|
|
60
|
+
socket.off("listening", onListening);
|
|
61
|
+
signal?.removeEventListener("abort", onAbort);
|
|
62
|
+
};
|
|
63
|
+
if (signal?.aborted) {
|
|
64
|
+
onAbort();
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
socket.once("error", onBindError);
|
|
68
|
+
socket.once("listening", onListening);
|
|
69
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
70
|
+
if (signal?.aborted) {
|
|
71
|
+
onAbort();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
socket.bind(udp.port, udp.address ?? "0.0.0.0");
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
socket.close();
|
|
79
|
+
if (error instanceof DOMException && error.name === "AbortError") {
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
throw (0, errors_1.createWebRtcDomException)("NotReadableError", error instanceof Error ? error.message : "Failed to bind UDP socket");
|
|
83
|
+
}
|
|
84
|
+
const onMessage = (message) => {
|
|
85
|
+
onPacket(Buffer.from(message));
|
|
86
|
+
};
|
|
87
|
+
const onSocketError = (error) => {
|
|
88
|
+
onError?.((0, errors_1.createWebRtcDomException)("NotReadableError", error.message || "UDP socket error"));
|
|
89
|
+
};
|
|
90
|
+
const stop = () => {
|
|
91
|
+
socket.off("message", onMessage);
|
|
92
|
+
socket.off("error", onSocketError);
|
|
93
|
+
signal?.removeEventListener("abort", stop);
|
|
94
|
+
try {
|
|
95
|
+
socket.close();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// already closed
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
socket.on("message", onMessage);
|
|
102
|
+
socket.on("error", onSocketError);
|
|
103
|
+
signal?.addEventListener("abort", stop, { once: true });
|
|
104
|
+
if (signal?.aborted) {
|
|
105
|
+
stop();
|
|
106
|
+
throwIfAborted(signal);
|
|
107
|
+
}
|
|
108
|
+
return stop;
|
|
109
|
+
}
|
|
110
|
+
const streamHubs = new WeakMap();
|
|
111
|
+
function openSharedStreamSource(stream, onPacket, onError, signal, onClose) {
|
|
112
|
+
throwIfAborted(signal);
|
|
113
|
+
let hub = streamHubs.get(stream);
|
|
114
|
+
if (!hub) {
|
|
115
|
+
hub = createStreamHub(stream);
|
|
116
|
+
streamHubs.set(stream, hub);
|
|
117
|
+
}
|
|
118
|
+
return hub.subscribe(onPacket, onError, signal, onClose);
|
|
119
|
+
}
|
|
120
|
+
function createStreamHub(stream) {
|
|
121
|
+
const listeners = new Set();
|
|
122
|
+
const errorListeners = new Set();
|
|
123
|
+
const closeListeners = new Set();
|
|
124
|
+
const abort = new AbortController();
|
|
125
|
+
let reader;
|
|
126
|
+
if (!(stream instanceof stream_1.Readable)) {
|
|
127
|
+
try {
|
|
128
|
+
reader = stream.getReader();
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
throw (0, errors_1.createWebRtcDomException)("NotReadableError", error instanceof Error ? error.message : "Failed to lock media stream");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const run = (async () => {
|
|
135
|
+
let pending = Buffer.alloc(0);
|
|
136
|
+
for await (const chunk of iterateBytes(stream, abort.signal, reader)) {
|
|
137
|
+
pending = Buffer.concat([pending, chunk]);
|
|
138
|
+
while (pending.length >= 4) {
|
|
139
|
+
const size = pending.readUInt32BE(0);
|
|
140
|
+
if (pending.length < 4 + size) {
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
const packet = Buffer.from(pending.subarray(4, 4 + size));
|
|
144
|
+
pending = pending.subarray(4 + size);
|
|
145
|
+
for (const listener of [...listeners]) {
|
|
146
|
+
listener(packet);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
})();
|
|
151
|
+
run.then(() => {
|
|
152
|
+
for (const onClose of [...closeListeners]) {
|
|
153
|
+
onClose();
|
|
154
|
+
}
|
|
155
|
+
}, (error) => {
|
|
156
|
+
const mapped = mapStreamError(error, abort.signal);
|
|
157
|
+
if (mapped.name === "AbortError") {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
for (const onError of [...errorListeners]) {
|
|
161
|
+
onError(mapped);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
return {
|
|
165
|
+
subscribe(onPacket, onError, signal, onClose) {
|
|
166
|
+
throwIfAborted(signal);
|
|
167
|
+
listeners.add(onPacket);
|
|
168
|
+
if (onError) {
|
|
169
|
+
errorListeners.add(onError);
|
|
170
|
+
}
|
|
171
|
+
if (onClose) {
|
|
172
|
+
closeListeners.add(onClose);
|
|
173
|
+
}
|
|
174
|
+
const stop = () => {
|
|
175
|
+
listeners.delete(onPacket);
|
|
176
|
+
if (onError) {
|
|
177
|
+
errorListeners.delete(onError);
|
|
178
|
+
}
|
|
179
|
+
if (onClose) {
|
|
180
|
+
closeListeners.delete(onClose);
|
|
181
|
+
}
|
|
182
|
+
signal?.removeEventListener("abort", stop);
|
|
183
|
+
if (listeners.size > 0) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
abort.abort();
|
|
187
|
+
if (stream instanceof stream_1.Readable) {
|
|
188
|
+
stream.destroy();
|
|
189
|
+
}
|
|
190
|
+
streamHubs.delete(stream);
|
|
191
|
+
};
|
|
192
|
+
signal?.addEventListener("abort", stop, { once: true });
|
|
193
|
+
if (signal?.aborted) {
|
|
194
|
+
stop();
|
|
195
|
+
throwIfAborted(signal);
|
|
196
|
+
}
|
|
197
|
+
return stop;
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function mapStreamError(error, signal) {
|
|
202
|
+
if (signal.aborted ||
|
|
203
|
+
(error instanceof DOMException && error.name === "AbortError") ||
|
|
204
|
+
(error instanceof Error && error.name === "AbortError")) {
|
|
205
|
+
return (0, errors_1.createWebRtcDomException)("AbortError", error instanceof Error ? error.message : "The operation was aborted");
|
|
206
|
+
}
|
|
207
|
+
return (0, errors_1.createWebRtcDomException)("NotReadableError", error instanceof Error ? error.message : "Failed to read media stream");
|
|
208
|
+
}
|
|
209
|
+
async function* iterateBytes(stream, signal, reader) {
|
|
210
|
+
if (stream instanceof stream_1.Readable) {
|
|
211
|
+
const onAbort = () => {
|
|
212
|
+
stream.destroy();
|
|
213
|
+
};
|
|
214
|
+
if (signal.aborted) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
218
|
+
try {
|
|
219
|
+
for await (const chunk of stream) {
|
|
220
|
+
if (signal.aborted) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
yield toBuffer(chunk);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
finally {
|
|
227
|
+
signal.removeEventListener("abort", onAbort);
|
|
228
|
+
}
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (signal.aborted) {
|
|
232
|
+
if (reader) {
|
|
233
|
+
await reader.cancel().catch(() => undefined);
|
|
234
|
+
}
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const streamReader = reader ?? stream.getReader();
|
|
238
|
+
const onAbort = () => {
|
|
239
|
+
void streamReader.cancel().catch(() => undefined);
|
|
240
|
+
};
|
|
241
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
242
|
+
if (signal.aborted) {
|
|
243
|
+
signal.removeEventListener("abort", onAbort);
|
|
244
|
+
await streamReader.cancel().catch(() => undefined);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
try {
|
|
248
|
+
for (;;) {
|
|
249
|
+
if (signal.aborted) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const { done, value } = await streamReader.read();
|
|
253
|
+
if (done) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (value) {
|
|
257
|
+
yield Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
finally {
|
|
262
|
+
signal.removeEventListener("abort", onAbort);
|
|
263
|
+
try {
|
|
264
|
+
streamReader.releaseLock();
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
// cancel() already released the lock
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
function encodeLengthPrefixed(packet) {
|
|
272
|
+
const header = Buffer.alloc(4);
|
|
273
|
+
header.writeUInt32BE(packet.length, 0);
|
|
274
|
+
return Buffer.concat([header, packet]);
|
|
275
|
+
}
|
|
276
|
+
async function readEntireStream(stream, signal = new AbortController().signal) {
|
|
277
|
+
const chunks = [];
|
|
278
|
+
try {
|
|
279
|
+
for await (const chunk of iterateBytes(stream, signal)) {
|
|
280
|
+
chunks.push(chunk);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
throw mapStreamError(error, signal);
|
|
285
|
+
}
|
|
286
|
+
if (signal.aborted) {
|
|
287
|
+
throw (0, errors_1.createWebRtcDomException)("AbortError", "The operation was aborted");
|
|
288
|
+
}
|
|
289
|
+
return Buffer.concat(chunks);
|
|
290
|
+
}
|
|
291
|
+
function isWebmContainer(buffer) {
|
|
292
|
+
return (buffer.length >= 4 &&
|
|
293
|
+
buffer[0] === 0x1a &&
|
|
294
|
+
buffer[1] === 0x45 &&
|
|
295
|
+
buffer[2] === 0xdf &&
|
|
296
|
+
buffer[3] === 0xa3);
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=sourceIo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sourceIo.js","sourceRoot":"","sources":["../../../../src/polyfill/sourceIo.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Socket, createSocket } from \"dgram\";\nimport { Readable } from \"stream\";\n\nimport { createWebRtcDomException } from \"../errors\";\n\nexport type BinaryLike = Buffer | ArrayBuffer | ArrayBufferView;\n\nexport type UdpOrStreamSource =\n | { udp: { port: number; address?: string }; stream?: never }\n | {\n udp?: never;\n stream: Readable | ReadableStream<Uint8Array>;\n };\n\nexport function toBuffer(value: BinaryLike | string): Buffer {\n if (Buffer.isBuffer(value)) {\n return value;\n }\n if (typeof value === \"string\") {\n return Buffer.from(value);\n }\n if (ArrayBuffer.isView(value)) {\n return Buffer.from(value.buffer, value.byteOffset, value.byteLength);\n }\n return Buffer.from(new Uint8Array(value));\n}\n\nexport async function openPacketSource(\n source: UdpOrStreamSource,\n onPacket: (packet: Buffer) => void,\n onError?: (error: DOMException) => void,\n signal?: AbortSignal,\n onClose?: () => void,\n): Promise<() => void> {\n throwIfAborted(signal);\n if (\"udp\" in source && source.udp) {\n return bindUdp(source.udp, onPacket, onError, signal);\n }\n return openSharedStreamSource(\n source.stream,\n onPacket,\n onError,\n signal,\n onClose,\n );\n}\n\nexport function throwIfAborted(signal?: AbortSignal) {\n if (signal?.aborted) {\n throw createWebRtcDomException(\"AbortError\", \"The operation was aborted\");\n }\n}\n\nexport type UdpSocketFactory = () => Socket;\n\nlet udpSocketFactory: UdpSocketFactory = () => createSocket(\"udp4\");\n\nexport function setUdpSocketFactory(factory?: UdpSocketFactory) {\n udpSocketFactory = factory ?? (() => createSocket(\"udp4\"));\n}\n\nasync function bindUdp(\n udp: { port: number; address?: string },\n onPacket: (packet: Buffer) => void,\n onError?: (error: DOMException) => void,\n signal?: AbortSignal,\n) {\n const socket: Socket = udpSocketFactory();\n try {\n await new Promise<void>((resolve, reject) => {\n const onBindError = (error: Error) => {\n cleanup();\n reject(error);\n };\n const onListening = () => {\n cleanup();\n resolve();\n };\n const onAbort = () => {\n cleanup();\n socket.close();\n reject(\n createWebRtcDomException(\"AbortError\", \"The operation was aborted\"),\n );\n };\n const cleanup = () => {\n socket.off(\"error\", onBindError);\n socket.off(\"listening\", onListening);\n signal?.removeEventListener(\"abort\", onAbort);\n };\n if (signal?.aborted) {\n onAbort();\n return;\n }\n socket.once(\"error\", onBindError);\n socket.once(\"listening\", onListening);\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n if (signal?.aborted) {\n onAbort();\n return;\n }\n socket.bind(udp.port, udp.address ?? \"0.0.0.0\");\n });\n } catch (error) {\n socket.close();\n if (error instanceof DOMException && error.name === \"AbortError\") {\n throw error;\n }\n throw createWebRtcDomException(\n \"NotReadableError\",\n error instanceof Error ? error.message : \"Failed to bind UDP socket\",\n );\n }\n\n const onMessage = (message: Buffer) => {\n onPacket(Buffer.from(message));\n };\n const onSocketError = (error: Error) => {\n onError?.(\n createWebRtcDomException(\n \"NotReadableError\",\n error.message || \"UDP socket error\",\n ),\n );\n };\n const stop = () => {\n socket.off(\"message\", onMessage);\n socket.off(\"error\", onSocketError);\n signal?.removeEventListener(\"abort\", stop);\n try {\n socket.close();\n } catch {\n // already closed\n }\n };\n socket.on(\"message\", onMessage);\n socket.on(\"error\", onSocketError);\n signal?.addEventListener(\"abort\", stop, { once: true });\n if (signal?.aborted) {\n stop();\n throwIfAborted(signal);\n }\n\n return stop;\n}\n\nconst streamHubs = new WeakMap<\n Readable | ReadableStream<Uint8Array>,\n StreamHub\n>();\n\ntype StreamHub = {\n subscribe(\n onPacket: (packet: Buffer) => void,\n onError?: (error: DOMException) => void,\n signal?: AbortSignal,\n onClose?: () => void,\n ): () => void;\n};\n\nfunction openSharedStreamSource(\n stream: Readable | ReadableStream<Uint8Array>,\n onPacket: (packet: Buffer) => void,\n onError?: (error: DOMException) => void,\n signal?: AbortSignal,\n onClose?: () => void,\n) {\n throwIfAborted(signal);\n let hub = streamHubs.get(stream);\n if (!hub) {\n hub = createStreamHub(stream);\n streamHubs.set(stream, hub);\n }\n return hub.subscribe(onPacket, onError, signal, onClose);\n}\n\nfunction createStreamHub(\n stream: Readable | ReadableStream<Uint8Array>,\n): StreamHub {\n const listeners = new Set<(packet: Buffer) => void>();\n const errorListeners = new Set<(error: DOMException) => void>();\n const closeListeners = new Set<() => void>();\n const abort = new AbortController();\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n if (!(stream instanceof Readable)) {\n try {\n reader = stream.getReader();\n } catch (error) {\n throw createWebRtcDomException(\n \"NotReadableError\",\n error instanceof Error ? error.message : \"Failed to lock media stream\",\n );\n }\n }\n\n const run = (async () => {\n let pending = Buffer.alloc(0);\n for await (const chunk of iterateBytes(stream, abort.signal, reader)) {\n pending = Buffer.concat([pending, chunk]);\n while (pending.length >= 4) {\n const size = pending.readUInt32BE(0);\n if (pending.length < 4 + size) {\n break;\n }\n const packet = Buffer.from(pending.subarray(4, 4 + size));\n pending = pending.subarray(4 + size);\n for (const listener of [...listeners]) {\n listener(packet);\n }\n }\n }\n })();\n\n run.then(\n () => {\n for (const onClose of [...closeListeners]) {\n onClose();\n }\n },\n (error) => {\n const mapped = mapStreamError(error, abort.signal);\n if (mapped.name === \"AbortError\") {\n return;\n }\n for (const onError of [...errorListeners]) {\n onError(mapped);\n }\n },\n );\n\n return {\n subscribe(onPacket, onError, signal, onClose) {\n throwIfAborted(signal);\n listeners.add(onPacket);\n if (onError) {\n errorListeners.add(onError);\n }\n if (onClose) {\n closeListeners.add(onClose);\n }\n const stop = () => {\n listeners.delete(onPacket);\n if (onError) {\n errorListeners.delete(onError);\n }\n if (onClose) {\n closeListeners.delete(onClose);\n }\n signal?.removeEventListener(\"abort\", stop);\n if (listeners.size > 0) {\n return;\n }\n abort.abort();\n if (stream instanceof Readable) {\n stream.destroy();\n }\n streamHubs.delete(stream);\n };\n signal?.addEventListener(\"abort\", stop, { once: true });\n if (signal?.aborted) {\n stop();\n throwIfAborted(signal);\n }\n return stop;\n },\n };\n}\n\nfunction mapStreamError(error: unknown, signal: AbortSignal) {\n if (\n signal.aborted ||\n (error instanceof DOMException && error.name === \"AbortError\") ||\n (error instanceof Error && error.name === \"AbortError\")\n ) {\n return createWebRtcDomException(\n \"AbortError\",\n error instanceof Error ? error.message : \"The operation was aborted\",\n );\n }\n return createWebRtcDomException(\n \"NotReadableError\",\n error instanceof Error ? error.message : \"Failed to read media stream\",\n );\n}\n\nasync function* iterateBytes(\n stream: Readable | ReadableStream<Uint8Array>,\n signal: AbortSignal,\n reader?: ReadableStreamDefaultReader<Uint8Array>,\n): AsyncGenerator<Buffer> {\n if (stream instanceof Readable) {\n const onAbort = () => {\n stream.destroy();\n };\n if (signal.aborted) {\n return;\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n try {\n for await (const chunk of stream) {\n if (signal.aborted) {\n return;\n }\n yield toBuffer(chunk);\n }\n } finally {\n signal.removeEventListener(\"abort\", onAbort);\n }\n return;\n }\n\n if (signal.aborted) {\n if (reader) {\n await reader.cancel().catch(() => undefined);\n }\n return;\n }\n const streamReader = reader ?? stream.getReader();\n const onAbort = () => {\n void streamReader.cancel().catch(() => undefined);\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n if (signal.aborted) {\n signal.removeEventListener(\"abort\", onAbort);\n await streamReader.cancel().catch(() => undefined);\n return;\n }\n try {\n for (;;) {\n if (signal.aborted) {\n return;\n }\n const { done, value } = await streamReader.read();\n if (done) {\n return;\n }\n if (value) {\n yield Buffer.from(value.buffer, value.byteOffset, value.byteLength);\n }\n }\n } finally {\n signal.removeEventListener(\"abort\", onAbort);\n try {\n streamReader.releaseLock();\n } catch {\n // cancel() already released the lock\n }\n }\n}\n\nexport function encodeLengthPrefixed(packet: Buffer) {\n const header = Buffer.alloc(4);\n header.writeUInt32BE(packet.length, 0);\n return Buffer.concat([header, packet]);\n}\n\nexport async function readEntireStream(\n stream: Readable | ReadableStream<Uint8Array>,\n signal: AbortSignal = new AbortController().signal,\n) {\n const chunks: Buffer[] = [];\n try {\n for await (const chunk of iterateBytes(stream, signal)) {\n chunks.push(chunk);\n }\n } catch (error) {\n throw mapStreamError(error, signal);\n }\n if (signal.aborted) {\n throw createWebRtcDomException(\"AbortError\", \"The operation was aborted\");\n }\n return Buffer.concat(chunks);\n}\n\nexport function isWebmContainer(buffer: Buffer) {\n return (\n buffer.length >= 4 &&\n buffer[0] === 0x1a &&\n buffer[1] === 0x45 &&\n buffer[2] === 0xdf &&\n buffer[3] === 0xa3\n );\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MediaStreamTrack } from "../media/track";
|
|
2
|
+
export declare function bindTrackStop(track: MediaStreamTrack, stop: () => void): void;
|
|
3
|
+
/** Fires when this track instance stops, even if a shared source still has live clones. */
|
|
4
|
+
export declare function bindOwnTrackStop(track: MediaStreamTrack, stop: () => void): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bindTrackStop = bindTrackStop;
|
|
4
|
+
exports.bindOwnTrackStop = bindOwnTrackStop;
|
|
5
|
+
function bindTrackStop(track, stop) {
|
|
6
|
+
track.bindUpstreamStop(stop);
|
|
7
|
+
}
|
|
8
|
+
/** Fires when this track instance stops, even if a shared source still has live clones. */
|
|
9
|
+
function bindOwnTrackStop(track, stop) {
|
|
10
|
+
const once = () => {
|
|
11
|
+
track.removeEventListener("ended", once);
|
|
12
|
+
stop();
|
|
13
|
+
};
|
|
14
|
+
track.addEventListener("ended", once);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=trackStop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trackStop.js","sourceRoot":"","sources":["../../../../src/polyfill/trackStop.ts"],"names":[],"mappings":";;AAEA,sCAEC;AAGD,4CAMC;AAXD,SAAgB,aAAa,CAAC,KAAuB,EAAE,IAAgB;IACrE,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,2FAA2F;AAC3F,SAAgB,gBAAgB,CAAC,KAAuB,EAAE,IAAgB;IACxE,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,KAAK,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;IACF,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC","sourcesContent":["import type { MediaStreamTrack } from \"../media/track\";\n\nexport function bindTrackStop(track: MediaStreamTrack, stop: () => void) {\n track.bindUpstreamStop(stop);\n}\n\n/** Fires when this track instance stops, even if a shared source still has live clones. */\nexport function bindOwnTrackStop(track: MediaStreamTrack, stop: () => void) {\n const once = () => {\n track.removeEventListener(\"ended\", once);\n stop();\n };\n track.addEventListener(\"ended\", once);\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SCTPOptions } from "../../sctp/src";
|
|
1
2
|
import { Event } from "./imports/common";
|
|
2
3
|
import { RTCDataChannel } from "./dataChannel";
|
|
3
4
|
import { type RTCStats } from "./media/stats";
|
|
@@ -11,7 +12,7 @@ export declare class SctpTransportManager {
|
|
|
11
12
|
private dataChannels;
|
|
12
13
|
readonly onDataChannel: Event<[RTCDataChannel]>;
|
|
13
14
|
constructor();
|
|
14
|
-
createSctpTransport(maxMessageSize?: number): RTCSctpTransport;
|
|
15
|
+
createSctpTransport(maxMessageSize?: number, sctpOptions?: SCTPOptions): RTCSctpTransport;
|
|
15
16
|
createDataChannel(label: string, options?: Partial<{
|
|
16
17
|
maxPacketLifeTime?: number;
|
|
17
18
|
protocol: string;
|
|
@@ -46,8 +46,8 @@ class SctpTransportManager {
|
|
|
46
46
|
value: new common_1.Event()
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
|
-
createSctpTransport(maxMessageSize) {
|
|
50
|
-
const sctp = new sctp_1.RTCSctpTransport(5000, maxMessageSize);
|
|
49
|
+
createSctpTransport(maxMessageSize, sctpOptions) {
|
|
50
|
+
const sctp = new sctp_1.RTCSctpTransport(5000, maxMessageSize, sctpOptions);
|
|
51
51
|
sctp.mid = undefined;
|
|
52
52
|
sctp.onDataChannel.subscribe((channel) => {
|
|
53
53
|
this.dataChannelsOpened++;
|
|
@@ -127,6 +127,9 @@ class SctpTransportManager {
|
|
|
127
127
|
async close() {
|
|
128
128
|
if (this.sctpTransport) {
|
|
129
129
|
await this.sctpTransport.stop();
|
|
130
|
+
// UdpTransport.send は既知アドレスでは callback を待たない。呼び出し側が
|
|
131
|
+
// 直後に ICE ソケットを閉じると queued な AbortChunk が落ちるので、1 tick 譲る。
|
|
132
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
130
133
|
}
|
|
131
134
|
this.onDataChannel.allUnsubscribe();
|
|
132
135
|
}
|