@newgameplusinc/odyssey-audio-video-sdk-dev 1.0.47 → 1.0.49

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.
@@ -90,6 +90,20 @@ class MediasoupManager {
90
90
  callback({ id: response.producerId });
91
91
  });
92
92
  });
93
+ // Handle transport connection state changes
94
+ this.sendTransport?.on("connectionstatechange", (state) => {
95
+ console.log(`[MediaSoup] Send transport connection state: ${state}`);
96
+ if (state === "failed" || state === "closed") {
97
+ console.error("❌ [MediaSoup] Send transport failed/closed - will recreate");
98
+ // Clear all producers since transport is dead
99
+ this.producers.clear();
100
+ // Emit event so parent SDK can recreate producers
101
+ this.socket.emit("transport-failed", {
102
+ participantId: this.participantId,
103
+ direction: "send"
104
+ });
105
+ }
106
+ });
93
107
  }
94
108
  connectRecvTransport() {
95
109
  this.recvTransport?.on("connect", async ({ dtlsParameters }, callback, errback) => {
@@ -100,6 +114,14 @@ class MediasoupManager {
100
114
  callback();
101
115
  });
102
116
  });
117
+ // Handle transport connection state changes
118
+ this.recvTransport?.on("connectionstatechange", (state) => {
119
+ console.log(`[MediaSoup] Recv transport connection state: ${state}`);
120
+ if (state === "failed" || state === "closed") {
121
+ console.error("❌ [MediaSoup] Recv transport failed/closed - consumers will be recreated");
122
+ // Consumers will be closed by server, SDK will handle via consumer.on('transportclose')
123
+ }
124
+ });
103
125
  }
104
126
  async produce(track, appData) {
105
127
  if (!this.sendTransport)
@@ -121,6 +143,17 @@ class MediasoupManager {
121
143
  };
122
144
  }
123
145
  const producer = await this.sendTransport.produce(produceOptions);
146
+ // Handle producer events
147
+ producer.on('transportclose', () => {
148
+ console.warn(`⚠️ [MediaSoup] Producer ${producer.id.substring(0, 8)} transport closed`);
149
+ this.producers.delete(producer.id);
150
+ // The main SDK (index.ts) should handle recreation
151
+ });
152
+ producer.on('trackended', () => {
153
+ console.warn(`⚠️ [MediaSoup] Producer ${producer.id.substring(0, 8)} track ended`);
154
+ producer.close();
155
+ this.producers.delete(producer.id);
156
+ });
124
157
  this.producers.set(producer.id, producer);
125
158
  return producer;
126
159
  }
@@ -133,6 +166,17 @@ class MediasoupManager {
133
166
  kind: data.kind,
134
167
  rtpParameters: data.rtpParameters,
135
168
  });
169
+ // Handle consumer events
170
+ consumer.on('transportclose', () => {
171
+ console.warn(`⚠️ [MediaSoup] Consumer ${consumer.id.substring(0, 8)} transport closed`);
172
+ this.consumers.delete(consumer.id);
173
+ // The main SDK (index.ts) should handle recreation
174
+ });
175
+ consumer.on('trackended', () => {
176
+ console.warn(`⚠️ [MediaSoup] Consumer ${consumer.id.substring(0, 8)} track ended`);
177
+ consumer.close();
178
+ this.consumers.delete(consumer.id);
179
+ });
136
180
  this.consumers.set(consumer.id, consumer);
137
181
  return { consumer, track: consumer.track };
138
182
  }
package/dist/index.d.ts CHANGED
@@ -31,6 +31,10 @@ export declare class OdysseySpatialComms extends EventManager {
31
31
  produceTrack(track: MediaStreamTrack, appData?: {
32
32
  isScreenshare?: boolean;
33
33
  }): Promise<any>;
34
+ /**
35
+ * Recreate all local producers (used after transport failure/reconnection)
36
+ */
37
+ recreateProducers(): Promise<void>;
34
38
  updatePosition(position: Position, direction: Direction, spatialData?: {
35
39
  cameraDistance?: number;
36
40
  screenPos?: {
package/dist/index.js CHANGED
@@ -131,6 +131,40 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
131
131
  }
132
132
  return producer;
133
133
  }
134
+ /**
135
+ * Recreate all local producers (used after transport failure/reconnection)
136
+ */
137
+ async recreateProducers() {
138
+ if (!this.localParticipant)
139
+ return;
140
+ console.log("🔄 [MediaSoup] Recreating all producers after transport failure");
141
+ // Clear existing producers from local participant
142
+ this.localParticipant.producers.clear();
143
+ const tracksToReproduce = [];
144
+ // Collect audio track
145
+ if (this.localParticipant.audioTrack && this.localParticipant.audioTrack.readyState === 'live') {
146
+ tracksToReproduce.push({ track: this.localParticipant.audioTrack });
147
+ }
148
+ // Collect video track
149
+ if (this.localParticipant.videoTrack && this.localParticipant.videoTrack.readyState === 'live') {
150
+ tracksToReproduce.push({ track: this.localParticipant.videoTrack });
151
+ }
152
+ // Collect screenshare track
153
+ const screenshareTrack = this.localParticipant.screenshareTrack;
154
+ if (screenshareTrack && screenshareTrack.readyState === 'live') {
155
+ tracksToReproduce.push({ track: screenshareTrack, appData: { isScreenshare: true } });
156
+ }
157
+ // Recreate producers
158
+ for (const { track, appData } of tracksToReproduce) {
159
+ try {
160
+ await this.produceTrack(track, appData);
161
+ console.log(`✅ [MediaSoup] Recreated ${track.kind} producer`);
162
+ }
163
+ catch (error) {
164
+ console.error(`❌ [MediaSoup] Failed to recreate ${track.kind} producer:`, error);
165
+ }
166
+ }
167
+ }
134
168
  updatePosition(position, direction, spatialData) {
135
169
  if (this.localParticipant && this.room) {
136
170
  this.localParticipant.position = position;
@@ -381,6 +415,8 @@ class OdysseySpatialComms extends EventManager_1.EventManager {
381
415
  participant.userName = data.userName;
382
416
  if (data.userEmail !== undefined)
383
417
  participant.userEmail = data.userEmail;
418
+ if (data.currentChannel !== undefined)
419
+ participant.currentChannel = data.currentChannel;
384
420
  // Only update spatial audio if NOT in huddle
385
421
  const participantChannel = participant.currentChannel;
386
422
  const isInHuddle = participantChannel === "odyssey-huddle";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newgameplusinc/odyssey-audio-video-sdk-dev",
3
- "version": "1.0.47",
3
+ "version": "1.0.49",
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",