@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.32 → 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.
@@ -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
@@ -95,6 +95,11 @@ export declare class OdysseySpatialComms extends EventManager {
95
95
  /**
96
96
  * Mute another participant (owner only)
97
97
  */
98
+ /**
99
+ * Update mute state for all participants based on channel matching
100
+ * Called when local user switches channels
101
+ */
102
+ private updateAllParticipantsMuteState;
98
103
  muteParticipant(participantId: string): Promise<{
99
104
  success?: boolean;
100
105
  error?: string;
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,10 +418,20 @@ 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
  });
@@ -527,6 +541,24 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
527
541
  /**
528
542
  * Mute another participant (owner only)
529
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
+ }
530
562
  async muteParticipant(participantId) {
531
563
  if (!this.localParticipant || !this.room) {
532
564
  return { success: false, error: "Not in a room" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newgameplusinc/odyssey-audio-video-sdk-dev",
3
- "version": "1.0.32",
3
+ "version": "1.0.33",
4
4
  "description": "Odyssey Spatial Audio & Video SDK using MediaSoup for real-time communication",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",