@4players/odin-nodejs 0.10.3 → 0.11.1

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/LICENSE +21 -0
  3. package/README.md +603 -44
  4. package/binding.gyp +29 -13
  5. package/cppsrc/binding.cpp +3 -6
  6. package/cppsrc/odinbindings.cpp +9 -45
  7. package/cppsrc/odincipher.cpp +92 -0
  8. package/cppsrc/odincipher.h +32 -0
  9. package/cppsrc/odinclient.cpp +19 -158
  10. package/cppsrc/odinclient.h +2 -5
  11. package/cppsrc/odinmedia.cpp +144 -186
  12. package/cppsrc/odinmedia.h +51 -18
  13. package/cppsrc/odinroom.cpp +675 -635
  14. package/cppsrc/odinroom.h +76 -26
  15. package/cppsrc/utilities.cpp +11 -81
  16. package/cppsrc/utilities.h +25 -140
  17. package/index.cjs +829 -0
  18. package/index.d.ts +3 -4
  19. package/libs/bin/linux/arm64/libodin.so +0 -0
  20. package/libs/bin/linux/arm64/libodin_crypto.so +0 -0
  21. package/libs/bin/linux/ia32/libodin.so +0 -0
  22. package/libs/bin/linux/ia32/libodin_crypto.so +0 -0
  23. package/libs/bin/linux/x64/libodin.so +0 -0
  24. package/libs/bin/linux/x64/libodin_crypto.so +0 -0
  25. package/{prebuilds/darwin-x64/node.napi.node → libs/bin/macos/universal/libodin.dylib} +0 -0
  26. package/libs/bin/macos/universal/libodin_crypto.dylib +0 -0
  27. package/libs/bin/windows/arm64/odin.dll +0 -0
  28. package/libs/bin/windows/arm64/odin.lib +0 -0
  29. package/libs/bin/windows/arm64/odin_crypto.dll +0 -0
  30. package/libs/bin/windows/arm64/odin_crypto.lib +0 -0
  31. package/libs/bin/windows/ia32/odin.dll +0 -0
  32. package/libs/bin/windows/ia32/odin.lib +0 -0
  33. package/libs/bin/windows/ia32/odin_crypto.dll +0 -0
  34. package/libs/bin/windows/ia32/odin_crypto.lib +0 -0
  35. package/libs/bin/windows/x64/odin.dll +0 -0
  36. package/libs/bin/windows/x64/odin.lib +0 -0
  37. package/libs/bin/windows/x64/odin_crypto.dll +0 -0
  38. package/libs/bin/windows/x64/odin_crypto.lib +0 -0
  39. package/libs/include/odin.h +665 -567
  40. package/libs/include/odin_crypto.h +46 -0
  41. package/odin.cipher.d.ts +31 -0
  42. package/odin.media.d.ts +69 -19
  43. package/odin.room.d.ts +348 -7
  44. package/package.json +5 -4
  45. package/prebuilds/{darwin-arm64/node.napi.node → darwin-x64+arm64/libodin.dylib} +0 -0
  46. package/prebuilds/darwin-x64+arm64/libodin_crypto.dylib +0 -0
  47. package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  48. package/prebuilds/linux-x64/libodin.so +0 -0
  49. package/prebuilds/linux-x64/libodin_crypto.so +0 -0
  50. package/prebuilds/linux-x64/node.napi.node +0 -0
  51. package/prebuilds/win32-x64/node.napi.node +0 -0
  52. package/prebuilds/win32-x64/odin.dll +0 -0
  53. package/prebuilds/win32-x64/odin_crypto.dll +0 -0
  54. package/scripts/postbuild.cjs +133 -0
  55. package/tests/audio-recording/README.md +97 -12
  56. package/tests/audio-recording/index.js +238 -130
  57. package/tests/connection-test/README.md +97 -0
  58. package/tests/connection-test/index.js +273 -0
  59. package/tests/lifecycle/test-room-cycle.js +169 -0
  60. package/tests/sending-audio/README.md +178 -9
  61. package/tests/sending-audio/canBounce.mp3 +0 -0
  62. package/tests/sending-audio/index.js +250 -87
  63. package/tests/sending-audio/test-kiss-api.js +149 -0
  64. package/tests/sending-audio/test-loop-audio.js +142 -0
  65. package/CMakeLists.txt +0 -25
  66. package/libs/bin/linux/arm64/libodin_static.a +0 -0
  67. package/libs/bin/linux/ia32/libodin_static.a +0 -0
  68. package/libs/bin/linux/x64/libodin_static.a +0 -0
  69. package/libs/bin/macos/arm64/libodin_static.a +0 -0
  70. package/libs/bin/macos/x64/libodin_static.a +0 -0
  71. package/libs/bin/windows/arm64/odin_static.lib +0 -0
  72. package/libs/bin/windows/ia32/odin_static.lib +0 -0
  73. package/libs/bin/windows/x64/odin_static.lib +0 -0
