mediasfu-shared 1.2.7 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/ProducerClient/producerClientEmits/updateRoomParametersClient.d.ts +2 -0
- package/dist/ProducerClient/producerClientEmits/updateRoomParametersClient.d.ts.map +1 -1
- package/dist/audioProcessing-Ca5wm1nV.js +150 -0
- package/dist/audioProcessing-Ca5wm1nV.js.map +1 -0
- package/dist/audioProcessing-VCbu70Jt.cjs +149 -0
- package/dist/audioProcessing-VCbu70Jt.cjs.map +1 -0
- package/dist/consumers/closeAndResize.d.ts +3 -0
- package/dist/consumers/closeAndResize.d.ts.map +1 -1
- package/dist/consumers/connectIps.d.ts +6 -0
- package/dist/consumers/connectIps.d.ts.map +1 -1
- package/dist/consumers/connectSendTransportAudio.d.ts.map +1 -1
- package/dist/consumers/connectSendTransportScreen.d.ts.map +1 -1
- package/dist/consumers/connectSendTransportScreenAudio.d.ts +65 -0
- package/dist/consumers/connectSendTransportScreenAudio.d.ts.map +1 -0
- package/dist/consumers/connectSendTransportVideo.d.ts.map +1 -1
- package/dist/consumers/consumerBackupPreference.d.ts +14 -0
- package/dist/consumers/consumerBackupPreference.d.ts.map +1 -0
- package/dist/consumers/createSendTransport.d.ts +4 -48
- package/dist/consumers/createSendTransport.d.ts.map +1 -1
- package/dist/consumers/disconnectSendTransportScreen.d.ts.map +1 -1
- package/dist/consumers/getPipedProducersAlt.d.ts.map +1 -1
- package/dist/consumers/index.cjs +23 -1
- package/dist/consumers/index.cjs.map +1 -1
- package/dist/consumers/index.d.ts +3 -0
- package/dist/consumers/index.d.ts.map +1 -1
- package/dist/consumers/index.js +61 -39
- package/dist/consumers/index.js.map +1 -1
- package/dist/consumers/screenAudio.d.ts +64 -0
- package/dist/consumers/screenAudio.d.ts.map +1 -0
- package/dist/consumers/sendTransportGuard.d.ts +30 -0
- package/dist/consumers/sendTransportGuard.d.ts.map +1 -0
- package/dist/consumers/socketReceiveMethods/producerClosed.d.ts.map +1 -1
- package/dist/consumers/startShareScreen.d.ts +14 -0
- package/dist/consumers/startShareScreen.d.ts.map +1 -1
- package/dist/consumers/streamSuccessScreen.d.ts.map +1 -1
- package/dist/{getParticipantMedia-DTZg8n5U.js → getParticipantMedia-CZbsFBth.js} +4 -4
- package/dist/{getParticipantMedia-DTZg8n5U.js.map → getParticipantMedia-CZbsFBth.js.map} +1 -1
- package/dist/{getParticipantMedia-c2bbdT5f.cjs → getParticipantMedia-Dli4dOLp.cjs} +4 -4
- package/dist/{getParticipantMedia-c2bbdT5f.cjs.map → getParticipantMedia-Dli4dOLp.cjs.map} +1 -1
- package/dist/index.cjs +37 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1525 -1494
- package/dist/index.native.cjs +37 -6
- package/dist/index.native.cjs.map +1 -1
- package/dist/index.native.d.ts +4 -0
- package/dist/index.native.d.ts.map +1 -1
- package/dist/index.native.js +107 -76
- package/dist/{joinLocalRoom-1dRd2PCN.js → joinLocalRoom-BWoS-8wt.js} +6 -4
- package/dist/joinLocalRoom-BWoS-8wt.js.map +1 -0
- package/dist/{joinLocalRoom-DwY-3ZsH.cjs → joinLocalRoom-DQvud99t.cjs} +6 -4
- package/dist/joinLocalRoom-DQvud99t.cjs.map +1 -0
- package/dist/{joinRoomOnMediaSFU-BnAWLciF.js → joinRoomOnMediaSFU-B6tTA0Mx.js} +17 -13
- package/dist/joinRoomOnMediaSFU-B6tTA0Mx.js.map +1 -0
- package/dist/{joinRoomOnMediaSFU-D2C7q1GK.cjs → joinRoomOnMediaSFU-CxwD9fBz.cjs} +17 -13
- package/dist/joinRoomOnMediaSFU-CxwD9fBz.cjs.map +1 -0
- package/dist/methods/index.cjs +11 -8
- package/dist/methods/index.cjs.map +1 -1
- package/dist/methods/index.js +13 -9
- package/dist/methods/index.js.map +1 -1
- package/dist/methods/socketReceive/getDomains.d.ts.map +1 -1
- package/dist/methods/utils/checkLimitsAndMakeRequest.d.ts.map +1 -1
- package/dist/methods/welcome/handleWelcomeRequest.d.ts.map +1 -1
- package/dist/sockets/SocketManager.d.ts +7 -0
- package/dist/sockets/SocketManager.d.ts.map +1 -1
- package/dist/sockets/mediaSocketErrors.d.ts +62 -0
- package/dist/sockets/mediaSocketErrors.d.ts.map +1 -0
- package/dist/types/index.cjs +4 -3
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.js +39 -38
- package/dist/types/shared-base-types.d.ts +4 -0
- package/dist/types/shared-base-types.d.ts.map +1 -1
- package/dist/{updateParticipantAudioDecibels-BJ2PxJJD.cjs → updateParticipantAudioDecibels-CbCP1PDs.cjs} +467 -89
- package/dist/updateParticipantAudioDecibels-CbCP1PDs.cjs.map +1 -0
- package/dist/{updateParticipantAudioDecibels-DiJ_LFfH.js → updateParticipantAudioDecibels-xKKq7Zp5.js} +505 -127
- package/dist/updateParticipantAudioDecibels-xKKq7Zp5.js.map +1 -0
- package/package.json +3 -2
- package/src/ProducerClient/producerClientEmits/updateRoomParametersClient.ts +4 -0
- package/src/consumers/closeAndResize.ts +14 -0
- package/src/consumers/connectIps.ts +81 -8
- package/src/consumers/connectSendTransportAudio.ts +7 -4
- package/src/consumers/connectSendTransportScreen.ts +6 -4
- package/src/consumers/connectSendTransportScreenAudio.ts +184 -0
- package/src/consumers/connectSendTransportVideo.ts +4 -2
- package/src/consumers/consumerBackupPreference.ts +43 -0
- package/src/consumers/createSendTransport.ts +62 -4
- package/src/consumers/disconnectSendTransportScreen.ts +8 -0
- package/src/consumers/getPipedProducersAlt.ts +4 -0
- package/src/consumers/index.ts +3 -0
- package/src/consumers/screenAudio.ts +132 -0
- package/src/consumers/sendTransportGuard.ts +65 -0
- package/src/consumers/socketReceiveMethods/producerClosed.ts +3 -0
- package/src/consumers/startShareScreen.ts +44 -8
- package/src/consumers/streamSuccessScreen.ts +11 -0
- package/src/index.native.ts +4 -0
- package/src/index.ts +4 -0
- package/src/methods/socketReceive/getDomains.ts +4 -0
- package/src/methods/utils/checkLimitsAndMakeRequest.ts +24 -11
- package/src/methods/welcome/handleWelcomeRequest.ts +15 -6
- package/src/sockets/SocketManager.ts +107 -13
- package/src/sockets/mediaSocketErrors.ts +156 -0
- package/src/types/shared-base-types.ts +4 -0
- package/dist/audioProcessing-0z5KlcmO.js +0 -35
- package/dist/audioProcessing-0z5KlcmO.js.map +0 -1
- package/dist/audioProcessing-BpbrdCk-.cjs +0 -34
- package/dist/audioProcessing-BpbrdCk-.cjs.map +0 -1
- package/dist/joinLocalRoom-1dRd2PCN.js.map +0 -1
- package/dist/joinLocalRoom-DwY-3ZsH.cjs.map +0 -1
- package/dist/joinRoomOnMediaSFU-BnAWLciF.js.map +0 -1
- package/dist/joinRoomOnMediaSFU-D2C7q1GK.cjs.map +0 -1
- package/dist/updateParticipantAudioDecibels-BJ2PxJJD.cjs.map +0 -1
- package/dist/updateParticipantAudioDecibels-DiJ_LFfH.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const io = require("socket.io-client");
|
|
3
|
-
const audioProcessing = require("./audioProcessing-
|
|
3
|
+
const audioProcessing = require("./audioProcessing-VCbu70Jt.cjs");
|
|
4
4
|
const createFrameworkConsumerContractError = (consumerName) => {
|
|
5
5
|
return new Error(
|
|
6
6
|
`${consumerName} is a render-coupled consumer helper and has no shared runtime implementation. Inject the framework-specific ${consumerName} implementation instead of calling the shared fallback export.`
|
|
@@ -507,6 +507,7 @@ const closeAndResize = async ({ producerId, kind, parameters }) => {
|
|
|
507
507
|
parameters = getUpdatedAllParams();
|
|
508
508
|
let {
|
|
509
509
|
allAudioStreams,
|
|
510
|
+
audioOnlyStreams = [],
|
|
510
511
|
allVideoStreams,
|
|
511
512
|
activeNames,
|
|
512
513
|
participants,
|
|
@@ -531,6 +532,7 @@ const closeAndResize = async ({ producerId, kind, parameters }) => {
|
|
|
531
532
|
updateMainWindow,
|
|
532
533
|
updateActiveNames,
|
|
533
534
|
updateAllAudioStreams,
|
|
535
|
+
updateAudioOnlyStreams,
|
|
534
536
|
updateAllVideoStreams,
|
|
535
537
|
updateShareScreenStarted,
|
|
536
538
|
updateUpdateMainWindow,
|
|
@@ -554,6 +556,11 @@ const closeAndResize = async ({ producerId, kind, parameters }) => {
|
|
|
554
556
|
return audioStream.producerId !== producerId;
|
|
555
557
|
});
|
|
556
558
|
updateAllAudioStreams(allAudioStreams);
|
|
559
|
+
const playerProducerId = (element) => String(element?.props?.remoteProducerId ?? element?.inputs?.remoteProducerId ?? element?.key ?? "");
|
|
560
|
+
if (audioOnlyStreams.some((element) => playerProducerId(element) === producerId)) {
|
|
561
|
+
audioOnlyStreams = audioOnlyStreams.filter((element) => playerProducerId(element) !== producerId);
|
|
562
|
+
updateAudioOnlyStreams?.(audioOnlyStreams);
|
|
563
|
+
}
|
|
557
564
|
if (recordingDisplayType == "video" && recordingVideoOptimized == true) ;
|
|
558
565
|
else {
|
|
559
566
|
participant = participants.find(
|
|
@@ -760,6 +767,24 @@ async function compareScreenStates({
|
|
|
760
767
|
console.log("compareScreenStates error", error);
|
|
761
768
|
}
|
|
762
769
|
}
|
|
770
|
+
function stopReconnectingWhenRefused(socket) {
|
|
771
|
+
const onRejected = (payload) => {
|
|
772
|
+
const refusal = new audioProcessing.MediaSocketConnectError({
|
|
773
|
+
phase: "rejected",
|
|
774
|
+
reason: audioProcessing.normalizeRejectionReason(payload?.reason),
|
|
775
|
+
stage: typeof payload?.stage === "string" ? payload.stage : void 0,
|
|
776
|
+
elapsedMs: 0
|
|
777
|
+
});
|
|
778
|
+
if (refusal.retryable) return;
|
|
779
|
+
socket.off("connection-rejected", onRejected);
|
|
780
|
+
console.warn(`MediaSFU media socket: reconnect refused (${refusal.reason}); not retrying.`);
|
|
781
|
+
try {
|
|
782
|
+
socket.disconnect();
|
|
783
|
+
} catch {
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
socket.on("connection-rejected", onRejected);
|
|
787
|
+
}
|
|
763
788
|
async function validateApiKeyToken(value) {
|
|
764
789
|
if (!/^[a-z0-9]{64}$/i.test(value)) {
|
|
765
790
|
throw new Error("Invalid API key or token.");
|
|
@@ -812,12 +837,26 @@ async function connectSocket({ apiUserName, apiKey, apiToken, link }) {
|
|
|
812
837
|
}
|
|
813
838
|
let settled = false;
|
|
814
839
|
let timeoutHandle;
|
|
840
|
+
const startedAt = Date.now();
|
|
841
|
+
let transportOpened = false;
|
|
842
|
+
let rejection = null;
|
|
815
843
|
const cleanupHandshake = () => {
|
|
816
844
|
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
817
845
|
socket.off("connection-success", handleConnectionSuccess);
|
|
818
846
|
socket.off("connect_error", handleConnectError);
|
|
819
847
|
socket.off("disconnect", handleDisconnectBeforeReady);
|
|
848
|
+
socket.off("connect", handleTransportOpen);
|
|
849
|
+
socket.off("connection-rejected", handleConnectionRejected);
|
|
820
850
|
};
|
|
851
|
+
const failure = (phase, transportError) => new audioProcessing.MediaSocketConnectError({
|
|
852
|
+
phase: rejection ? "rejected" : phase,
|
|
853
|
+
reason: rejection?.reason,
|
|
854
|
+
stage: rejection?.stage,
|
|
855
|
+
elapsedMs: Date.now() - startedAt,
|
|
856
|
+
online: audioProcessing.currentOnlineState(),
|
|
857
|
+
transportError,
|
|
858
|
+
link
|
|
859
|
+
});
|
|
821
860
|
const settle = (action) => {
|
|
822
861
|
if (settled) return;
|
|
823
862
|
settled = true;
|
|
@@ -833,33 +872,48 @@ async function connectSocket({ apiUserName, apiKey, apiToken, link }) {
|
|
|
833
872
|
} catch {
|
|
834
873
|
}
|
|
835
874
|
console.log(`Connected to ${conn} socket with ID: ${socketId}`);
|
|
836
|
-
settle(() =>
|
|
875
|
+
settle(() => {
|
|
876
|
+
stopReconnectingWhenRefused(socket);
|
|
877
|
+
resolve(socket);
|
|
878
|
+
});
|
|
837
879
|
};
|
|
838
880
|
const handleConnectError = (error) => {
|
|
839
881
|
settle(() => {
|
|
840
882
|
socket.disconnect();
|
|
841
|
-
reject(
|
|
883
|
+
reject(failure(transportOpened ? "after-open" : "before-open", error?.message));
|
|
884
|
+
});
|
|
885
|
+
};
|
|
886
|
+
const handleTransportOpen = () => {
|
|
887
|
+
transportOpened = true;
|
|
888
|
+
};
|
|
889
|
+
const handleConnectionRejected = (payload) => {
|
|
890
|
+
rejection = {
|
|
891
|
+
reason: audioProcessing.normalizeRejectionReason(payload?.reason),
|
|
892
|
+
stage: typeof payload?.stage === "string" ? payload.stage : void 0
|
|
893
|
+
};
|
|
894
|
+
settle(() => {
|
|
895
|
+
try {
|
|
896
|
+
socket.disconnect();
|
|
897
|
+
} catch {
|
|
898
|
+
}
|
|
899
|
+
reject(failure("rejected"));
|
|
842
900
|
});
|
|
843
901
|
};
|
|
844
902
|
const handleDisconnectBeforeReady = (reason) => {
|
|
845
|
-
settle(
|
|
846
|
-
() => reject(
|
|
847
|
-
new Error(
|
|
848
|
-
"Media socket closed before the room was ready (" + reason + ")."
|
|
849
|
-
)
|
|
850
|
-
)
|
|
851
|
-
);
|
|
903
|
+
settle(() => reject(failure("after-open", reason)));
|
|
852
904
|
};
|
|
853
905
|
socket.on("connection-success", handleConnectionSuccess);
|
|
854
906
|
socket.on("connect_error", handleConnectError);
|
|
855
907
|
socket.on("disconnect", handleDisconnectBeforeReady);
|
|
908
|
+
socket.on("connect", handleTransportOpen);
|
|
909
|
+
socket.on("connection-rejected", handleConnectionRejected);
|
|
856
910
|
timeoutHandle = setTimeout(() => {
|
|
857
911
|
settle(() => {
|
|
858
912
|
try {
|
|
859
913
|
socket.disconnect();
|
|
860
914
|
} catch {
|
|
861
915
|
}
|
|
862
|
-
reject(
|
|
916
|
+
reject(failure("timeout"));
|
|
863
917
|
});
|
|
864
918
|
}, CONNECT_TIMEOUT_MS);
|
|
865
919
|
});
|
|
@@ -873,11 +927,24 @@ async function connectLocalSocket({ link }) {
|
|
|
873
927
|
socket = io(`${link}/media`, {
|
|
874
928
|
transports: ["websocket"]
|
|
875
929
|
});
|
|
930
|
+
const startedAt = Date.now();
|
|
931
|
+
let transportOpened = false;
|
|
932
|
+
socket.on("connect", () => {
|
|
933
|
+
transportOpened = true;
|
|
934
|
+
});
|
|
876
935
|
socket.on("connection-success", (data) => {
|
|
877
936
|
resolve({ socket, data });
|
|
878
937
|
});
|
|
879
938
|
socket.on("connect_error", (error) => {
|
|
880
|
-
reject(
|
|
939
|
+
reject(
|
|
940
|
+
new audioProcessing.MediaSocketConnectError({
|
|
941
|
+
phase: transportOpened ? "after-open" : "before-open",
|
|
942
|
+
elapsedMs: Date.now() - startedAt,
|
|
943
|
+
online: audioProcessing.currentOnlineState(),
|
|
944
|
+
transportError: error?.message,
|
|
945
|
+
link
|
|
946
|
+
})
|
|
947
|
+
);
|
|
881
948
|
});
|
|
882
949
|
});
|
|
883
950
|
}
|
|
@@ -1246,11 +1313,72 @@ const newPipeProducer = async ({
|
|
|
1246
1313
|
updateFirst_round(updatedFirstRound);
|
|
1247
1314
|
}
|
|
1248
1315
|
};
|
|
1316
|
+
const SCREEN_AUDIO_MEDIA_TAG = "screen-audio";
|
|
1317
|
+
const SCREEN_AUDIO_CODEC_OPTIONS = {
|
|
1318
|
+
opusStereo: true,
|
|
1319
|
+
opusDtx: false,
|
|
1320
|
+
opusFec: true,
|
|
1321
|
+
opusMaxAverageBitrate: 128e3
|
|
1322
|
+
};
|
|
1323
|
+
const screenAudioProducerIds = /* @__PURE__ */ new Set();
|
|
1324
|
+
const markScreenAudioProducer = (producerId, mediaTag) => {
|
|
1325
|
+
if (producerId && mediaTag === SCREEN_AUDIO_MEDIA_TAG) screenAudioProducerIds.add(producerId);
|
|
1326
|
+
};
|
|
1327
|
+
const forgetScreenAudioProducer = (producerId) => {
|
|
1328
|
+
if (producerId) screenAudioProducerIds.delete(producerId);
|
|
1329
|
+
};
|
|
1330
|
+
const isScreenAudioProducer = ({ producerId, participants = [], appData }) => {
|
|
1331
|
+
if (!producerId) return false;
|
|
1332
|
+
if (screenAudioProducerIds.has(producerId)) return true;
|
|
1333
|
+
if (appData?.mediaTag === SCREEN_AUDIO_MEDIA_TAG) return true;
|
|
1334
|
+
return participants.some((participant) => participant?.ScreenAudioID === producerId);
|
|
1335
|
+
};
|
|
1336
|
+
const shouldShareScreenAudio = ({ supportsScreenAudio, screenAudioEnabled, screenAudioMode }) => supportsScreenAudio === true && screenAudioEnabled !== false && screenAudioMode !== "never";
|
|
1337
|
+
const canCaptureDisplayAudio = (nav = typeof navigator !== "undefined" ? navigator : void 0) => {
|
|
1338
|
+
if (!nav) return false;
|
|
1339
|
+
const ua = String(nav.userAgent || "");
|
|
1340
|
+
if (/Mobi|Android|iPhone|iPad|iPod/i.test(ua)) return false;
|
|
1341
|
+
const brands = (nav.userAgentData?.brands || []).map((entry) => String(entry?.brand || ""));
|
|
1342
|
+
if (brands.some((brand) => /Chromium|Google Chrome|Microsoft Edge|Opera|Brave/i.test(brand))) return true;
|
|
1343
|
+
return /(Chrome|Chromium|Edg)\//.test(ua) && !/Firefox|FxiOS|OPiOS/.test(ua);
|
|
1344
|
+
};
|
|
1345
|
+
const setScreenAudioPaused = (producer, paused) => {
|
|
1346
|
+
if (!producer || producer.closed) return false;
|
|
1347
|
+
if (paused && !producer.paused) producer.pause();
|
|
1348
|
+
if (!paused && producer.paused) producer.resume();
|
|
1349
|
+
return producer.paused;
|
|
1350
|
+
};
|
|
1351
|
+
const buildDisplayMediaOptions = ({ targetWidth, targetHeight, withAudio }) => {
|
|
1352
|
+
const options = {
|
|
1353
|
+
video: { width: targetWidth, height: targetHeight, frameRate: 30 },
|
|
1354
|
+
audio: withAudio ? { echoCancellation: false, noiseSuppression: false, autoGainControl: false } : false
|
|
1355
|
+
};
|
|
1356
|
+
if (withAudio) {
|
|
1357
|
+
options.systemAudio = "include";
|
|
1358
|
+
options.suppressLocalAudioPlayback = false;
|
|
1359
|
+
}
|
|
1360
|
+
return options;
|
|
1361
|
+
};
|
|
1362
|
+
const producersBySocket = /* @__PURE__ */ new WeakMap();
|
|
1363
|
+
const rememberScreenAudioProducer = (socket, producer) => {
|
|
1364
|
+
if (!socket) return;
|
|
1365
|
+
if (producer) producersBySocket.set(socket, producer);
|
|
1366
|
+
else producersBySocket.delete(socket);
|
|
1367
|
+
};
|
|
1368
|
+
const recallScreenAudioProducer = (socket) => socket && producersBySocket.get(socket) || null;
|
|
1369
|
+
const setScreenAudioVolume = (volume, root = typeof document !== "undefined" ? document : null) => {
|
|
1370
|
+
if (!root) return;
|
|
1371
|
+
const value = Math.min(1, Math.max(0, Number.isFinite(volume) ? volume : 1));
|
|
1372
|
+
root.querySelectorAll('audio[data-screen-audio="true"]').forEach((element) => {
|
|
1373
|
+
element.volume = value;
|
|
1374
|
+
});
|
|
1375
|
+
};
|
|
1249
1376
|
const producerClosed = async ({
|
|
1250
1377
|
remoteProducerId,
|
|
1251
1378
|
parameters
|
|
1252
1379
|
}) => {
|
|
1253
1380
|
let { consumerTransports, closeAndResize: closeAndResize2, screenId, updateConsumerTransports } = parameters;
|
|
1381
|
+
forgetScreenAudioProducer(remoteProducerId);
|
|
1254
1382
|
const activeTranslationProducerIds = parameters.activeTranslationProducerIds;
|
|
1255
1383
|
const isTranslationProducer = activeTranslationProducerIds?.has?.(remoteProducerId);
|
|
1256
1384
|
if (isTranslationProducer) {
|
|
@@ -1401,6 +1529,20 @@ const joinConsumeRoom = async ({
|
|
|
1401
1529
|
};
|
|
1402
1530
|
const pendingConsumeConnections = /* @__PURE__ */ new WeakMap();
|
|
1403
1531
|
const normalizeConsumeEndpoint = (ip) => ip.trim().toLowerCase().replace(/\.$/, "");
|
|
1532
|
+
const CONSUME_REJECTION_COOLDOWN_MS = 6e4;
|
|
1533
|
+
const rejectedConsumeEndpoints = /* @__PURE__ */ new WeakMap();
|
|
1534
|
+
const consumeEndpointRecentlyRejected = (owner, endpoint) => {
|
|
1535
|
+
const at = rejectedConsumeEndpoints.get(owner)?.get(endpoint);
|
|
1536
|
+
return at !== void 0 && Date.now() - at < CONSUME_REJECTION_COOLDOWN_MS;
|
|
1537
|
+
};
|
|
1538
|
+
const rememberConsumeEndpointRejection = (owner, endpoint) => {
|
|
1539
|
+
let byEndpoint = rejectedConsumeEndpoints.get(owner);
|
|
1540
|
+
if (!byEndpoint) {
|
|
1541
|
+
byEndpoint = /* @__PURE__ */ new Map();
|
|
1542
|
+
rejectedConsumeEndpoints.set(owner, byEndpoint);
|
|
1543
|
+
}
|
|
1544
|
+
byEndpoint.set(endpoint, Date.now());
|
|
1545
|
+
};
|
|
1404
1546
|
const hasConsumeEndpoint = (consumeSockets, endpoint) => {
|
|
1405
1547
|
for (let index = consumeSockets.length - 1; index >= 0; index -= 1) {
|
|
1406
1548
|
const socketObj = consumeSockets[index];
|
|
@@ -1468,7 +1610,9 @@ const connectIps = async ({
|
|
|
1468
1610
|
});
|
|
1469
1611
|
return [consume_sockets, roomRecvIPs];
|
|
1470
1612
|
}
|
|
1613
|
+
const rejectionOwner = parameters?.socket || consume_sockets;
|
|
1471
1614
|
for (const ip of remIP) {
|
|
1615
|
+
if (consumeEndpointRecentlyRejected(rejectionOwner, normalizeConsumeEndpoint(ip))) continue;
|
|
1472
1616
|
const releaseReservation = await reserveConsumeEndpoint(
|
|
1473
1617
|
consume_sockets,
|
|
1474
1618
|
ip,
|
|
@@ -1480,11 +1624,25 @@ const connectIps = async ({
|
|
|
1480
1624
|
try {
|
|
1481
1625
|
remote_sock = await connectSocket({ apiUserName, apiKey, apiToken, link: `https://${ip}.mediasfu.com` });
|
|
1482
1626
|
if (remote_sock.id) {
|
|
1627
|
+
let consumeRoomReady = false;
|
|
1628
|
+
const pendingProducers = [];
|
|
1483
1629
|
if (!roomRecvIPs.includes(ip)) {
|
|
1484
1630
|
roomRecvIPs.push(ip);
|
|
1485
1631
|
updateRoomRecvIPs(roomRecvIPs);
|
|
1486
1632
|
}
|
|
1487
|
-
|
|
1633
|
+
const consumeProducer = async ({ producerId, islevel, isTranslation, translationMeta, mediaTag }) => {
|
|
1634
|
+
markScreenAudioProducer(producerId, mediaTag);
|
|
1635
|
+
if (!consumeRoomReady) {
|
|
1636
|
+
pendingProducers.push({ producerId, islevel, isTranslation, translationMeta });
|
|
1637
|
+
return;
|
|
1638
|
+
}
|
|
1639
|
+
const preferDelay = isTranslation ? 0 : audioProcessing.consumerBackupPreferDelay(
|
|
1640
|
+
ip,
|
|
1641
|
+
parameters.getUpdatedAllParams?.()?.consume_sockets
|
|
1642
|
+
);
|
|
1643
|
+
if (preferDelay > 0) {
|
|
1644
|
+
await new Promise((resolve) => setTimeout(resolve, preferDelay));
|
|
1645
|
+
}
|
|
1488
1646
|
if (newProducerMethod) {
|
|
1489
1647
|
await newProducerMethod({
|
|
1490
1648
|
producerId,
|
|
@@ -1495,7 +1653,8 @@ const connectIps = async ({
|
|
|
1495
1653
|
translationMeta
|
|
1496
1654
|
});
|
|
1497
1655
|
}
|
|
1498
|
-
}
|
|
1656
|
+
};
|
|
1657
|
+
remote_sock.on("new-pipe-producer", consumeProducer);
|
|
1499
1658
|
remote_sock.on("producer-closed", async ({ remoteProducerId }) => {
|
|
1500
1659
|
if (closedProducerMethod) {
|
|
1501
1660
|
await closedProducerMethod({ remoteProducerId, parameters });
|
|
@@ -1512,6 +1671,11 @@ const connectIps = async ({
|
|
|
1512
1671
|
throw new Error(`Consume room ${ip} did not return RTP capabilities.`);
|
|
1513
1672
|
}
|
|
1514
1673
|
}
|
|
1674
|
+
const queuedProducers = pendingProducers.splice(0);
|
|
1675
|
+
consumeRoomReady = true;
|
|
1676
|
+
for (const producer of queuedProducers) {
|
|
1677
|
+
await consumeProducer(producer);
|
|
1678
|
+
}
|
|
1515
1679
|
consume_sockets.push({ [ip]: remote_sock });
|
|
1516
1680
|
updateConsume_sockets(consume_sockets);
|
|
1517
1681
|
connected = true;
|
|
@@ -1533,7 +1697,12 @@ const connectIps = async ({
|
|
|
1533
1697
|
});
|
|
1534
1698
|
}
|
|
1535
1699
|
} catch (error) {
|
|
1536
|
-
|
|
1700
|
+
if (audioProcessing.isMediaSocketConnectError(error) && !error.retryable) {
|
|
1701
|
+
rememberConsumeEndpointRejection(rejectionOwner, normalizeConsumeEndpoint(ip));
|
|
1702
|
+
console.warn(`connectIps: ${ip} refused this room (${error.reason}); not retrying for ${CONSUME_REJECTION_COOLDOWN_MS / 1e3} s.`, error.message);
|
|
1703
|
+
} else {
|
|
1704
|
+
console.log("connectIps error", error);
|
|
1705
|
+
}
|
|
1537
1706
|
} finally {
|
|
1538
1707
|
if (!connected && remote_sock) {
|
|
1539
1708
|
remote_sock.removeAllListeners?.();
|
|
@@ -1767,6 +1936,36 @@ const connectSendTransport = async ({ option, targetOption = "all", parameters }
|
|
|
1767
1936
|
console.log("connectSendTransport error", error);
|
|
1768
1937
|
}
|
|
1769
1938
|
};
|
|
1939
|
+
const pendingCreations = /* @__PURE__ */ new WeakMap();
|
|
1940
|
+
const pendingSendTransportCreation = (socket) => socket ? pendingCreations.get(socket) : void 0;
|
|
1941
|
+
const trackSendTransportCreation = (socket, create) => {
|
|
1942
|
+
if (!socket) return create();
|
|
1943
|
+
const running = create();
|
|
1944
|
+
pendingCreations.set(socket, running);
|
|
1945
|
+
const release = () => {
|
|
1946
|
+
if (pendingCreations.get(socket) === running) pendingCreations.delete(socket);
|
|
1947
|
+
};
|
|
1948
|
+
running.then(release, release);
|
|
1949
|
+
return running;
|
|
1950
|
+
};
|
|
1951
|
+
const isOpen = (item) => Boolean(item && !item.closed);
|
|
1952
|
+
const pendingProduces = /* @__PURE__ */ new WeakMap();
|
|
1953
|
+
const produceOnce$1 = async (transport, key, produce) => {
|
|
1954
|
+
let byKey = pendingProduces.get(transport);
|
|
1955
|
+
if (!byKey) {
|
|
1956
|
+
byKey = /* @__PURE__ */ new Map();
|
|
1957
|
+
pendingProduces.set(transport, byKey);
|
|
1958
|
+
}
|
|
1959
|
+
const inFlight = byKey.get(key);
|
|
1960
|
+
if (inFlight) return { producer: await inFlight, joined: true };
|
|
1961
|
+
const running = produce();
|
|
1962
|
+
byKey.set(key, running);
|
|
1963
|
+
try {
|
|
1964
|
+
return { producer: await running, joined: false };
|
|
1965
|
+
} finally {
|
|
1966
|
+
if (byKey.get(key) === running) byKey.delete(key);
|
|
1967
|
+
}
|
|
1968
|
+
};
|
|
1770
1969
|
const connectLocalSendTransportAudio = async ({
|
|
1771
1970
|
parameters,
|
|
1772
1971
|
audioParams
|
|
@@ -1779,7 +1978,7 @@ const connectLocalSendTransportAudio = async ({
|
|
|
1779
1978
|
updateLocalProducerTransport
|
|
1780
1979
|
} = parameters;
|
|
1781
1980
|
if (localProducerTransport) {
|
|
1782
|
-
localAudioProducer = await localProducerTransport.produce(audioParams);
|
|
1981
|
+
localAudioProducer = (await produceOnce$1(localProducerTransport, "audio", () => localProducerTransport.produce(audioParams))).producer;
|
|
1783
1982
|
updateLocalAudioProducer?.(localAudioProducer);
|
|
1784
1983
|
updateLocalProducerTransport?.(localProducerTransport);
|
|
1785
1984
|
}
|
|
@@ -1817,8 +2016,9 @@ const connectSendTransportAudio = async ({
|
|
|
1817
2016
|
updateProducerTransport
|
|
1818
2017
|
} = parameters;
|
|
1819
2018
|
if (targetOption === "all" || targetOption === "remote") {
|
|
1820
|
-
|
|
1821
|
-
|
|
2019
|
+
const produced = await produceOnce$1(producerTransport, "audio", () => producerTransport.produce(audioParams));
|
|
2020
|
+
audioProducer = produced.producer;
|
|
2021
|
+
if (!produced.joined) updateMicLevel(audioProducer, parameters.updateAudioLevel);
|
|
1822
2022
|
updateAudioProducer(audioProducer);
|
|
1823
2023
|
updateProducerTransport(producerTransport);
|
|
1824
2024
|
}
|
|
@@ -1856,11 +2056,11 @@ const connectLocalSendTransportScreen = async ({
|
|
|
1856
2056
|
(codec2) => codec2.mimeType.toLowerCase() === "video/vp9"
|
|
1857
2057
|
);
|
|
1858
2058
|
if (localProducerTransport) {
|
|
1859
|
-
localScreenProducer = await localProducerTransport.produce({
|
|
2059
|
+
localScreenProducer = (await produceOnce$1(localProducerTransport, "screen", () => localProducerTransport.produce({
|
|
1860
2060
|
track: stream.getVideoTracks()[0],
|
|
1861
2061
|
codec,
|
|
1862
2062
|
appData: { mediaTag: "screen-video" }
|
|
1863
|
-
});
|
|
2063
|
+
}))).producer;
|
|
1864
2064
|
updateLocalScreenProducer?.(localScreenProducer);
|
|
1865
2065
|
updateLocalProducerTransport?.(localProducerTransport);
|
|
1866
2066
|
}
|
|
@@ -1890,12 +2090,12 @@ const connectSendTransportScreen = async ({
|
|
|
1890
2090
|
(codec2) => codec2.mimeType.toLowerCase() === "video/vp9"
|
|
1891
2091
|
);
|
|
1892
2092
|
if (targetOption === "remote" || targetOption === "all") {
|
|
1893
|
-
screenProducer = await producerTransport.produce({
|
|
2093
|
+
screenProducer = (await produceOnce$1(producerTransport, "screen", () => producerTransport.produce({
|
|
1894
2094
|
track: stream.getVideoTracks()[0],
|
|
1895
2095
|
...params,
|
|
1896
2096
|
codec,
|
|
1897
2097
|
appData: { mediaTag: "screen-video" }
|
|
1898
|
-
});
|
|
2098
|
+
}))).producer;
|
|
1899
2099
|
updateScreenProducer(screenProducer);
|
|
1900
2100
|
updateProducerTransport(producerTransport);
|
|
1901
2101
|
}
|
|
@@ -1923,7 +2123,7 @@ const connectLocalSendTransportVideo = async ({
|
|
|
1923
2123
|
updateLocalProducerTransport
|
|
1924
2124
|
} = parameters;
|
|
1925
2125
|
if (localProducerTransport) {
|
|
1926
|
-
localVideoProducer = await localProducerTransport.produce(videoParams);
|
|
2126
|
+
localVideoProducer = (await produceOnce$1(localProducerTransport, "video", () => localProducerTransport.produce(videoParams))).producer;
|
|
1927
2127
|
updateLocalVideoProducer?.(localVideoProducer);
|
|
1928
2128
|
updateLocalProducerTransport?.(localProducerTransport);
|
|
1929
2129
|
}
|
|
@@ -1948,7 +2148,7 @@ const connectSendTransportVideo = async ({
|
|
|
1948
2148
|
updateUpdateMainWindow
|
|
1949
2149
|
} = parameters;
|
|
1950
2150
|
if (targetOption === "all" || targetOption === "remote") {
|
|
1951
|
-
videoProducer = await producerTransport.produce(videoParams);
|
|
2151
|
+
videoProducer = (await produceOnce$1(producerTransport, "video", () => producerTransport.produce(videoParams))).producer;
|
|
1952
2152
|
if (islevel === "2") {
|
|
1953
2153
|
updateMainWindow = true;
|
|
1954
2154
|
}
|
|
@@ -2068,7 +2268,7 @@ const createLocalSendTransport = async ({
|
|
|
2068
2268
|
console.error("Error creating local send transport:", error);
|
|
2069
2269
|
}
|
|
2070
2270
|
};
|
|
2071
|
-
const
|
|
2271
|
+
const createSendTransportNow = async ({
|
|
2072
2272
|
option,
|
|
2073
2273
|
parameters
|
|
2074
2274
|
}) => {
|
|
@@ -2098,67 +2298,109 @@ const createSendTransport = async ({
|
|
|
2098
2298
|
} catch (error) {
|
|
2099
2299
|
console.log("Error creating local send transport:", error);
|
|
2100
2300
|
}
|
|
2101
|
-
socket.emit(
|
|
2301
|
+
await new Promise((resolve, reject) => socket.emit(
|
|
2102
2302
|
"createWebRtcTransport",
|
|
2103
2303
|
{ consumer: false, islevel },
|
|
2104
2304
|
async ({ params }) => {
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
if (!resolvedDevice) {
|
|
2111
|
-
return;
|
|
2112
|
-
}
|
|
2113
|
-
const createdProducerTransport = await resolvedDevice.createSendTransport(params);
|
|
2114
|
-
updateProducerTransport(createdProducerTransport);
|
|
2115
|
-
createdProducerTransport.on(
|
|
2116
|
-
"connect",
|
|
2117
|
-
async ({ dtlsParameters }, callback, errback) => {
|
|
2118
|
-
try {
|
|
2119
|
-
socket.emit("transport-connect", { dtlsParameters });
|
|
2120
|
-
callback();
|
|
2121
|
-
} catch (error) {
|
|
2122
|
-
errback(error);
|
|
2123
|
-
}
|
|
2124
|
-
}
|
|
2125
|
-
);
|
|
2126
|
-
createdProducerTransport.on(
|
|
2127
|
-
"produce",
|
|
2128
|
-
async (parameters2, callback, errback) => {
|
|
2129
|
-
try {
|
|
2130
|
-
socket.emit(
|
|
2131
|
-
"transport-produce",
|
|
2132
|
-
{
|
|
2133
|
-
kind: parameters2.kind,
|
|
2134
|
-
rtpParameters: parameters2.rtpParameters,
|
|
2135
|
-
appData: parameters2.appData,
|
|
2136
|
-
islevel,
|
|
2137
|
-
name: member
|
|
2138
|
-
},
|
|
2139
|
-
async ({ id }) => {
|
|
2140
|
-
callback({ id });
|
|
2141
|
-
}
|
|
2142
|
-
);
|
|
2143
|
-
} catch (error) {
|
|
2144
|
-
errback(error);
|
|
2145
|
-
}
|
|
2305
|
+
try {
|
|
2306
|
+
if (params && params.error) {
|
|
2307
|
+
console.error("Error in createWebRtcTransport:", params.error);
|
|
2308
|
+
reject(new Error(String(params.error)));
|
|
2309
|
+
return;
|
|
2146
2310
|
}
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
await connectSendTransport2({
|
|
2152
|
-
targetOption: "remote",
|
|
2153
|
-
option,
|
|
2154
|
-
parameters: {
|
|
2155
|
-
...parameters,
|
|
2156
|
-
producerTransport: createdProducerTransport
|
|
2311
|
+
const resolvedDevice = parameters.getCurrentParams ? parameters.getCurrentParams().device : device ?? null;
|
|
2312
|
+
if (!resolvedDevice) {
|
|
2313
|
+
resolve();
|
|
2314
|
+
return;
|
|
2157
2315
|
}
|
|
2158
|
-
|
|
2159
|
-
|
|
2316
|
+
const createdProducerTransport = await resolvedDevice.createSendTransport(params);
|
|
2317
|
+
updateProducerTransport(createdProducerTransport);
|
|
2318
|
+
createdProducerTransport.on(
|
|
2319
|
+
"connect",
|
|
2320
|
+
async ({ dtlsParameters }, callback, errback) => {
|
|
2321
|
+
try {
|
|
2322
|
+
socket.emit("transport-connect", { dtlsParameters });
|
|
2323
|
+
callback();
|
|
2324
|
+
} catch (error) {
|
|
2325
|
+
errback(error);
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
);
|
|
2329
|
+
createdProducerTransport.on(
|
|
2330
|
+
"produce",
|
|
2331
|
+
async (parameters2, callback, errback) => {
|
|
2332
|
+
try {
|
|
2333
|
+
socket.emit(
|
|
2334
|
+
"transport-produce",
|
|
2335
|
+
{
|
|
2336
|
+
kind: parameters2.kind,
|
|
2337
|
+
rtpParameters: parameters2.rtpParameters,
|
|
2338
|
+
appData: parameters2.appData,
|
|
2339
|
+
islevel,
|
|
2340
|
+
name: member
|
|
2341
|
+
},
|
|
2342
|
+
async ({ id }) => {
|
|
2343
|
+
callback({ id });
|
|
2344
|
+
}
|
|
2345
|
+
);
|
|
2346
|
+
} catch (error) {
|
|
2347
|
+
errback(error);
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
);
|
|
2351
|
+
attachTransportRecovery(createdProducerTransport, socket, () => clearFailedSendState(parameters, createdProducerTransport));
|
|
2352
|
+
transportCreated = true;
|
|
2353
|
+
parameters = parameters.getCurrentParams?.() ?? parameters;
|
|
2354
|
+
await connectSendTransport2({
|
|
2355
|
+
targetOption: "remote",
|
|
2356
|
+
option,
|
|
2357
|
+
parameters: {
|
|
2358
|
+
...parameters,
|
|
2359
|
+
producerTransport: createdProducerTransport
|
|
2360
|
+
}
|
|
2361
|
+
});
|
|
2362
|
+
updateTransportCreated(transportCreated);
|
|
2363
|
+
resolve();
|
|
2364
|
+
} catch (error) {
|
|
2365
|
+
reject(error);
|
|
2366
|
+
}
|
|
2160
2367
|
}
|
|
2161
|
-
);
|
|
2368
|
+
));
|
|
2369
|
+
} catch (error) {
|
|
2370
|
+
console.log("Error creating send transport:", error);
|
|
2371
|
+
}
|
|
2372
|
+
};
|
|
2373
|
+
const producerFor = (params, option) => {
|
|
2374
|
+
if (option === "audio") return isOpen(params.audioProducer);
|
|
2375
|
+
if (option === "video") return isOpen(params.videoProducer);
|
|
2376
|
+
if (option === "screen") return isOpen(params.screenProducer);
|
|
2377
|
+
return isOpen(params.audioProducer) && isOpen(params.videoProducer);
|
|
2378
|
+
};
|
|
2379
|
+
const createSendTransport = async ({
|
|
2380
|
+
option,
|
|
2381
|
+
parameters
|
|
2382
|
+
}) => {
|
|
2383
|
+
try {
|
|
2384
|
+
const current = parameters.getCurrentParams?.() ?? parameters.getUpdatedAllParams?.() ?? parameters;
|
|
2385
|
+
const socket = current.socket;
|
|
2386
|
+
const pending = pendingSendTransportCreation(socket);
|
|
2387
|
+
if (!pending && !(current.transportCreated && isOpen(current.producerTransport))) {
|
|
2388
|
+
await trackSendTransportCreation(socket, () => createSendTransportNow({ option, parameters }));
|
|
2389
|
+
return;
|
|
2390
|
+
}
|
|
2391
|
+
if (pending) await pending.catch(() => void 0);
|
|
2392
|
+
const latest = parameters.getCurrentParams?.() ?? parameters.getUpdatedAllParams?.() ?? parameters;
|
|
2393
|
+
if (!isOpen(latest.producerTransport)) {
|
|
2394
|
+
await createSendTransport({ option, parameters });
|
|
2395
|
+
return;
|
|
2396
|
+
}
|
|
2397
|
+
if (producerFor(latest, option)) return;
|
|
2398
|
+
const connectSendTransport2 = latest.connectSendTransport ?? parameters.connectSendTransport;
|
|
2399
|
+
await connectSendTransport2({
|
|
2400
|
+
targetOption: "all",
|
|
2401
|
+
option,
|
|
2402
|
+
parameters: { ...latest, producerTransport: latest.producerTransport }
|
|
2403
|
+
});
|
|
2162
2404
|
} catch (error) {
|
|
2163
2405
|
console.log("Error creating send transport:", error);
|
|
2164
2406
|
}
|
|
@@ -2232,6 +2474,99 @@ const disconnectSendTransportAudio = async ({
|
|
|
2232
2474
|
console.log("Error disconnecting primary audio send transport:", error);
|
|
2233
2475
|
}
|
|
2234
2476
|
};
|
|
2477
|
+
const currentScreenAudioProducer = (parameters) => parameters.screenAudioProducer || recallScreenAudioProducer(parameters.socket);
|
|
2478
|
+
const storeScreenAudioProducer = (parameters, producer) => {
|
|
2479
|
+
rememberScreenAudioProducer(parameters.socket, producer);
|
|
2480
|
+
parameters.updateScreenAudioProducer?.(producer);
|
|
2481
|
+
};
|
|
2482
|
+
const disconnectSendTransportScreenAudio = async ({
|
|
2483
|
+
parameters,
|
|
2484
|
+
notifyServer = false
|
|
2485
|
+
}) => {
|
|
2486
|
+
const params = parameters.getUpdatedAllParams ? parameters.getUpdatedAllParams() : parameters;
|
|
2487
|
+
const producer = currentScreenAudioProducer(params);
|
|
2488
|
+
if (!producer) return;
|
|
2489
|
+
try {
|
|
2490
|
+
if (!producer.closed) producer.close();
|
|
2491
|
+
} catch {
|
|
2492
|
+
}
|
|
2493
|
+
storeScreenAudioProducer(params, null);
|
|
2494
|
+
if (notifyServer) {
|
|
2495
|
+
try {
|
|
2496
|
+
params.socket?.emit("closeScreenAudioProducer");
|
|
2497
|
+
} catch {
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
};
|
|
2501
|
+
const toggleScreenAudio = ({ parameters, paused }) => {
|
|
2502
|
+
const params = parameters.getUpdatedAllParams ? parameters.getUpdatedAllParams() : parameters;
|
|
2503
|
+
const producer = currentScreenAudioProducer(params);
|
|
2504
|
+
if (!producer || producer.closed) return null;
|
|
2505
|
+
const next = paused ?? !producer.paused;
|
|
2506
|
+
if (next && !producer.paused) producer.pause();
|
|
2507
|
+
if (!next && producer.paused) producer.resume();
|
|
2508
|
+
params.updateScreenAudioProducer?.(producer);
|
|
2509
|
+
return producer.paused;
|
|
2510
|
+
};
|
|
2511
|
+
const produceOnce = async (transport, track) => {
|
|
2512
|
+
const producer = await transport.produce({
|
|
2513
|
+
track,
|
|
2514
|
+
codecOptions: SCREEN_AUDIO_CODEC_OPTIONS,
|
|
2515
|
+
appData: { mediaTag: SCREEN_AUDIO_MEDIA_TAG },
|
|
2516
|
+
// The track belongs to the screen share stream, which stops it with the share.
|
|
2517
|
+
stopTracks: false
|
|
2518
|
+
});
|
|
2519
|
+
if (!producer?.id) {
|
|
2520
|
+
try {
|
|
2521
|
+
producer?.close();
|
|
2522
|
+
} catch {
|
|
2523
|
+
}
|
|
2524
|
+
return null;
|
|
2525
|
+
}
|
|
2526
|
+
return producer;
|
|
2527
|
+
};
|
|
2528
|
+
const connectSendTransportScreenAudio = async ({
|
|
2529
|
+
stream,
|
|
2530
|
+
parameters,
|
|
2531
|
+
retryDelayMs = 600
|
|
2532
|
+
}) => {
|
|
2533
|
+
const params = parameters.getUpdatedAllParams ? parameters.getUpdatedAllParams() : parameters;
|
|
2534
|
+
const track = stream?.getAudioTracks?.()[0];
|
|
2535
|
+
if (!track || track.readyState === "ended") return null;
|
|
2536
|
+
if (!shouldShareScreenAudio(params)) return null;
|
|
2537
|
+
const transport = params.producerTransport;
|
|
2538
|
+
if (!transport || transport.closed) return null;
|
|
2539
|
+
const existing = currentScreenAudioProducer(params);
|
|
2540
|
+
if (existing && !existing.closed) return existing;
|
|
2541
|
+
try {
|
|
2542
|
+
let producer = await produceOnce(transport, track);
|
|
2543
|
+
const trackEnded = () => track.readyState === "ended";
|
|
2544
|
+
if (!producer && retryDelayMs > 0 && !trackEnded()) {
|
|
2545
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
|
|
2546
|
+
producer = await produceOnce(transport, track);
|
|
2547
|
+
}
|
|
2548
|
+
if (!producer) return null;
|
|
2549
|
+
storeScreenAudioProducer(params, producer);
|
|
2550
|
+
const screenProducer = params.screenProducer;
|
|
2551
|
+
if (screenProducer?.paused) producer.pause();
|
|
2552
|
+
screenProducer?.observer?.on("pause", () => {
|
|
2553
|
+
if (!producer.closed) producer.pause();
|
|
2554
|
+
});
|
|
2555
|
+
screenProducer?.observer?.on("resume", () => {
|
|
2556
|
+
if (!producer.closed) producer.resume();
|
|
2557
|
+
});
|
|
2558
|
+
screenProducer?.observer?.on("close", () => {
|
|
2559
|
+
void disconnectSendTransportScreenAudio({ parameters: params });
|
|
2560
|
+
});
|
|
2561
|
+
track.addEventListener("ended", () => {
|
|
2562
|
+
void disconnectSendTransportScreenAudio({ parameters: params, notifyServer: true });
|
|
2563
|
+
});
|
|
2564
|
+
return producer;
|
|
2565
|
+
} catch (error) {
|
|
2566
|
+
console.log("connectSendTransportScreenAudio error", error);
|
|
2567
|
+
return null;
|
|
2568
|
+
}
|
|
2569
|
+
};
|
|
2235
2570
|
const disconnectLocalSendTransportScreen = async ({ parameters }) => {
|
|
2236
2571
|
try {
|
|
2237
2572
|
let {
|
|
@@ -2253,6 +2588,10 @@ const disconnectLocalSendTransportScreen = async ({ parameters }) => {
|
|
|
2253
2588
|
const disconnectSendTransportScreen = async ({ parameters }) => {
|
|
2254
2589
|
let { getUpdatedAllParams } = parameters;
|
|
2255
2590
|
parameters = getUpdatedAllParams();
|
|
2591
|
+
try {
|
|
2592
|
+
await disconnectSendTransportScreenAudio({ parameters });
|
|
2593
|
+
} catch {
|
|
2594
|
+
}
|
|
2256
2595
|
try {
|
|
2257
2596
|
let {
|
|
2258
2597
|
screenProducer,
|
|
@@ -3654,6 +3993,11 @@ async function startShareScreen({ parameters }) {
|
|
|
3654
3993
|
onWeb,
|
|
3655
3994
|
targetWidth = 1280,
|
|
3656
3995
|
targetHeight = 720,
|
|
3996
|
+
supportsScreenAudio,
|
|
3997
|
+
screenAudioEnabled,
|
|
3998
|
+
screenAudioMode = "ask",
|
|
3999
|
+
screenAudioPrompt,
|
|
4000
|
+
displayAudioCapable,
|
|
3657
4001
|
streamSuccessScreen: streamSuccessScreen2
|
|
3658
4002
|
} = parameters;
|
|
3659
4003
|
try {
|
|
@@ -3666,15 +4010,23 @@ async function startShareScreen({ parameters }) {
|
|
|
3666
4010
|
return;
|
|
3667
4011
|
}
|
|
3668
4012
|
if (mediaDevices && mediaDevices.getDisplayMedia) {
|
|
4013
|
+
let withAudio = shouldShareScreenAudio({ supportsScreenAudio, screenAudioEnabled, screenAudioMode }) && (displayAudioCapable ?? canCaptureDisplayAudio());
|
|
4014
|
+
if (withAudio && screenAudioMode === "ask" && screenAudioPrompt) {
|
|
4015
|
+
const choice = await screenAudioPrompt();
|
|
4016
|
+
if (choice === null) {
|
|
4017
|
+
updateShared(false);
|
|
4018
|
+
return;
|
|
4019
|
+
}
|
|
4020
|
+
withAudio = choice === "audio";
|
|
4021
|
+
}
|
|
3669
4022
|
shared = true;
|
|
3670
|
-
await mediaDevices.getDisplayMedia(
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
}
|
|
3676
|
-
|
|
3677
|
-
}).then(async (stream) => {
|
|
4023
|
+
await mediaDevices.getDisplayMedia(
|
|
4024
|
+
buildDisplayMediaOptions({
|
|
4025
|
+
targetWidth,
|
|
4026
|
+
targetHeight,
|
|
4027
|
+
withAudio
|
|
4028
|
+
})
|
|
4029
|
+
).then(async (stream) => {
|
|
3678
4030
|
await streamSuccessScreen2({ stream, parameters });
|
|
3679
4031
|
}).catch(async () => {
|
|
3680
4032
|
shared = false;
|
|
@@ -4102,6 +4454,14 @@ const streamSuccessScreen = async ({
|
|
|
4102
4454
|
});
|
|
4103
4455
|
}
|
|
4104
4456
|
socket.emit("startScreenShare");
|
|
4457
|
+
try {
|
|
4458
|
+
await connectSendTransportScreenAudio({
|
|
4459
|
+
stream: localStreamScreen,
|
|
4460
|
+
parameters: getUpdatedAllParams()
|
|
4461
|
+
});
|
|
4462
|
+
} catch (error) {
|
|
4463
|
+
console.log("Screen audio not shared:", error);
|
|
4464
|
+
}
|
|
4105
4465
|
} catch (error) {
|
|
4106
4466
|
showAlert?.({
|
|
4107
4467
|
message: error.message,
|
|
@@ -5373,6 +5733,7 @@ const getPipedProducersAlt = async ({
|
|
|
5373
5733
|
} else {
|
|
5374
5734
|
producerId = producer.id;
|
|
5375
5735
|
translationMeta = producer.translationMeta || null;
|
|
5736
|
+
markScreenAudioProducer(producerId, producer.mediaTag);
|
|
5376
5737
|
}
|
|
5377
5738
|
if (translationMeta) {
|
|
5378
5739
|
const shouldConsume = shouldConsumeTranslationProducer(
|
|
@@ -5591,8 +5952,13 @@ function updateParticipantAudioDecibels({
|
|
|
5591
5952
|
}
|
|
5592
5953
|
updateAudioDecibels(audioDecibels);
|
|
5593
5954
|
}
|
|
5955
|
+
exports.CONSUME_REJECTION_COOLDOWN_MS = CONSUME_REJECTION_COOLDOWN_MS;
|
|
5956
|
+
exports.SCREEN_AUDIO_CODEC_OPTIONS = SCREEN_AUDIO_CODEC_OPTIONS;
|
|
5957
|
+
exports.SCREEN_AUDIO_MEDIA_TAG = SCREEN_AUDIO_MEDIA_TAG;
|
|
5594
5958
|
exports.autoAdjust = autoAdjust;
|
|
5959
|
+
exports.buildDisplayMediaOptions = buildDisplayMediaOptions;
|
|
5595
5960
|
exports.calculateRowsAndColumns = calculateRowsAndColumns;
|
|
5961
|
+
exports.canCaptureDisplayAudio = canCaptureDisplayAudio;
|
|
5596
5962
|
exports.changeVids = changeVids;
|
|
5597
5963
|
exports.checkGrid = checkGrid;
|
|
5598
5964
|
exports.checkPermission = checkPermission;
|
|
@@ -5608,6 +5974,7 @@ exports.connectRecvTransport = connectRecvTransport;
|
|
|
5608
5974
|
exports.connectSendTransport = connectSendTransport;
|
|
5609
5975
|
exports.connectSendTransportAudio = connectSendTransportAudio;
|
|
5610
5976
|
exports.connectSendTransportScreen = connectSendTransportScreen;
|
|
5977
|
+
exports.connectSendTransportScreenAudio = connectSendTransportScreenAudio;
|
|
5611
5978
|
exports.connectSendTransportVideo = connectSendTransportVideo;
|
|
5612
5979
|
exports.connectSocket = connectSocket;
|
|
5613
5980
|
exports.consumerResume = consumerResume;
|
|
@@ -5616,16 +5983,20 @@ exports.createFrameworkConsumerContractError = createFrameworkConsumerContractEr
|
|
|
5616
5983
|
exports.createSendTransport = createSendTransport;
|
|
5617
5984
|
exports.disconnectSendTransportAudio = disconnectSendTransportAudio;
|
|
5618
5985
|
exports.disconnectSendTransportScreen = disconnectSendTransportScreen;
|
|
5986
|
+
exports.disconnectSendTransportScreenAudio = disconnectSendTransportScreenAudio;
|
|
5619
5987
|
exports.disconnectSendTransportVideo = disconnectSendTransportVideo;
|
|
5620
5988
|
exports.disconnectSocket = disconnectSocket;
|
|
5621
5989
|
exports.dispStreams = dispStreams;
|
|
5990
|
+
exports.forgetScreenAudioProducer = forgetScreenAudioProducer;
|
|
5622
5991
|
exports.generatePageContent = generatePageContent;
|
|
5623
5992
|
exports.getEstimate = getEstimate;
|
|
5624
5993
|
exports.getPipedProducersAlt = getPipedProducersAlt;
|
|
5625
5994
|
exports.getProducersPiped = getProducersPiped;
|
|
5626
5995
|
exports.getVideos = getVideos;
|
|
5996
|
+
exports.isScreenAudioProducer = isScreenAudioProducer;
|
|
5627
5997
|
exports.joinConRoom = joinConRoom;
|
|
5628
5998
|
exports.joinConsumeRoom = joinConsumeRoom;
|
|
5999
|
+
exports.markScreenAudioProducer = markScreenAudioProducer;
|
|
5629
6000
|
exports.mixStreams = mixStreams;
|
|
5630
6001
|
exports.newPipeProducer = newPipeProducer;
|
|
5631
6002
|
exports.onScreenChanges = onScreenChanges;
|
|
@@ -5635,16 +6006,22 @@ exports.producerClosed = producerClosed;
|
|
|
5635
6006
|
exports.rePort = rePort;
|
|
5636
6007
|
exports.reUpdateInter = reUpdateInter;
|
|
5637
6008
|
exports.readjust = readjust;
|
|
6009
|
+
exports.recallScreenAudioProducer = recallScreenAudioProducer;
|
|
5638
6010
|
exports.receiveAllPipedTransports = receiveAllPipedTransports;
|
|
5639
6011
|
exports.receiveRoomMessages = receiveRoomMessages;
|
|
6012
|
+
exports.rememberScreenAudioProducer = rememberScreenAudioProducer;
|
|
5640
6013
|
exports.reorderStreams = reorderStreams;
|
|
5641
6014
|
exports.requestScreenShare = requestScreenShare;
|
|
5642
6015
|
exports.resumePauseAudioStreams = resumePauseAudioStreams;
|
|
5643
6016
|
exports.resumePauseStreams = resumePauseStreams;
|
|
5644
6017
|
exports.resumeSendTransportAudio = resumeSendTransportAudio;
|
|
5645
6018
|
exports.selectVideoProducerCodec = selectVideoProducerCodec;
|
|
6019
|
+
exports.setScreenAudioPaused = setScreenAudioPaused;
|
|
6020
|
+
exports.setScreenAudioVolume = setScreenAudioVolume;
|
|
6021
|
+
exports.shouldShareScreenAudio = shouldShareScreenAudio;
|
|
5646
6022
|
exports.signalNewConsumerTransport = signalNewConsumerTransport;
|
|
5647
6023
|
exports.startShareScreen = startShareScreen;
|
|
6024
|
+
exports.stopReconnectingWhenRefused = stopReconnectingWhenRefused;
|
|
5648
6025
|
exports.stopShareScreen = stopShareScreen;
|
|
5649
6026
|
exports.streamSuccessAudio = streamSuccessAudio;
|
|
5650
6027
|
exports.streamSuccessAudioSwitch = streamSuccessAudioSwitch;
|
|
@@ -5653,8 +6030,9 @@ exports.streamSuccessVideo = streamSuccessVideo;
|
|
|
5653
6030
|
exports.switchUserAudio = switchUserAudio;
|
|
5654
6031
|
exports.switchUserVideo = switchUserVideo;
|
|
5655
6032
|
exports.switchUserVideoAlt = switchUserVideoAlt;
|
|
6033
|
+
exports.toggleScreenAudio = toggleScreenAudio;
|
|
5656
6034
|
exports.trigger = trigger;
|
|
5657
6035
|
exports.updateMicLevel = updateMicLevel;
|
|
5658
6036
|
exports.updateMiniCardsGrid = updateMiniCardsGrid;
|
|
5659
6037
|
exports.updateParticipantAudioDecibels = updateParticipantAudioDecibels;
|
|
5660
|
-
//# sourceMappingURL=updateParticipantAudioDecibels-
|
|
6038
|
+
//# sourceMappingURL=updateParticipantAudioDecibels-CbCP1PDs.cjs.map
|