@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.
- package/CHANGELOG.md +72 -0
- package/LICENSE +21 -0
- package/README.md +603 -44
- package/binding.gyp +29 -13
- package/cppsrc/binding.cpp +3 -6
- package/cppsrc/odinbindings.cpp +9 -45
- package/cppsrc/odincipher.cpp +92 -0
- package/cppsrc/odincipher.h +32 -0
- package/cppsrc/odinclient.cpp +19 -158
- package/cppsrc/odinclient.h +2 -5
- package/cppsrc/odinmedia.cpp +144 -186
- package/cppsrc/odinmedia.h +51 -18
- package/cppsrc/odinroom.cpp +675 -635
- package/cppsrc/odinroom.h +76 -26
- package/cppsrc/utilities.cpp +11 -81
- package/cppsrc/utilities.h +25 -140
- package/index.cjs +829 -0
- package/index.d.ts +3 -4
- package/libs/bin/linux/arm64/libodin.so +0 -0
- package/libs/bin/linux/arm64/libodin_crypto.so +0 -0
- package/libs/bin/linux/ia32/libodin.so +0 -0
- package/libs/bin/linux/ia32/libodin_crypto.so +0 -0
- package/libs/bin/linux/x64/libodin.so +0 -0
- package/libs/bin/linux/x64/libodin_crypto.so +0 -0
- package/{prebuilds/darwin-x64/node.napi.node → libs/bin/macos/universal/libodin.dylib} +0 -0
- package/libs/bin/macos/universal/libodin_crypto.dylib +0 -0
- package/libs/bin/windows/arm64/odin.dll +0 -0
- package/libs/bin/windows/arm64/odin.lib +0 -0
- package/libs/bin/windows/arm64/odin_crypto.dll +0 -0
- package/libs/bin/windows/arm64/odin_crypto.lib +0 -0
- package/libs/bin/windows/ia32/odin.dll +0 -0
- package/libs/bin/windows/ia32/odin.lib +0 -0
- package/libs/bin/windows/ia32/odin_crypto.dll +0 -0
- package/libs/bin/windows/ia32/odin_crypto.lib +0 -0
- package/libs/bin/windows/x64/odin.dll +0 -0
- package/libs/bin/windows/x64/odin.lib +0 -0
- package/libs/bin/windows/x64/odin_crypto.dll +0 -0
- package/libs/bin/windows/x64/odin_crypto.lib +0 -0
- package/libs/include/odin.h +665 -567
- package/libs/include/odin_crypto.h +46 -0
- package/odin.cipher.d.ts +31 -0
- package/odin.media.d.ts +69 -19
- package/odin.room.d.ts +348 -7
- package/package.json +5 -4
- package/prebuilds/{darwin-arm64/node.napi.node → darwin-x64+arm64/libodin.dylib} +0 -0
- package/prebuilds/darwin-x64+arm64/libodin_crypto.dylib +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-x64/libodin.so +0 -0
- package/prebuilds/linux-x64/libodin_crypto.so +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/prebuilds/win32-x64/odin.dll +0 -0
- package/prebuilds/win32-x64/odin_crypto.dll +0 -0
- package/scripts/postbuild.cjs +133 -0
- package/tests/audio-recording/README.md +97 -12
- package/tests/audio-recording/index.js +238 -130
- package/tests/connection-test/README.md +97 -0
- package/tests/connection-test/index.js +273 -0
- package/tests/lifecycle/test-room-cycle.js +169 -0
- package/tests/sending-audio/README.md +178 -9
- package/tests/sending-audio/canBounce.mp3 +0 -0
- package/tests/sending-audio/index.js +250 -87
- package/tests/sending-audio/test-kiss-api.js +149 -0
- package/tests/sending-audio/test-loop-audio.js +142 -0
- package/CMakeLists.txt +0 -25
- package/libs/bin/linux/arm64/libodin_static.a +0 -0
- package/libs/bin/linux/ia32/libodin_static.a +0 -0
- package/libs/bin/linux/x64/libodin_static.a +0 -0
- package/libs/bin/macos/arm64/libodin_static.a +0 -0
- package/libs/bin/macos/x64/libodin_static.a +0 -0
- package/libs/bin/windows/arm64/odin_static.lib +0 -0
- package/libs/bin/windows/ia32/odin_static.lib +0 -0
- 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
|
package/odin.cipher.d.ts
ADDED
|
@@ -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
|
-
*
|
|
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.
|
|
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
|
-
*
|
|
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
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
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
|
-
|
|
68
|
+
sendMP3(filePath: string): Promise<void>;
|
|
28
69
|
|
|
29
70
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
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
|
-
|
|
77
|
+
sendWAV(filePath: string): Promise<void>;
|
|
35
78
|
|
|
36
79
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* @param
|
|
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
|
-
|
|
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
|
|
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
|
|
198
|
+
* The full room state including all current peers and their media streams.
|
|
113
199
|
*/
|
|
114
|
-
|
|
200
|
+
room: OdinRoomInfo;
|
|
115
201
|
|
|
116
202
|
/**
|
|
117
|
-
*
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|