@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.259 → 1.0.261

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.
@@ -63,18 +63,11 @@ class MLNoiseSuppressor {
63
63
  // Set TensorFlow.js backend
64
64
  await tf.setBackend('webgl');
65
65
  await tf.ready();
66
- // Load model with input shape fix
67
- const modelJson = await (await fetch(modelUrl)).json();
68
- if (modelJson.modelTopology?.config?.layers?.[0]?.config
69
- ?.batch_input_shape === undefined) {
70
- modelJson.modelTopology.config.layers[0].config.batch_input_shape = [
71
- null,
72
- 257,
73
- 1,
74
- 1,
75
- ];
76
- }
77
- this.model = await tf.loadLayersModel(tf.io.fromMemory(modelJson.modelTopology, modelJson.weightsManifest[0].weights));
66
+ // Load model - use standard loadLayersModel instead of fromMemory
67
+ // This handles weight loading automatically
68
+ console.log(`[MLNoiseSuppressor] Loading model from: ${modelUrl}`);
69
+ this.model = await tf.loadLayersModel(modelUrl);
70
+ console.log(`[MLNoiseSuppressor] Model loaded successfully`);
78
71
  // Load config
79
72
  const baseUrl = modelUrl.substring(0, modelUrl.lastIndexOf('/'));
80
73
  const configResponse = await fetch(`${baseUrl}/model_config.json`);
@@ -88,8 +81,10 @@ class MLNoiseSuppressor {
88
81
  this.normStats = { mean: 0, std: 1 };
89
82
  }
90
83
  this.isInitialized = true;
84
+ console.log(`[MLNoiseSuppressor] Initialization complete`);
91
85
  }
92
86
  catch (error) {
87
+ console.error(`[MLNoiseSuppressor] Initialization failed:`, error);
93
88
  throw error;
94
89
  }
95
90
  }
@@ -62,11 +62,25 @@ class SpatialAudioChannel {
62
62
  * Setup spatial audio for a participant
63
63
  */
64
64
  async setupParticipant(participantId, track, bypassSpatialization = false) {
65
+ console.log(`🎧 [SpatialAudioChannel] Setting up participant ${participantId.substring(0, 8)}`, {
66
+ trackKind: track.kind,
67
+ trackEnabled: track.enabled,
68
+ trackMuted: track.muted,
69
+ trackReadyState: track.readyState,
70
+ bypassSpatialization,
71
+ audioContextState: this.audioContext.state,
72
+ });
65
73
  if (this.audioContext.state === 'suspended') {
74
+ console.log(`🎧 [SpatialAudioChannel] Resuming suspended AudioContext...`);
66
75
  await this.audioContext.resume();
76
+ console.log(`🎧 [SpatialAudioChannel] AudioContext resumed, state: ${this.audioContext.state}`);
67
77
  }
68
78
  const stream = new MediaStream([track]);
69
79
  const source = this.audioContext.createMediaStreamSource(stream);
80
+ console.log(`🎧 [SpatialAudioChannel] Created MediaStreamSource for ${participantId.substring(0, 8)}`, {
81
+ streamActive: stream.active,
82
+ streamTracks: stream.getTracks().length,
83
+ });
70
84
  // Create all audio nodes
71
85
  const panner = this.createPanner();
72
86
  const stereoPanner = this.audioContext.createStereoPanner();
@@ -124,6 +138,13 @@ class SpatialAudioChannel {
124
138
  dynamicLowpass,
125
139
  stream,
126
140
  });
141
+ console.log(`🎧 [SpatialAudioChannel] ✅ Audio pipeline setup complete for ${participantId.substring(0, 8)}`, {
142
+ bypassSpatialization,
143
+ masterGainValue: this.masterGainNode.gain.value,
144
+ participantGainValue: gain.gain.value,
145
+ audioContextState: this.audioContext.state,
146
+ connectedToDestination: true,
147
+ });
127
148
  }
