@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.31 → 1.0.33
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/dist/SpatialAudioManager.d.ts +7 -0
- package/dist/SpatialAudioManager.js +13 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +54 -1
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
|
@@ -88,6 +88,13 @@ export declare class SpatialAudioManager extends EventManager {
|
|
|
88
88
|
y: number;
|
|
89
89
|
z: number;
|
|
90
90
|
}): void;
|
|
91
|
+
/**
|
|
92
|
+
* Mute or unmute a participant's audio
|
|
93
|
+
* Used for channel-based audio routing (huddle vs spatial)
|
|
94
|
+
* @param participantId The participant to mute/unmute
|
|
95
|
+
* @param muted True to mute, false to unmute
|
|
96
|
+
*/
|
|
97
|
+
setParticipantMuted(participantId: string, muted: boolean): void;
|
|
91
98
|
setListenerPosition(position: Position, orientation: {
|
|
92
99
|
forwardX: number;
|
|
93
100
|
forwardY: number;
|
|
@@ -235,6 +235,19 @@ class SpatialAudioManager extends EventManager_1.EventManager {
|
|
|
235
235
|
nodes.gain.gain.setTargetAtTime(distanceGain, this.audioContext.currentTime, 0.05);
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Mute or unmute a participant's audio
|
|
240
|
+
* Used for channel-based audio routing (huddle vs spatial)
|
|
241
|
+
* @param participantId The participant to mute/unmute
|
|
242
|
+
* @param muted True to mute, false to unmute
|
|
243
|
+
*/
|
|
244
|
+
setParticipantMuted(participantId, muted) {
|
|
245
|
+
const nodes = this.participantNodes.get(participantId);
|
|
246
|
+
if (nodes?.gain) {
|
|
247
|
+
// Set gain to 0 (muted) or 1 (unmuted) immediately
|
|
248
|
+
nodes.gain.gain.setValueAtTime(muted ? 0 : 1, this.audioContext.currentTime);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
238
251
|
setListenerPosition(position, orientation) {
|
|
239
252
|
const normalizedPosition = this.normalizePositionUnits(position);
|
|
240
253
|
this.applyListenerTransform(normalizedPosition, orientation);
|
package/dist/index.d.ts
CHANGED
|
@@ -92,6 +92,18 @@ export declare class OdysseySpatialComms extends EventManager {
|
|
|
92
92
|
* Get participant's current channel
|
|
93
93
|
*/
|
|
94
94
|
getParticipantChannel(participantId: string): Promise<string>;
|
|
95
|
+
/**
|
|
96
|
+
* Mute another participant (owner only)
|
|
97
|
+
*/
|
|
98
|
+
/**
|
|
99
|
+
* Update mute state for all participants based on channel matching
|
|
100
|
+
* Called when local user switches channels
|
|
101
|
+
*/
|
|
102
|
+
private updateAllParticipantsMuteState;
|
|
103
|
+
muteParticipant(participantId: string): Promise<{
|
|
104
|
+
success?: boolean;
|
|
105
|
+
error?: string;
|
|
106
|
+
}>;
|
|
95
107
|
/**
|
|
96
108
|
* Get local participant's current channel
|
|
97
109
|
*/
|
package/dist/index.js
CHANGED
|
@@ -315,11 +315,15 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
|
|
|
315
315
|
}
|
|
316
316
|
else {
|
|
317
317
|
// Check if participant is in huddle - if so, skip spatial audio
|
|
318
|
-
const participantChannel = participant.currentChannel;
|
|
318
|
+
const participantChannel = participant.currentChannel || "spatial";
|
|
319
319
|
const isInHuddle = participantChannel === "odyssey-huddle";
|
|
320
320
|
// Setup spatial audio with full 3D positioning (disabled for huddle users)
|
|
321
321
|
await this.spatialAudioManager.setupSpatialAudioForParticipant(participant.participantId, track, isInHuddle // Disable spatial audio for huddle users
|
|
322
322
|
);
|
|
323
|
+
// CRITICAL: Mute if not in same channel
|
|
324
|
+
const myChannel = this.localParticipant?.currentChannel || "spatial";
|
|
325
|
+
const shouldMute = myChannel !== participantChannel;
|
|
326
|
+
this.spatialAudioManager.setParticipantMuted(participant.participantId, shouldMute);
|
|
323
327
|
// Only update spatial audio position if NOT in huddle
|
|
324
328
|
if (!isInHuddle) {
|
|
325
329
|
this.spatialAudioManager.updateSpatialAudio(participant.participantId, data.position);
|
|
@@ -414,13 +418,27 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
|
|
|
414
418
|
console.error(`Failed to update spatial audio for ${participant.participantId}:`, err);
|
|
415
419
|
});
|
|
416
420
|
}
|
|
421
|
+
// CRITICAL: Mute/unmute based on channel matching
|
|
422
|
+
// If I'm in huddle and they're in spatial -> MUTE them
|
|
423
|
+
// If I'm in spatial and they're in huddle -> MUTE them
|
|
424
|
+
// If we're in the same channel -> UNMUTE them
|
|
425
|
+
const myChannel = this.localParticipant?.currentChannel || "spatial";
|
|
426
|
+
const theirChannel = data.channelId || "spatial";
|
|
427
|
+
const shouldMute = myChannel !== theirChannel;
|
|
428
|
+
this.spatialAudioManager.setParticipantMuted(participant.participantId, shouldMute);
|
|
417
429
|
}
|
|
418
430
|
// Update local participant if it's them
|
|
419
431
|
if (this.localParticipant?.participantId === data.participantId && this.localParticipant !== null) {
|
|
420
432
|
this.localParticipant.currentChannel = data.channelId;
|
|
433
|
+
// When LOCAL user changes channel, update ALL other participants' mute state
|
|
434
|
+
this.updateAllParticipantsMuteState();
|
|
421
435
|
}
|
|
422
436
|
this.emit("participant-channel-changed", data);
|
|
423
437
|
});
|
|
438
|
+
this.socket.on("mute-requested", (data) => {
|
|
439
|
+
// Owner has requested this participant to mute
|
|
440
|
+
this.emit("mute-requested", data);
|
|
441
|
+
});
|
|
424
442
|
}
|
|
425
443
|
// ==================== HUDDLE METHODS ====================
|
|
426
444
|
/**
|
|
@@ -520,6 +538,41 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
|
|
|
520
538
|
});
|
|
521
539
|
});
|
|
522
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Mute another participant (owner only)
|
|
543
|
+
*/
|
|
544
|
+
/**
|
|
545
|
+
* Update mute state for all participants based on channel matching
|
|
546
|
+
* Called when local user switches channels
|
|
547
|
+
*/
|
|
548
|
+
updateAllParticipantsMuteState() {
|
|
549
|
+
if (!this.localParticipant || !this.room)
|
|
550
|
+
return;
|
|
551
|
+
const myChannel = this.localParticipant.currentChannel || "spatial";
|
|
552
|
+
this.room.participants.forEach((participant) => {
|
|
553
|
+
// Skip local participant (never hear yourself)
|
|
554
|
+
if (participant.participantId === this.localParticipant?.participantId) {
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
const theirChannel = participant.currentChannel || "spatial";
|
|
558
|
+
const shouldMute = myChannel !== theirChannel;
|
|
559
|
+
this.spatialAudioManager.setParticipantMuted(participant.participantId, shouldMute);
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
async muteParticipant(participantId) {
|
|
563
|
+
if (!this.localParticipant || !this.room) {
|
|
564
|
+
return { success: false, error: "Not in a room" };
|
|
565
|
+
}
|
|
566
|
+
return new Promise((resolve) => {
|
|
567
|
+
this.socket.emit("mute-participant", {
|
|
568
|
+
targetParticipantId: participantId,
|
|
569
|
+
roomId: this.room.id,
|
|
570
|
+
requesterId: this.localParticipant.participantId,
|
|
571
|
+
}, (response) => {
|
|
572
|
+
resolve(response);
|
|
573
|
+
});
|
|
574
|
+
});
|
|
575
|
+
}
|
|
523
576
|
/**
|
|
524
577
|
* Get local participant's current channel
|
|
525
578
|
*/
|
package/dist/types.d.ts
CHANGED
|
@@ -56,4 +56,4 @@ export interface ParticipantsSnapshotEvent {
|
|
|
56
56
|
}>;
|
|
57
57
|
timestamp: number;
|
|
58
58
|
}
|
|
59
|
-
export type OdysseyEvent = "connected" | "disconnected" | "room-joined" | "all-participants-update" | "new-participant" | "participant-left" | "producer-created" | "consumer-created" | "participant-media-state-updated" | "participant-position-updated" | "error" | "huddle-invite-received" | "private-huddle-started" | "huddle-updated" | "huddle-invite-rejected" | "huddle-ended" | "participant-channel-changed";
|
|
59
|
+
export type OdysseyEvent = "connected" | "disconnected" | "room-joined" | "all-participants-update" | "new-participant" | "participant-left" | "producer-created" | "consumer-created" | "participant-media-state-updated" | "participant-position-updated" | "error" | "huddle-invite-received" | "private-huddle-started" | "huddle-updated" | "huddle-invite-rejected" | "huddle-ended" | "participant-channel-changed" | "mute-requested";
|
package/package.json
CHANGED