@@ -0,0 +1,46 @@
1
+ /* Copyright (c) 4Players GmbH. All rights reserved. */
2
+
3
+ #pragma once
4
+
5
+ /** @file */
6
+
7
+ #include <stdarg.h>
8
+ #include <stdbool.h>
9
+ #include <stddef.h>
10
+ #include <stdint.h>
11
+ #include <stdlib.h>
12
+ #include "odin.h"
13
+
14
+ #define ODIN_CRYPTO_VERSION "1.0.0"
15
+
16
+ #define OdinCipherImpl_ADDITIONAL_CAPACITY_DATAGRAM (TAG_SIZE + 12)
17
+
18
+ enum OdinCryptoPeerStatus
19
+ #ifdef __cplusplus
20
+ : int32_t
21
+ #endif // __cplusplus
22
+ {
23
+ ODIN_CRYPTO_PEER_STATUS_PASSWORD_MISSMATCH = -1,
24
+ ODIN_CRYPTO_PEER_STATUS_UNKNOWN = 0,
25
+ ODIN_CRYPTO_PEER_STATUS_UNENCRYPTED = 1,
26
+ ODIN_CRYPTO_PEER_STATUS_ENCRYPTED = 2,
27
+ };
28
+ #ifndef __cplusplus
29
+ typedef int32_t OdinCryptoPeerStatus;
30
+ #endif // __cplusplus
31
+
32
+ #ifdef __cplusplus
33
+ extern "C" {
34
+ #endif // __cplusplus
35
+
36
+ OdinCipher *odin_crypto_create(const char *version);
37
+
38
+ OdinCryptoPeerStatus odin_crypto_get_peer_status(OdinCipher *cipher, uint64_t peer_id);
39
+
40
+ int32_t odin_crypto_set_password(OdinCipher *cipher,
41
+ const uint8_t *password,
42
+ uint32_t password_length);
43
+
44
+ #ifdef __cplusplus
45
+ } // extern "C"
46
+ #endif // __cplusplus
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Possible encryption status values for a peer.
3
+ * - 'unknown': Peer status not yet determined (no communication yet)
4
+ * - 'unencrypted': Peer is not using encryption
5
+ * - 'encrypted': Peer is using encryption with a matching password
6
+ * - 'password_mismatch': Peer is encrypted but password doesn't match
7
+ */
8
+ export type OdinCryptoPeerStatus = 'unknown' | 'unencrypted' | 'encrypted' | 'password_mismatch';
9
+
10
+ export declare class OdinCipher {
11
+ /**
12
+ * Creates a new OdinCipher instance with default version.
13
+ */
14
+ constructor();
15
+
16
+ /**
17
+ * Sets the encryption password for end-to-end encryption.
18
+ * All audio and messages will be encrypted using this password.
19
+ * @param password - The password as a byte array.
20
+ */
21
+ setPassword(password: Uint8Array): void;
22
+
23
+ /**
24
+ * Gets the encryption status of a specific peer.
25
+ * Useful for verifying that E2EE is working correctly with each peer.
26
+ *
27
+ * @param peerId - The peer ID to check status for.
28
+ * @returns The encryption status of the peer.
29
+ */
30
+ getPeerStatus(peerId: number): OdinCryptoPeerStatus;
31
+ }
package/odin.media.d.ts CHANGED
@@ -1,12 +1,35 @@
1
- import {OdinAPMSettings, OdinRoom} from "./odin.room";
1
+ import { OdinAPMSettings, OdinRoom } from "./odin.room";
2
2
 