128
149
  /**
129
150
  * Update spatial audio for a participant
@@ -66,12 +66,31 @@ class MediasoupManager {
66
66
  }
67
67
  async createSendTransport(participantId) {
68
68
  const params = await this.createWebRtcTransport('send', participantId);
69
- this.sendTransport = this.device.createSendTransport(params);
69
+ // Extract iceServers from params and pass them correctly
70
+ const { iceServers, ...transportParams } = params;
71
+ console.log(`🎧 [MediasoupManager] Creating send transport with ICE servers:`, {
72
+ hasIceServers: !!iceServers,
73
+ iceServerCount: iceServers?.length || 0,
74
+ });
75
+ this.sendTransport = this.device.createSendTransport({
76
+ ...transportParams,
77
+ iceServers: iceServers || [],
78
+ });
70
79
  this.connectSendTransport();
71
80
  }
72
81
  async createRecvTransport(participantId) {
73
82
  const params = await this.createWebRtcTransport('recv', participantId);
74
- this.recvTransport = this.device.createRecvTransport(params);
83
+ // Extract iceServers from params and pass them correctly
84
+ const { iceServers, ...transportParams } = params;
85
+ console.log(`🎧 [MediasoupManager] Creating recv transport with ICE servers:`, {
86
+ hasIceServers: !!iceServers,
87
+ iceServerCount: iceServers?.length || 0,
88
+ iceServers: iceServers,
89
+ });
90
+ this.recvTransport = this.device.createRecvTransport({
91
+ ...transportParams,
92
+ iceServers: iceServers || [],
93
+ });
75
94
  this.connectRecvTransport();
76
95
  }
77
96
  connectSendTransport() {
@@ -108,18 +127,33 @@ class MediasoupManager {
108
127
  }
109
128
  connectRecvTransport() {
110
129
  this.recvTransport?.on('connect', async ({ dtlsParameters }, callback, errback) => {
130
+ console.log(`🎧 [MediasoupManager] Recv transport connecting, DTLS params:`, {
131
+ transportId: this.recvTransport.id.substring(0, 8),
132
+ });
111
133
  this.socket.emit('connect-transport', { transportId: this.recvTransport.id, dtlsParameters }, (response) => {
112
- if (response.error)
134
+ if (response.error) {
135
+ console.error(`🎧 [MediasoupManager] ❌ Recv transport connect failed:`, response.error);
113
136
  errback(new Error(response.error));
114
- else
137
+ }
138
+ else {
139
+ console.log(`🎧 [MediasoupManager] ✅ Recv transport connected`);
115
140
  callback();
141
+ }
116
142
  });
117
143
  });
118
144
  this.recvTransport?.on('connectionstatechange', (state) => {
145
+ console.log(`🎧 [MediasoupManager] Recv transport connection state changed: ${state}`);
119
146
  if (state === 'failed' || state === 'closed') {
120
- // Consumers will be closed by server
147
+ console.error(`🎧 [MediasoupManager] Recv transport ${state}`);
148
+ }
149
+ if (state === 'connected') {
150
+ console.log(`🎧 [MediasoupManager] ✅ Recv transport fully connected!`);
121
151
  }
122
152
  });
153
+ // Also monitor ICE state separately
154
+ this.recvTransport?.on('icegatheringstatechange', (state) => {
155
+ console.log(`🎧 [MediasoupManager] Recv transport ICE gathering state: ${state}`);
156
+ });
123
157
  }
124
158
  async produce(track, appData) {
125
159
  if (!this.sendTransport)
@@ -149,12 +183,27 @@ class MediasoupManager {
149
183
  async consume(data) {
150
184
  if (!this.recvTransport)
151
185
  throw new Error('Receive transport not set up');
186
+ console.log(`🎧 [MediasoupManager] Creating consumer for ${data.participantId.substring(0, 8)}`, {
187
+ consumerId: data.consumerId.substring(0, 8),
188
+ producerId: data.producerId.substring(0, 8),
189
+ kind: data.kind,
190
+ recvTransportId: this.recvTransport.id.substring(0, 8),
191
+ recvTransportConnectionState: this.recvTransport.connectionState,
192
+ });
152
193
  const consumer = await this.recvTransport.consume({
153
194
  id: data.consumerId,
154
195
  producerId: data.producerId,
155
196
  kind: data.kind,
156
197
  rtpParameters: data.rtpParameters,
157
198
  });
199
+ console.log(`🎧 [MediasoupManager] Consumer created for ${data.participantId.substring(0, 8)}`, {
200
+ consumerId: consumer.id.substring(0, 8),
201
+ trackKind: consumer.track.kind,
202
+ trackEnabled: consumer.track.enabled,
203
+ trackMuted: consumer.track.muted,
204
+ trackReadyState: consumer.track.readyState,
205
+ consumerPaused: consumer.paused,
206
+ });
158
207
  consumer.on('transportclose', () => {
159
208
  this.consumers.delete(consumer.id);
160
209
  });
package/dist/index.js CHANGED
@@ -399,11 +399,19 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
399
399
  participant.consumers.set(consumer.id, consumer);
400
400
  if (track.kind === "audio") {
401
401
  participant.audioTrack = track;
402
+ console.log(`🎧 [SDK] Received audio consumer for ${participant.participantId.substring(0, 8)}`, {
403
+ consumerId: consumer.id.substring(0, 8),
404
+ trackEnabled: track.enabled,
405
+ trackMuted: track.muted,
406
+ trackReadyState: track.readyState,
407
+ consumerPaused: consumer.paused,
408
+ });
402
409
  // CRITICAL: Do NOT setup spatial audio for local participant (yourself)
403
410
  // This prevents hearing your own microphone (loopback)
404
411
  const isLocalParticipant = participant.participantId ===
405
412
  this.localParticipant?.participantId;
406
413
  if (isLocalParticipant) {
414
+ console.log(`🎧 [SDK] Skipping audio setup for local participant (prevent loopback)`);
407
415
  // Do NOT connect this audio to Web Audio API
408
416
  return; // Exit early to prevent any audio processing
409
417
  }
@@ -411,18 +419,20 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
411
419
  // Check if participant is in a huddle (non-spatial channel)
412
420
  const participantChannel = participant.currentChannel || "spatial";
413
421
  const isInHuddle = participantChannel !== "spatial";
422
+ console.log(`🎧 [SDK] Setting up spatial audio for ${participant.participantId.substring(0, 8)}, huddle: ${isInHuddle}`);
414
423
  // Setup spatial audio - bypass 3D positioning for huddle members
415
424
  await this.spatialAudioManager.setupSpatialAudioForParticipant(participant.participantId, track, isInHuddle // Bypass spatialization if in huddle
416
425
  );
417
426
  }
418
427
  // NOW resume the consumer after audio pipeline is ready
428
+ console.log(`🎧 [SDK] Resuming consumer ${consumer.id.substring(0, 8)}...`);
419
429
  this.mediasoupManager
420
430
  .resumeConsumer(consumer.id)
421
431
  .then(() => {
422
- // Consumer resumed successfully
432
+ console.log(`🎧 [SDK] ✅ Consumer ${consumer.id.substring(0, 8)} resumed successfully`);
423
433
  })
424
- .catch(() => {
425
- // Failed to resume consumer - will be handled by transport recovery
434
+ .catch((err) => {
435
+ console.error(`🎧 [SDK] ❌ Failed to resume consumer ${consumer.id.substring(0, 8)}:`, err);
426
436
  });
427
437
  }
428
438
  else if (track.kind === "video") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newgameplusinc/odyssey-audio-video-sdk-dev",
3
- "version": "1.0.259",
3
+ "version": "1.0.261",
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",