mediasfu-shared 1.0.2 → 1.0.4
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 +108 -103
- package/dist/index.cjs +163 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +163 -46
- package/dist/index.js.map +1 -1
- package/package.json +99 -85
- package/src/consumers/connectIps.ts +3 -1
- package/src/consumers/connectLocalIps.ts +3 -1
- package/src/consumers/connectRecvTransport.ts +75 -21
- package/src/consumers/processConsumerTransportsAudio.ts +94 -2
- package/src/consumers/translationConsumerSwitch.ts +38 -16
- package/src/methods/requests/hostRequestResponse.ts +12 -7
- package/src/methods/socketReceive/translationReceiveMethods.ts +2 -2
- package/src/methods/stream/clickVideo.ts +6 -1
- package/src/methods/utils/resolveMediaSFURoomApi.ts +13 -1
package/dist/index.d.ts
CHANGED
|
@@ -10427,7 +10427,7 @@ export declare interface TranslationSubscribedOptions {
|
|
|
10427
10427
|
data: TranslationSubscribedData;
|
|
10428
10428
|
updateListenPreferences?: (updater: (prev: Map<string, string>) => Map<string, string>) => void;
|
|
10429
10429
|
updateTranslationProducerMap?: (updater: (prev: TranslationProducerMap) => TranslationProducerMap) => void;
|
|
10430
|
-
startConsumingTranslation?: (producerId: string, speakerId: string, language: string) => Promise<void>;
|
|
10430
|
+
startConsumingTranslation?: (producerId: string, speakerId: string, language: string, originalProducerId?: string) => Promise<void>;
|
|
10431
10431
|
showAlert?: ShowAlert;
|
|
10432
10432
|
}
|
|
10433
10433
|
|
package/dist/index.js
CHANGED
|
@@ -1241,13 +1241,15 @@ const connectIps = async ({
|
|
|
1241
1241
|
roomRecvIPs.push(ip);
|
|
1242
1242
|
updateRoomRecvIPs(roomRecvIPs);
|
|
1243
1243
|
}
|
|
1244
|
-
remote_sock.on("new-pipe-producer", async ({ producerId, islevel }) => {
|
|
1244
|
+
remote_sock.on("new-pipe-producer", async ({ producerId, islevel, isTranslation, translationMeta }) => {
|
|
1245
1245
|
if (newProducerMethod) {
|
|
1246
1246
|
await newProducerMethod({
|
|
1247
1247
|
producerId,
|
|
1248
1248
|
islevel,
|
|
1249
1249
|
nsock: remote_sock,
|
|
1250
|
-
parameters
|
|
1250
|
+
parameters,
|
|
1251
|
+
isTranslation,
|
|
1252
|
+
translationMeta
|
|
1251
1253
|
});
|
|
1252
1254
|
}
|
|
1253
1255
|
});
|
|
@@ -1288,13 +1290,15 @@ const connectLocalIps = async ({
|
|
|
1288
1290
|
parameters
|
|
1289
1291
|
}) => {
|
|
1290
1292
|
try {
|
|
1291
|
-
socket.on("new-producer", async ({ producerId, islevel }) => {
|
|
1293
|
+
socket.on("new-producer", async ({ producerId, islevel, isTranslation, translationMeta }) => {
|
|
1292
1294
|
if (newProducerMethod) {
|
|
1293
1295
|
await newProducerMethod({
|
|
1294
1296
|
producerId,
|
|
1295
1297
|
islevel,
|
|
1296
1298
|
nsock: socket,
|
|
1297
|
-
parameters
|
|
1299
|
+
parameters,
|
|
1300
|
+
isTranslation,
|
|
1301
|
+
translationMeta
|
|
1298
1302
|
});
|
|
1299
1303
|
}
|
|
1300
1304
|
});
|
|
@@ -1308,6 +1312,47 @@ const connectLocalIps = async ({
|
|
|
1308
1312
|
console.log("ConnectLocalIps error", error);
|
|
1309
1313
|
}
|
|
1310
1314
|
};
|
|
1315
|
+
const getSpeakerNameForProducerId$1 = (producerId, parameters) => {
|
|
1316
|
+
const participants = parameters.participants;
|
|
1317
|
+
const participant = participants?.find((candidate) => candidate.audioID === producerId);
|
|
1318
|
+
if (participant?.name) {
|
|
1319
|
+
return participant.name;
|
|
1320
|
+
}
|
|
1321
|
+
const audStreamName = parameters.audStreamNames?.find((stream) => stream.producerId === producerId && typeof stream.name === "string");
|
|
1322
|
+
if (audStreamName?.name) {
|
|
1323
|
+
return audStreamName.name;
|
|
1324
|
+
}
|
|
1325
|
+
return parameters.allAudioStreams?.find((stream) => stream.producerId === producerId && typeof stream.name === "string")?.name;
|
|
1326
|
+
};
|
|
1327
|
+
const isOriginalAudioSuppressedByTranslation$1 = (producerId, parameters) => {
|
|
1328
|
+
const activeTranslationProducerIds = parameters.activeTranslationProducerIds;
|
|
1329
|
+
if (activeTranslationProducerIds?.has(producerId)) {
|
|
1330
|
+
return false;
|
|
1331
|
+
}
|
|
1332
|
+
const speakerTranslationStates = parameters.speakerTranslationStates;
|
|
1333
|
+
if (!speakerTranslationStates?.size) {
|
|
1334
|
+
return false;
|
|
1335
|
+
}
|
|
1336
|
+
const speakerName = getSpeakerNameForProducerId$1(producerId, parameters);
|
|
1337
|
+
if (speakerName) {
|
|
1338
|
+
const speakerState = speakerTranslationStates.get(speakerName);
|
|
1339
|
+
if (speakerState?.enabled) {
|
|
1340
|
+
return true;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
return Array.from(speakerTranslationStates.values()).some((speakerState) => {
|
|
1344
|
+
if (!speakerState?.enabled) {
|
|
1345
|
+
return false;
|
|
1346
|
+
}
|
|
1347
|
+
if (speakerState.originalProducerId === producerId) {
|
|
1348
|
+
return true;
|
|
1349
|
+
}
|
|
1350
|
+
if (!speakerName) {
|
|
1351
|
+
return false;
|
|
1352
|
+
}
|
|
1353
|
+
return speakerState.speakerId === speakerName || speakerState.speakerName === speakerName;
|
|
1354
|
+
});
|
|
1355
|
+
};
|
|
1311
1356
|
const connectRecvTransport = async ({
|
|
1312
1357
|
consumerTransport,
|
|
1313
1358
|
remoteProducerId,
|
|
@@ -1369,24 +1414,15 @@ const connectRecvTransport = async ({
|
|
|
1369
1414
|
if (params.kind === "audio") {
|
|
1370
1415
|
try {
|
|
1371
1416
|
const updatedParams = parameters.getUpdatedAllParams();
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
if (participant?.name) {
|
|
1379
|
-
const speakerState = speakerTranslationStates.get(participant.name);
|
|
1380
|
-
if (speakerState?.enabled && speakerState.originalProducerId === remoteProducerId) {
|
|
1381
|
-
consumer.pause();
|
|
1382
|
-
nsock.emit(
|
|
1383
|
-
"consumer-pause",
|
|
1384
|
-
{ serverConsumerId: params.serverConsumerId },
|
|
1385
|
-
() => {
|
|
1386
|
-
}
|
|
1387
|
-
);
|
|
1417
|
+
if (isOriginalAudioSuppressedByTranslation$1(remoteProducerId, updatedParams)) {
|
|
1418
|
+
consumer.pause();
|
|
1419
|
+
nsock.emit(
|
|
1420
|
+
"consumer-pause",
|
|
1421
|
+
{ serverConsumerId: params.serverConsumerId },
|
|
1422
|
+
() => {
|
|
1388
1423
|
}
|
|
1389
|
-
|
|
1424
|
+
);
|
|
1425
|
+
return;
|
|
1390
1426
|
}
|
|
1391
1427
|
} catch {
|
|
1392
1428
|
}
|
|
@@ -2647,6 +2683,50 @@ async function processConsumerTransports({
|
|
|
2647
2683
|
const getProducerId$1 = (value) => {
|
|
2648
2684
|
return value?.producerId;
|
|
2649
2685
|
};
|
|
2686
|
+
const getSpeakerNameForProducerId = (producerId, parameters) => {
|
|
2687
|
+
const participants = parameters.participants;
|
|
2688
|
+
const participant = participants?.find((candidate) => candidate.audioID === producerId);
|
|
2689
|
+
if (participant?.name) {
|
|
2690
|
+
return participant.name;
|
|
2691
|
+
}
|
|
2692
|
+
const audStreamName = parameters.audStreamNames?.find((stream) => stream.producerId === producerId && typeof stream.name === "string");
|
|
2693
|
+
if (audStreamName?.name) {
|
|
2694
|
+
return audStreamName.name;
|
|
2695
|
+
}
|
|
2696
|
+
return parameters.allAudioStreams?.find((stream) => stream.producerId === producerId && typeof stream.name === "string")?.name;
|
|
2697
|
+
};
|
|
2698
|
+
const isOriginalAudioSuppressedByTranslation = (producerId, parameters) => {
|
|
2699
|
+
if (!producerId) {
|
|
2700
|
+
return false;
|
|
2701
|
+
}
|
|
2702
|
+
const activeTranslationProducerIds = parameters.activeTranslationProducerIds;
|
|
2703
|
+
if (activeTranslationProducerIds?.has(producerId)) {
|
|
2704
|
+
return false;
|
|
2705
|
+
}
|
|
2706
|
+
const speakerTranslationStates = parameters.speakerTranslationStates;
|
|
2707
|
+
if (!speakerTranslationStates?.size) {
|
|
2708
|
+
return false;
|
|
2709
|
+
}
|
|
2710
|
+
const speakerName = getSpeakerNameForProducerId(producerId, parameters);
|
|
2711
|
+
if (speakerName) {
|
|
2712
|
+
const speakerState = speakerTranslationStates.get(speakerName);
|
|
2713
|
+
if (speakerState?.enabled) {
|
|
2714
|
+
return true;
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
return Array.from(speakerTranslationStates.values()).some((speakerState) => {
|
|
2718
|
+
if (!speakerState?.enabled) {
|
|
2719
|
+
return false;
|
|
2720
|
+
}
|
|
2721
|
+
if (speakerState.originalProducerId === producerId) {
|
|
2722
|
+
return true;
|
|
2723
|
+
}
|
|
2724
|
+
if (!speakerName) {
|
|
2725
|
+
return false;
|
|
2726
|
+
}
|
|
2727
|
+
return speakerState.speakerId === speakerName || speakerState.speakerName === speakerName;
|
|
2728
|
+
});
|
|
2729
|
+
};
|
|
2650
2730
|
const processConsumerTransportsAudio = async ({
|
|
2651
2731
|
consumerTransports,
|
|
2652
2732
|
lStreams,
|
|
@@ -2660,12 +2740,12 @@ const processConsumerTransportsAudio = async ({
|
|
|
2660
2740
|
});
|
|
2661
2741
|
};
|
|
2662
2742
|
const consumerTransportsToResume = consumerTransports.filter(
|
|
2663
|
-
(transport) => isValidProducerId(transport.producerId, lStreams) && transport.consumer?.paused === true && transport.consumer?.kind === "audio"
|
|
2743
|
+
(transport) => isValidProducerId(transport.producerId, lStreams) && !isOriginalAudioSuppressedByTranslation(transport.producerId, parameters) && transport.consumer?.paused === true && transport.consumer?.kind === "audio"
|
|
2664
2744
|
);
|
|
2665
2745
|
const consumerTransportsToPause = consumerTransports.filter(
|
|
2666
|
-
(transport) => transport.producerId && transport.producerId !== null && transport.producerId !== "" && !lStreams.some(
|
|
2746
|
+
(transport) => transport.producerId && transport.producerId !== null && transport.producerId !== "" && (isOriginalAudioSuppressedByTranslation(transport.producerId, parameters) || !lStreams.some(
|
|
2667
2747
|
(stream) => getProducerId$1(stream) === transport.producerId
|
|
2668
|
-
) && transport.consumer && transport.consumer?.kind && transport.consumer.paused !== true && transport.consumer.kind === "audio"
|
|
2748
|
+
)) && transport.consumer && transport.consumer?.kind && transport.consumer.paused !== true && transport.consumer.kind === "audio"
|
|
2669
2749
|
);
|
|
2670
2750
|
await sleep2({ ms: 100 });
|
|
2671
2751
|
for (const transport of consumerTransportsToPause) {
|
|
@@ -2678,6 +2758,9 @@ const processConsumerTransportsAudio = async ({
|
|
|
2678
2758
|
);
|
|
2679
2759
|
}
|
|
2680
2760
|
for (const transport of consumerTransportsToResume) {
|
|
2761
|
+
if (isOriginalAudioSuppressedByTranslation(transport.producerId, parameters)) {
|
|
2762
|
+
continue;
|
|
2763
|
+
}
|
|
2681
2764
|
transport.socket_.emit(
|
|
2682
2765
|
"consumer-resume",
|
|
2683
2766
|
{ serverConsumerId: transport.serverConsumerTransportId },
|
|
@@ -4133,7 +4216,9 @@ const clickVideo = async ({ parameters }) => {
|
|
|
4133
4216
|
audioSetting,
|
|
4134
4217
|
videoSetting,
|
|
4135
4218
|
screenshareSetting,
|
|
4136
|
-
chatSetting
|
|
4219
|
+
chatSetting,
|
|
4220
|
+
permissionConfig: parameters.permissionConfig,
|
|
4221
|
+
participantLevel: islevel
|
|
4137
4222
|
});
|
|
4138
4223
|
} else {
|
|
4139
4224
|
response = 0;
|
|
@@ -5288,11 +5373,17 @@ const hostRequestResponse = async ({
|
|
|
5288
5373
|
updateChatRequestTime,
|
|
5289
5374
|
updateRequestIntervalSeconds
|
|
5290
5375
|
}) => {
|
|
5376
|
+
const requestType = requestResponse.type ?? requestResponse.icon;
|
|
5291
5377
|
const filteredRequests = requestList.filter(
|
|
5292
|
-
(request) =>
|
|
5378
|
+
(request) => {
|
|
5379
|
+
const matchesId = request.id === requestResponse.id;
|
|
5380
|
+
const matchesType = requestType == null || request.icon === requestType;
|
|
5381
|
+
const matchesName = requestResponse.name == null || request.name === requestResponse.name;
|
|
5382
|
+
const matchesUsername = requestResponse.username == null || request.username === requestResponse.username;
|
|
5383
|
+
return !(matchesId && matchesType && matchesName && matchesUsername);
|
|
5384
|
+
}
|
|
5293
5385
|
);
|
|
5294
5386
|
updateRequestList(filteredRequests);
|
|
5295
|
-
const requestType = requestResponse.type;
|
|
5296
5387
|
if (requestResponse.action === "accepted") {
|
|
5297
5388
|
switch (requestType) {
|
|
5298
5389
|
case "fa-microphone":
|
|
@@ -6258,11 +6349,20 @@ const updateRoomParametersClient = ({ parameters }) => {
|
|
|
6258
6349
|
}
|
|
6259
6350
|
};
|
|
6260
6351
|
const DEFAULT_MEDIA_SFU_ROOM_API_URL = "https://mediasfu.com/v1/rooms/";
|
|
6352
|
+
const normalizeManagedRoomApi = (normalizedLink) => {
|
|
6353
|
+
if (normalizedLink.includes("/v1/rooms")) {
|
|
6354
|
+
return `${normalizedLink.replace(/\/$/, "")}/`;
|
|
6355
|
+
}
|
|
6356
|
+
return `${normalizedLink.replace(/\/$/, "")}/v1/rooms/`;
|
|
6357
|
+
};
|
|
6261
6358
|
const resolveMediaSFURoomApi = (localLink, action) => {
|
|
6262
6359
|
const normalizedLink = localLink?.trim();
|
|
6263
|
-
if (!normalizedLink
|
|
6360
|
+
if (!normalizedLink) {
|
|
6264
6361
|
return DEFAULT_MEDIA_SFU_ROOM_API_URL;
|
|
6265
6362
|
}
|
|
6363
|
+
if (normalizedLink.includes("mediasfu.com")) {
|
|
6364
|
+
return normalizeManagedRoomApi(normalizedLink);
|
|
6365
|
+
}
|
|
6266
6366
|
return `${normalizedLink.replace(/\/$/, "")}/${action}`;
|
|
6267
6367
|
};
|
|
6268
6368
|
const readResponseError$1 = async (response) => {
|
|
@@ -7336,15 +7436,22 @@ const pauseOriginalProducer = async ({
|
|
|
7336
7436
|
const transport = consumerTransports.find(
|
|
7337
7437
|
(t) => t.producerId === originalProducerId && t.consumer?.kind === "audio"
|
|
7338
7438
|
);
|
|
7339
|
-
if (
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7439
|
+
if (!transport?.consumer) {
|
|
7440
|
+
return;
|
|
7441
|
+
}
|
|
7442
|
+
if (transport.consumer.track) {
|
|
7443
|
+
transport.consumer.track.enabled = false;
|
|
7444
|
+
}
|
|
7445
|
+
if (transport.consumer.paused) {
|
|
7446
|
+
return;
|
|
7347
7447
|
}
|
|
7448
|
+
transport.consumer.pause();
|
|
7449
|
+
transport.socket_?.emit(
|
|
7450
|
+
"consumer-pause",
|
|
7451
|
+
{ serverConsumerId: transport.serverConsumerTransportId },
|
|
7452
|
+
async () => {
|
|
7453
|
+
}
|
|
7454
|
+
);
|
|
7348
7455
|
} catch (error) {
|
|
7349
7456
|
console.error("[TranslationSwitch] Error pausing original producer:", error);
|
|
7350
7457
|
}
|
|
@@ -7362,17 +7469,27 @@ const resumeOriginalProducer = async ({
|
|
|
7362
7469
|
const transport = consumerTransports.find(
|
|
7363
7470
|
(t) => t.producerId === originalProducerId && t.consumer?.kind === "audio"
|
|
7364
7471
|
);
|
|
7365
|
-
if (transport
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7472
|
+
if (!transport?.consumer) {
|
|
7473
|
+
return;
|
|
7474
|
+
}
|
|
7475
|
+
if (!transport.consumer.paused) {
|
|
7476
|
+
if (transport.consumer.track) {
|
|
7477
|
+
transport.consumer.track.enabled = true;
|
|
7478
|
+
}
|
|
7479
|
+
return;
|
|
7480
|
+
}
|
|
7481
|
+
transport.socket_?.emit(
|
|
7482
|
+
"consumer-resume",
|
|
7483
|
+
{ serverConsumerId: transport.serverConsumerTransportId },
|
|
7484
|
+
async ({ resumed }) => {
|
|
7485
|
+
if (resumed) {
|
|
7486
|
+
if (transport.consumer.track) {
|
|
7487
|
+
transport.consumer.track.enabled = true;
|
|
7372
7488
|
}
|
|
7489
|
+
transport.consumer.resume();
|
|
7373
7490
|
}
|
|
7374
|
-
|
|
7375
|
-
|
|
7491
|
+
}
|
|
7492
|
+
);
|
|
7376
7493
|
} catch (error) {
|
|
7377
7494
|
console.error("[TranslationSwitch] Error resuming original producer:", error);
|
|
7378
7495
|
}
|
|
@@ -12219,7 +12336,7 @@ const translationSubscribed = async ({
|
|
|
12219
12336
|
}));
|
|
12220
12337
|
}
|
|
12221
12338
|
if (producerId && startConsumingTranslation) {
|
|
12222
|
-
await startConsumingTranslation(producerId, speakerId, language);
|
|
12339
|
+
await startConsumingTranslation(producerId, speakerId, language, originalProducerId);
|
|
12223
12340
|
}
|
|
12224
12341
|
if (showAlert && channelCreated) {
|
|
12225
12342
|
showAlert({
|