3
3
  /**
4
- * The OdinMedia class. Represents a local media stream added to the room - i.e. a microphone, another audio stream like files.
4
+ * Represents a decoded audio buffer (from audio-decode library).
5
+ */
6
+ export interface AudioBuffer {
7
+ sampleRate: number;
8
+ numberOfChannels: number;
9
+ duration: number;
10
+ length: number;
11
+ getChannelData(channel: number): Float32Array;
12
+ }
13
+
14
+ /**
15
+ * The OdinMedia class represents a local audio stream for sending audio to the room.
5
16
  * Don't create OdinMedia instances directly, use `createAudioStream` from OdinRoom instead.
17
+ *
18
+ * This wrapper closely follows the core ODIN SDK pattern:
19
+ * 1. Create audio stream: `media = room.createAudioStream(48000, 2)`
20
+ * 2. Set server-assigned media ID: `media.setMediaId(mediaIds[0])` // From Joined event
21
+ * 3. Send audio chunks: `media.sendAudioData(chunk)` // 20ms chunks recommended
22
+ * 4. When done: `media.close()`
23
+ *
24
+ * Or use the convenience API for file playback:
25
+ * await media.sendMP3('./file.mp3'); // Auto handles everything
26
+ * await media.sendWAV('./file.wav');
27
+ * await media.sendBuffer(audioBuffer);
6
28
  */
7
29
  export declare class OdinMedia {
8
30
  /**
9
- * Creates a new instance of a media object. Don't create OdinMedia directly, use `createAudioStream` from OdinRoom instead.
31
+ * Creates a new instance of a media object.
32
+ * Don't create OdinMedia directly, use `createAudioStream` from OdinRoom instead.
10
33
  * @param room - The room to add the media to.
11
34
  * @param sampleRate - The sample rate of the audio stream (between 8000 and 48000)
12
35
  * @param channelCount - The number of channels of the audio stream (1 or 2)
@@ -15,35 +38,62 @@ export declare class OdinMedia {
15
38
  constructor(room: OdinRoom, sampleRate: number, channelCount: number, options?: OdinAPMSettings);
16
39
 
17
40
  /**
18
- * Closes the local audio stream and removed the media from the room
41
+ * Sets the server-assigned media ID.
42
+ * Must be called before sendAudioData() with an ID from the Joined event's mediaIds array.
43
+ * @param mediaId - The media ID from Joined event
44
+ */
45
+ setMediaId(mediaId: number): void;
46
+
47
+ /**
48
+ * Closes the local audio stream and releases resources.
49
+ * After calling this, the media stream cannot be used.
19
50
  */
20
51
  close(): void;
21
52
 
22
53
  /**
23
- * Instructs the server to pause the media object, ceasing the reception of
24
- * data. This operation essentially communicates a server-side mute request from the client, thus
25
- * indicating a desire to halt packet reception for this media stream.
54
+ * Sends audio data to the room.
55
+ * Data must be a 32-bit float array with samples between -1 and 1.
56
+ * Audio data should be sent in regular intervals (20ms chunks recommended).
57
+ * @param data - A 32-bit float array containing the audio data.
58
+ */
59
+ sendAudioData(data: Float32Array): void;
60
+
61
+ /**
62
+ * Send an MP3 file with automatic decoding and real-time streaming.
63
+ * Handles all setup (media ID, StartMedia RPC, timing) automatically.
64
+ *
65
+ * @param filePath - Path to the MP3 file
66
+ * @returns Promise that resolves when audio streaming is complete
26
67
  */
27
- pause(): void;
68
+ sendMP3(filePath: string): Promise<void>;
28
69
 
29
70
  /**
30
- * Instructs the server to resume the media object, resuming the reception of
31
- * data. This operation essentially communicates a server-side unmute request from the client, thus
32
- * indicating a desire to resume packet reception for this media stream.
71
+ * Send a WAV file with automatic decoding and real-time streaming.
72
+ * Handles all setup (media ID, StartMedia RPC, timing) automatically.
73
+ *
74
+ * @param filePath - Path to the WAV file
75
+ * @returns Promise that resolves when audio streaming is complete
33
76
  */
34
- resume(): void;
77
+ sendWAV(filePath: string): Promise<void>;
35
78
 
36
79
  /**
37
- * Sends audio data to the room. The data must be in the format specified when creating the media as a 32-bit float array.
38
- * Samples need to be between -1 and 1. Audio data needs to be sent in regular intervals, otherwise the audio will be sound
39
- * interrupted. See the example for more details.
40
- * @param data - A 32-bit float array containing the audio data.
80
+ * Send decoded audio with real-time streaming.
81
+ * Handles all setup (media ID, StartMedia RPC, timing) automatically.
82
+ *
83
+ * @param audioBuffer - Decoded audio buffer (from audio-decode library)
84
+ * @returns Promise that resolves when audio streaming is complete
41
85
  */
42
- sendAudioData(data: Float32Array): void;
86
+ sendBuffer(audioBuffer: AudioBuffer): Promise<void>;
43
87
 
44
88
  /**
45
89
  * Gets the ID of the media.
46
- * @returns The ID of the media.
90
+ * @returns The ID of the media, or null if closed.
91
+ */
92
+ get id(): number | null;
93
+
94
+ /**
95
+ * Checks if this media stream has been closed.
96
+ * @returns True if the stream is closed and can no longer be used.
47
97
  */
48
- get id(): string;
98
+ get closed(): boolean;
49
99
  }
