Skip to main content

ODIN Voice Web SDK

ODIN is our cross-platform immersive voice SDK with best-in-class quality and noise suppression technologies. You can integrate it with ease in your TypeScript/JavaScript-based applications.

Source Code

The web SDK is developed in TypeScript and is open source. Check out the source in our public Github repository.

Installation

You can install the ODIN web SDK in your NodeJS project (you may want to build a bot in your NodeJS-based server that responds to messages sent by users). You may also add ODIN to your Angular, React, React Native, Svelte, or any other frontend framework based on NPM.

NPM

npm npm npm

Install the web SDK via npm in your project like this:

npm install --save @4players/odin

HTML

If you want to include ODIN in your website, you can add ODIN with this script tag to your website:


<script type="text/javascript" src="https://4npcdn.com/2355/odin/javascript/latest/odin.min.js"></script>

We also provide versioned URLs like this:


<script type="text/javascript" src="https://4npcdn.com/2355/odin/javascript/0.9.0/odin.min.js"></script>

If you want to host it yourself or make adjustments, you can also build it from source:

  1. Clone this repo on your workstation: https://github.com/4Players/odin-sdk-web
  2. Install modules: npm install
  3. Build vanilla JavaScript script: npm run bundle
  4. Congratulations! You now have a bundled script file named odin.min.js in the dist folder.

You can now use the code as shown in the sample below, with one exception:

In the NPM package, namespaces and modules exist to separate different APIs from each other so they don't share the same space and accidentally overwrite things from other APIs. As some browsers don't support modules, we group ODIN APIs in a global namespace named ODIN. The namespace is defined in the Rollup bundle settings (please refer to rollup.config.ts for details).

Therefore, whenever you see something in the docs that says OdinClient.initRoom you'll need to change that to ODIN.OdinClient.initRoom in vanilla JavaScript.

Interoperability

The ODIN web SDK is fully compatible with our other client SDKs, so you can easily communicate between your favorite web browser and any native app or game which integrates ODIN.

While next-gen browsers and native ODIN SDKs utilize WebTransport over HTTP/3 to talk to an ODIN server using a secure and reliable multiplexed transport, we've also implemented a fallback mechanism over WebRTC data channels for browsers without HTTP/3 support.

Event Handling

The ODIN server will automatically notify you about relevant updates, and the ODIN web SDK uses the JavaScript EventTarget API to dispatch custom events based on the

OdinEventTarget

. Use any of the provided addEventListener methods to set up a function that will be called whenever the specified event is delivered to the target.

Events are available in the following scopes:

This allows fine-grained control over which events you want to receive on any specific class instance, most notably OdinRoom. Please refer to the scopes listed above to find out which events are available.

anyOdinObjectInstance.addEventListener('<EVENT_NAME>', function (event) { /* do something */
});

Using Media objects

ODIN works with the concept of media objects that are attached to a room. A media is either remote (i.e., connected to the mic of someone else’s device) or a local media, which is linked to your own microphone or other input device.

After joining a room, you can create a media (linked to your local input device) and add it to the room. After joining a room, you are just a listener in the room, and you don't send anything to it (i.e., you are muted). If you want to unmute the local user, you need to attach a media to that room:

Creating a media object
// Create a new audio stream for our default capture device and append it to the room
const mediaStream = await navigator.mediaDevices.getUserMedia({
echoCancellation: true,
autoGainControl: true,
noiseSuppression: true,
});

// Create and append a new input media to the room
const inputMedia = await odinRoom.createMedia(mediaStream);

// Start transmitting voice data (this can also be done later in the event listener for 'MediaStarted')
inputMedia.start();

That's it. The navigator object's mediaDevices has many functions to identify the input devices available on the user's device, i.e., you could show users a list of devices with all mics attached to the user's device before attaching that media.

warning

Important: In our Web SDK, media objects are not started immediately. The objects are created, but they don't send any data yet. You need to call the start method on the media object to start sending (and receiving data).

If you also want to enable receiving voice from others, you'll need to start incoming media objects too. For this, add an event handler for the MediaStarted event like this:

Starting incoming media objects
// Listen to media started events in the room and start decoding its voice packets
odinRoom.addEventListener('MediaStarted', (event) => {
console.log(`Peer ${event.payload.peer.id} added a new media stream to the room`);
// Start the media stream to enable the speaker for this media stream.
event.payload.media.start();
});

Disconnect from Odin

To disconnect a player from an Odin room, you can simply call:

room.disconnect(); // room: OdinRoom

This function will stop all media objects from sending and receiving data. However, the browser may continue showing a microphone indicator on the tab, which can mistakenly suggest that the microphone is still being used. To remove this indicator and let the browser know that the microphone is no longer active, implement the clean-up code as shown in the example below:

Clean-up media tracks and hide microphone indicator
function stopMediaStream(ms: MediaStream) {
ms.getTracks().forEach((track) => {
track.stop();
ms.removeTrack(track);
});
}

Execute this clean-up function on the media stream that is capturing audio to ensure that all resources are properly released and the microphone indicator is removed.

Examples

We have prepared a couple of examples for various web frameworks.

Vanilla JS

This example shows how to join a room and how to add a media stream (i.e., microphone) to it. It also shows how to subscribe to important events and how to manage them. This can be useful for updating lists of users in the channel or showing activity indicators.

info

To join an ODIN room, you need to create an access token. This should not be done on the client side as the access key is very powerful and should not be exposed in a public client. We provide an easy-to-use and deploy token server via NodeJS that you can use to create ODIN tokens. You can also use our NPM package @4players/odin-tokens to add a route to your existing NodeJS-based server or cloud functions. Check out the token server here: Token Server NodeJS Example.

The code should be self-explanatory; however, the basic steps are:

  1. Receive an access token for the room default from our example token server.
  2. Join the room with that access token.
  3. Set up listeners to receive notifications if new users join the room or start and stop talking.
Vanilla JS Example
https://github.com/4Players/odin-sdk-web/blob/main/examples/odin-typescript-example/src/main.ts

Angular

We have created a simple Angular application that you can use as a starting point for your own Angular application or an integration into existing applications.

We provide the source code in our Github repository: Angular Demo for ODIN.