Overview
We offer ODIN, a high-quality cross-platform immersive voice SDK that includes state-of-the-art noise suppression technologies.
The Node.js SDK provides native bindings for the ODIN Voice SDK, enabling you to build powerful server-side voice applications including recording bots, AI voice assistants, audio processing pipelines, and content moderation tools.
Features
- 🎙️ Real-time Voice Chat - Low-latency voice communication
- 🔐 End-to-End Encryption - Built-in E2EE with OdinCipher
- 🤖 Bot Integration - Perfect for recording bots, AI assistants, and moderation tools
- 📊 Raw Audio Access - Get PCM audio data for processing, recording, or transcription
- 🌍 Proximity Chat - 3D positional audio support
- ⚡ High Performance - Native C++ bindings for maximum efficiency
- 📈 Diagnostics - Real-time connection and audio quality monitoring
Web SDK vs Node.js SDK
Our Web SDK includes fallback code for WebRTC and is compatible with most browsers. While it can also be used in Node.js, it may not be as performant as our native Node.js SDK, which is designed for advanced use cases and bots.
Although we strive to keep the API as similar as possible between our SDKs, there are some differences. The main difference is that the Node.js version allows you to access raw audio data from the ODIN server, which enables you to record or stream audio to the room.
The Node.js SDK is optimized for server-side use cases like:
- 🎙️ Audio recording bots
- 🤖 AI-powered voice assistants
- 📝 Speech-to-text transcription
- 🛡️ Content moderation
- 🔊 Audio processing pipelines
Important: You cannot combine the WebSDK and the Node.js SDK in the same project. You either have @4players/odin-nodejs or @4players/odin in your package.json file, but not both.
Source Code
The Node.js SDK is developed in C/C++ using Node API and is open source. Check out the source in our public GitHub repository.
Installation
Install the SDK via npm in your project:
Platform Support
This SDK includes prebuilt binaries for:
- macOS (x86_64 and ARM64)
- Windows (x86_64)
- Linux (x86_64)
If you deploy your application to a different platform, npm install will try to build the library from source. This requires a working C/C++ compiler and the necessary build tools. You can find more info in the node-gyp documentation.
Quick Start
1. Get Your Access Key
Sign up at 4Players ODIN to get your free access key.
2. Basic Connection Example
Event Handling
The SDK provides typed event handlers for easy integration:
Using Convenience Methods (Recommended)
Using addEventListener (Alternative)
You can also use the traditional addEventListener pattern:
Available events include: Joined, Left, PeerJoined, PeerLeft, MessageReceived, PeerUserDataChanged, RoomUserDataChanged, MediaStarted, MediaStopped, MediaActivity, AudioDataReceived, PeerTagsChanged, ConnectionStateChanged.
Working with Audio
Receiving Audio Data
Once the script has joined a room, you receive audio data through the AudioDataReceived event or the onAudioDataReceived handler:
Sending Audio - High-Level API (Recommended)
The high-level API handles all the complexity automatically - media ID allocation, StartMedia RPC, and timing:
Sending Audio - Low-Level API
For full control over audio transmission, use the low-level API:
ODIN requires 20ms chunks of audio data (i.e., 50 times a second). Calculate the chunk length based on the sample rate: chunkLength = sampleRate / 50.
End-to-End Encryption (E2EE)
Enable encryption for secure voice communication using OdinCipher:
All participants in a room must use the same cipher password to communicate. Ensure you distribute the password securely.
Verifying Peer Encryption Status
You can verify that a peer is using the same encryption as you:
Proximity Chat (3D Audio)
Enable distance-based audio for spatial applications like games or virtual worlds:
Peers are visible to each other only within a unit circle of radius 1.0. Use setPositionScale() to adapt ODIN to your coordinate system.
Connection Diagnostics
Monitor connection quality and troubleshoot issues:
Audio Recording Example
Record audio from peers to WAV files:
API Quick Reference
OdinClient
| Method | Description |
|---|---|
generateToken(accessKey, roomId, userId) | Generate a room token locally |
createRoom(token) | Create a room instance (recommended) |
createRoomWithToken(token) | Alias for createRoom |
OdinRoom
| Method | Description |
|---|---|
join(gateway, userData?) | Connect to the room |
close() | Disconnect from the room |
sendMessage(data, peerIds?) | Send a message to peers |
updatePosition(x, y, z) | Update 3D position |
setPositionScale(scale) | Set position scale factor |
setCipher(cipher) | Enable E2EE |
createAudioStream(sampleRate, channels) | Create audio output stream |
getConnectionId() | Get connection identifier |
getConnectionStats() | Get connection quality metrics |
getJitterStats(mediaId) | Get audio jitter metrics |
OdinRoom Properties
| Property | Type | Description |
|---|---|---|
ownPeerId | number | Your peer ID |
connected | boolean | Connection status |
availableMediaIds | number[] | Available media IDs for audio streams |
OdinMedia
| Method | Description |
|---|---|
sendMP3(filePath) | Stream an MP3 file (high-level) |
sendWAV(filePath) | Stream a WAV file (high-level) |
sendBuffer(audioBuffer) | Stream AudioBuffer (high-level) |
setMediaId(mediaId) | Set server-assigned media ID |
close() | Stop transmission (sends StopMedia RPC) and release resources |
sendAudioData(samples) | Send raw audio samples (low-level) |
OdinCipher
| Method | Description |
|---|---|
setPassword(password) | Set encryption password |
getPeerStatus(peerId) | Get peer's encryption status |
Events
| Event | Payload |
|---|---|
ConnectionStateChanged | { state, message } |
Joined | { roomId, ownPeerId, room, mediaIds } |
Left | { reason } |
PeerJoined | { peerId, userId, userData, peer } |
PeerLeft | { peerId } |
MediaStarted | { peerId, media } |
MediaStopped | { peerId, mediaId } |
MediaActivity | { peerId, mediaId, state } |
MessageReceived | { senderPeerId, message } |
AudioDataReceived | { peerId, mediaId, samples16, samples32 } |
Examples
We have prepared examples to get you started with the ODIN Node.js SDK:
- Streaming Audio Files - Learn how to stream audio files into rooms
- Transcribing Audio - Real-time audio transcription with OpenAI Whisper
You can also find additional examples in the tests/ folder of the SDK repository.
Troubleshooting
Build Errors
If you encounter build errors, ensure you have the required tools:
macOS Security Warnings
If you see "code signature not valid" errors:
Connection Issues
- Verify your access key is correct
- Check your network allows WebSocket connections
- Ensure the token hasn't expired
Lifecycle Best Practices
When building long-running applications (like NestJS servers, recording bots, or AI assistants), follow these patterns:
Singleton OdinClient Pattern
Create one OdinClient instance for the entire process lifetime:
Proper Audio Stream Cleanup
Always close audio streams when done:
Centralized Cleanup with onLeft
Use onLeft for unified cleanup (handles both normal and error cases):
The onLeft event is emitted for both server-initiated disconnects (e.g., timeout, kick) and client-initiated disconnects (room.close()). Use it for centralized cleanup logic.
Support
- 📖 Documentation: docs.4players.io
- 💬 Discord: Join our community
- 📧 Email: support@4players.io
- 🐛 Issues: GitHub Issues