package/odin.room.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import {OdinMedia} from "./odin.media";
1
+ import { OdinMedia } from "./odin.media";
2
+ import { OdinCipher } from "./odin.cipher";
2
3
 
3
4
  /**
4
5
  * Defines available Odin events
@@ -64,6 +65,11 @@ declare interface OdinEvents {
64
65
  * You can use the samples to record audio or send them to an AI for transcription.
65
66
  */
66
67
  AudioDataReceived: OdinAudioDataReceivedEvent;
68
+
69
+ /**
70
+ * Fired when the tags of a remote peer changed.
71
+ */
72
+ PeerTagsChanged: OdinPeerTagsChangedEvent;
67
73
  }
68
74
 
69
75
  export type OdinConnectionStateChangedEvent = (event: OdinConnectionStateChangedEventPayload) => void;
@@ -78,6 +84,7 @@ export type OdinMediaAddedEvent = (event: OdinMediaAddedEventPayload) => void;
78
84
  export type OdinMediaRemovedEvent = (event: OdinMediaRemovedEventPayload) => void;
79
85
  export type OdinMediaActivityEvent = (event: OdinMediaActivityEventPayload) => void;
80
86
  export type OdinAudioDataReceivedEvent = (event: OdinAudioDataReceivedEventPayload) => void;
87
+ export type OdinPeerTagsChangedEvent = (event: OdinPeerTagsChangedEventPayload) => void;
81
88
 
82
89
  /**
83
90
  * The base event payload that is passed to all events.
@@ -94,8 +101,87 @@ declare interface OdinEventPayload {
94
101
  tag: number;
95
102
  }
96
103
 
104
+ /**
105
+ * Represents a media stream in the ODIN room.
106
+ * Media streams are used for audio transmission between peers.
107
+ */
108
+ export declare interface OdinMediaInfo {
109
+ /**
110
+ * The unique identifier of the media stream.
111
+ */
112
+ id: number;
113
+
114
+ /**
115
+ * Custom properties associated with this media stream.
116
+ */
117
+ properties: Record<string, unknown>;
118
+
119
+ /**
120
+ * Whether the media stream is currently paused.
121
+ */
122
+ paused: boolean;
123
+ }
124
+
125
+ /**
126
+ * Represents a peer in the ODIN room.
127
+ * A peer is a participant in the room that can send and receive audio.
128
+ */
129
+ export declare interface OdinPeerInfo {
130
+ /**
131
+ * The unique identifier of the peer within the room.
132
+ */
133
+ id: number;
134
+
135
+ /**
136
+ * The user ID associated with this peer (from the token).
137
+ */
138
+ user_id: string;
139
+
140
+ /**
141
+ * Custom user data associated with this peer.
142
+ */
143
+ user_data: Uint8Array | undefined;
144
+
145
+ /**
146
+ * List of media streams owned by this peer.
147
+ */
148
+ medias: OdinMediaInfo[];
149
+
150
+ /**
151
+ * Tags associated with this peer for filtering/grouping.
152
+ */
153
+ tags: string[];
154
+ }
155
+
156
+ /**
157
+ * Represents the room state returned when joining.
158
+ * Contains information about the room and all current participants.
159
+ */
160
+ export declare interface OdinRoomInfo {
161
+ /**
162
+ * The unique identifier of the room.
163
+ */
164
+ id: string;
165
+
166
+ /**
167
+ * The customer ID owning this room.
168
+ */
169
+ customer: string;
170
+
171
+ /**
172
+ * Custom user data associated with the room.
173
+ */
174
+ user_data: Uint8Array | undefined;
175
+
176
+ /**
177
+ * List of all peers currently in the room.
178
+ */
179
+ peers: OdinPeerInfo[];
180
+ }
181
+
97
182
  /**
98
183
  * The payload for the Joined event.
184
+ * This event is fired when the local user successfully joins a room.
99
185
  */
100
186
  export declare interface OdinJoinedEventPayload extends OdinEventPayload {
101
187
  /**
@@ -104,29 +190,39 @@ export declare interface OdinJoinedEventPayload extends OdinEventPayload {
104
190
  roomId: string;
105
191
 
106
192
  /**
107
- * The ID of the local peer.
193
+ * The ID of the local peer within the room.
108
194
  */
109
195
  ownPeerId: number;
110
196
 
111
197
  /**
112
- * The ID of the local user. It is the same as the user id that was passed to join.
198
+ * The full room state including all current peers and their media streams.
113
199
  */
114
- ownUserId: string;
200
+ room: OdinRoomInfo;
115
201
 
116
202
  /**
117
- * The current user data of the room
203
+ * List of media IDs owned by the local peer.
204
+ * These are media streams that were previously created and are still active.
118
205
  */
119
- roomUserData: Uint8Array | undefined;
206
+ mediaIds: number[];
120
207
  }
121
208
 
122
209
  /**
123
210
  * The payload for the Left event.
211
+ * This event is fired when the local user leaves a room, either due to a server-initiated
212
+ * disconnect or when `room.close()` is called programmatically.
124
213
  */
125
214
  export declare interface OdinLeftEventPayload extends OdinEventPayload {
126
215
  /**
127
- * The ID of the room that was left. It's the same as the room id that was passed to join.
216
+ * The ID of the room that was left.
128
217
  */
129
218
  roomId: string;
219
+
220
+ /**
221
+ * The reason for leaving the room.
222
+ * - 'ClientDisconnect': The client called `room.close()` programmatically
223
+ * - Other values: Server-initiated disconnects (e.g., 'kicked', 'timeout', etc.)
224
+ */
225
+ reason: string;
130
226
  }
131
227
 
132
228
  /**
@@ -301,6 +397,21 @@ export declare interface OdinAudioDataReceivedEventPayload {
301
397
  samples32: Uint8Array;
302
398
  }
303
399
 
400
+ /**
401
+ * The payload for the PeerTagsChanged event.
402
+ */
403
+ export declare interface OdinPeerTagsChangedEventPayload extends OdinEventPayload {
404
+ /**
405
+ * The ID of the peer whose tags changed.
406
+ */
407
+ peerId: number;
408
+
409
+ /**
410
+ * The new tags of the peer.
411
+ */
412
+ tags: string[];
413
+ }
414
+
304
415
  /**
305
416
  * Noise suppression levels
306
417
  */
@@ -474,8 +585,24 @@ export declare class OdinRoom {
474
585
  */
475
586
  setPositionScale(scale: number): void;
476
587
 
588
+ /**
589
+ * Sets the cipher for end-to-end encryption.
590
+ * @param cipher - The cipher instance.
591
+ */
592
+ setCipher(cipher: OdinCipher): void;
593
+
477
594
  /**
478
595
  * Closes the room and disconnects from the server.
596
+ *
597
+ * This method emits the 'Left' event before closing the native connection,
598
+ * ensuring that cleanup callbacks registered via `onLeft()` are triggered.
599
+ * The event payload will contain `{ reason: 'ClientDisconnect' }` to
600
+ * distinguish it from server-initiated disconnects.
601
+ *
602
+ * This provides a single, consistent cleanup path for session state management,
603
+ * as the `onLeft` handler will fire for both:
604
+ * - Client-initiated disconnects (calling `close()`)
605
+ * - Server-initiated disconnects (kicked, timeout, etc.)
479
606
  */
480
607
  close(): void;
481
608
 
@@ -497,4 +624,218 @@ export declare class OdinRoom {
497
624
  * @returns The OdinMedia object that allows you to send audio data.
498
625
  */
499
626
  createAudioStream(sampleRate: number, channels: number, apmSettings?: OdinAPMSettings): OdinMedia;
627
+
628
+ /**
629
+ * Gets whether the room is currently connected.
630
+ */
631
+ get connected(): boolean;
632
+
633
+ // =========================================
634
+ // Convenience event handler methods
635
+ // =========================================
636
+
637
+ /**
638
+ * Set handler for when room is successfully joined.
639
+ * @param handler - Handler receiving `{ roomId, ownPeerId, room }`
640
+ */
641
+ onJoined(handler: OdinJoinedEvent): void;
642
+
643
+ /**
644
+ * Set handler for when room is left.
645
+ * @param handler - Handler receiving `{ reason }`
646
+ */
647
+ onLeft(handler: OdinLeftEvent): void;
648
+
649
+ /**
650
+ * Set handler for peer joined events.
651
+ * @param handler - Handler receiving `{ peerId, peer, userId, userData }`
652
+ */
653
+ onPeerJoined(handler: OdinPeerJoinedEvent): void;
654
+
655
+ /**
656
+ * Set handler for peer left events.
657
+ * @param handler - Handler receiving `{ peerId }`
658
+ */
659
+ onPeerLeft(handler: OdinPeerLeftEvent): void;
660
+
661
+ /**
662
+ * Set handler for media started events (when a peer starts streaming audio).
663
+ * @param handler - Handler receiving `{ peerId, media }`
664
+ */
665
+ onMediaStarted(handler: OdinMediaAddedEvent): void;
666
+
667
+ /**
668
+ * Set handler for media stopped events.
669
+ * @param handler - Handler receiving `{ peerId, mediaId }`
670
+ */
671
+ onMediaStopped(handler: OdinMediaRemovedEvent): void;
672
+
673
+ /**
674
+ * Set handler for message received events.
675
+ * @param handler - Handler receiving `{ senderPeerId, message }`
676
+ */
677
+ onMessageReceived(handler: OdinMessageReceivedEvent): void;
678
+
679
+ /**
680
+ * Set handler for connection state changes.
681
+ * @param handler - Handler receiving `{ state, message }`
682
+ */
683
+ onConnectionStateChanged(handler: OdinConnectionStateChangedEvent): void;
684
+
685
+ /**
686
+ * Set handler for audio data events (for recording/processing).
687
+ * @param handler - Handler receiving `{ peerId, mediaId, samples16, samples32 }`
688
+ */
689
+ onAudioDataReceived(handler: OdinAudioDataReceivedEvent): void;
690
+
691
+ /**
692
+ * Set handler for peer user data changed events.
693
+ * @param handler - Handler receiving `{ peerId, userData }`
694
+ */
695
+ onPeerUserDataChanged(handler: OdinPeerUserDataChangedEvent): void;
696
+
697
+ /**
698
+ * Set handler for room user data changed events.
699
+ * @param handler - Handler receiving `{ userData }`
700
+ */
701
+ onRoomUserDataChanged(handler: OdinRoomUserDataChangedEvent): void;
702
+
703
+ /**
704
+ * Set handler for media activity events (voice activity detection).
705
+ * @param handler - Handler receiving `{ peerId, mediaId, state }`
706
+ */
707
+ onMediaActivity(handler: OdinMediaActivityEvent): void;
708
+
709
+ /**
710
+ * Set handler for peer tags changed events.
711
+ * @param handler - Handler receiving `{ peerId, tags }`
712
+ */
713
+ onPeerTagsChanged(handler: OdinPeerTagsChangedEvent): void;
714
+
715
+ // =========================================
716
+ // Diagnostics and Statistics
717
+ // =========================================
718
+
719
+ /**
720
+ * Retrieves detailed connection statistics for the room.
721
+ * Useful for monitoring network quality and debugging connectivity issues.
722
+ * @returns Connection statistics object, or null if not connected.
723
+ */
724
+ getConnectionStats(): OdinConnectionStats | null;
725
+
726
+ /**
727
+ * Retrieves the underlying connection identifier for the room.
728
+ * @returns The connection ID, or 0 if not connected.
729
+ */
730
+ getConnectionId(): number;
731
+
732
+ /**
733
+ * Retrieves jitter buffer statistics for a specific media stream.
734
+ * Useful for debugging audio quality issues.
735
+ * @param mediaId - The media ID to get jitter stats for.
736
+ * @returns Jitter statistics object, or null if decoder not found.
737
+ */
738
+ getJitterStats(mediaId: number): OdinJitterStats | null;
739
+ }
740
+
741
+ /**
742
+ * Connection statistics returned by getConnectionStats().
743
+ * Provides detailed metrics about the underlying UDP connection.
744
+ */
745
+ export declare interface OdinConnectionStats {
746
+ /**
747
+ * The number of outgoing UDP datagrams sent.
748
+ */
749
+ udpTxDatagrams: number;
750
+
751
+ /**
752
+ * The total number of bytes sent in outgoing UDP datagrams.
753
+ */
754
+ udpTxBytes: number;
755
+
756
+ /**
757
+ * The packet loss percentage for outgoing UDP datagrams (0.0 to 1.0).
758
+ */
759
+ udpTxLoss: number;
760
+
761
+ /**
762
+ * The number of incoming UDP datagrams received.
763
+ */
764
+ udpRxDatagrams: number;
765
+
766
+ /**
767
+ * The total number of bytes received in incoming UDP datagrams.
768
+ */
769
+ udpRxBytes: number;
770
+
771
+ /**
772
+ * The packet loss percentage for incoming UDP datagrams (0.0 to 1.0).
773
+ */
774
+ udpRxLoss: number;
775
+
776
+ /**
777
+ * The current congestion window size in bytes.
778
+ */
779
+ cwnd: number;
780
+
781
+ /**
782
+ * The number of congestion events that have occurred.
783
+ */
784
+ congestionEvents: number;
785
+
786
+ /**
787
+ * The current round-trip time (RTT) in milliseconds.
788
+ */
789
+ rtt: number;
790
+ }
791
+
792
+ /**
793
+ * Jitter buffer statistics returned by getJitterStats().
794
+ * Provides detailed metrics about audio packet reception and processing.
795
+ */
796
+ export declare interface OdinJitterStats {
797
+ /**
798
+ * The total number of packets seen by the jitter buffer.
799
+ */
800
+ packetsTotal: number;
801
+
802
+ /**
803
+ * The number of packets currently buffered.
804
+ */
805
+ packetsBuffered: number;
806
+
807
+ /**
808
+ * The number of packets successfully processed.
809
+ */
810
+ packetsProcessed: number;
811
+
812
+ /**
813
+ * The number of packets dropped because they arrived too early.
814
+ */
815
+ packetsArrivedTooEarly: number;
816
+
817
+ /**
818
+ * The number of packets dropped because they arrived too late.
819
+ */
820
+ packetsArrivedTooLate: number;
821
+
822
+ /**
823
+ * The number of packets dropped due to jitter buffer reset.
824
+ */
825
+ packetsDropped: number;
826
+
827
+ /**
828
+ * The number of packets marked as invalid.
829
+ */
830
+ packetsInvalid: number;
831
+
832
+ /**
833
+ * The number of duplicate packets received.
834
+ */
835
+ packetsRepeated: number;
836
+
837
+ /**
838
+ * The number of packets lost during transmission.
839
+ */
840
+ packetsLost: number;
500
841
  }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@4players/odin-nodejs",
3
- "version": "0.10.3",
3
+ "version": "0.11.1",
4
4
  "description": "NodeJS bindings for the ODIN SDK. Use for AI enhanced human interactions, content moderation and audio processing features in a backend.",
5
5
  "main": "index.cjs",
6
6
  "types": "index.d.ts",
7
7
  "scripts": {
8
- "build:debug": "node-gyp rebuild --debug",
9
- "build:release": "node-gyp rebuild",
8
+ "build:debug": "node-gyp rebuild --debug && node scripts/postbuild.cjs debug",
9
+ "build:release": "node-gyp rebuild && node scripts/postbuild.cjs",
10
10
  "build": "npm run build:release",
11
11
  "clean": "node-gyp clean",
12
12
  "install": "node-gyp-build"
@@ -20,6 +20,7 @@
20
20
  "dependencies": {
21
21
  "@4players/odin-foundation": "^0.2.0",
22
22
  "@4players/odin-tokens": "^1.3.0",
23
+ "@msgpack/msgpack": "^3.1.2",
23
24
  "audio-buffer-stream": "^1.1.0",
24
25
  "audio-decode": "^2.1.1",
25
26
  "audio-lena": "^2.3.0",
@@ -47,4 +48,4 @@
47
48
  "x64",
48
49
  "arm64"
49
50
  ]
50
- }
51
+ }
Binary file
Binary file
Binary file
Binary file