@4players/odin
Version:
A cross-platform SDK enabling developers to integrate real-time VoIP chat technology into their projects
234 lines (233 loc) • 7.3 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OdinPeer = void 0;
const audio_1 = require("./audio");
const media_1 = require("./media");
/**
* Class describing a single peer inside an `OdinRoom`.
*/
class OdinPeer {
/**
* Creates a new `OdinPeer` instance.
*
* @param _id The ID of the new peer
* @param _userId The user ID of the new peer
* @param _remote Indicates, whether the peer is a remote peer or not
* @ignore
*/
constructor(_roomStream, _id, _userId, _remote) {
this._roomStream = _roomStream;
this._id = _id;
this._userId = _userId;
this._remote = _remote;
/**
* An instance of `EventTarget` for handling events related to this peer.
*/
this._eventTarget = new EventTarget();
/**
* Free media IDs available to this peer.
*/
this._freeMediaIds = [];
/**
* Map of currently active media instances associated with this peer.
*/
this._activeMedias = new Map();
/**
* User data associated with the peer.
*/
this._data = new Uint8Array();
this._audioService = audio_1.OdinAudioService.getInstance();
}
/**
* The ID of the peer.
*/
get id() {
return this._id;
}
/**
* The identifier of the peer.
*/
get userId() {
return this._userId;
}
/**
* Indicates, whether the peer is a remote peer or not.
*/
get remote() {
return this._remote;
}
/**
* A list of media instances owned by the peer.
*/
get medias() {
return this._activeMedias;
}
/**
* Set updated user data for the peer.
*/
set data(data) {
this._data = data;
}
/**
* The arbitrary user data of the peer.
*/
get data() {
return this._data;
}
/**
* An event target handler for the peer.
*
* @ignore
*/
get eventTarget() {
return this._eventTarget;
}
/**
* Set the list of media IDs assigned by the server.
*
* @ignore
*/
setFreeMediaIds(ids) {
if (this._freeMediaIds.length > 0)
return;
this._freeMediaIds = ids;
}
/**
* Creates a local media, configures audio capture/playback and returns the new `OdinMedia` instance.
*/
createMedia() {
if (this._activeMedias.size > 0) {
throw new Error('Unable to create new media; adding more than one media per local peer is currently not supported');
}
const freeMediaId = this.takeFreeMedia();
if (!freeMediaId)
throw new Error('Unable to create new media; no more media IDs available');
const newMedia = new media_1.OdinMedia(freeMediaId, this._id, false);
this._activeMedias.set(newMedia.id, newMedia);
return newMedia;
}
/**
* Adds a media to the list of active medias and starts decoding.
*
* @param media The media instance to add
*/
addMedia(media) {
this._activeMedias.set(media.id, media);
}
/**
* Removes a media from the list of active medias and stops decoding.
*
* @param media The media instance to remove
*/
removeMedia(media) {
var _a;
media.stop();
(_a = this._audioService) === null || _a === void 0 ? void 0 : _a.unregisterMedia(media);
this._activeMedias.delete(media.id);
}
/**
* Removes a media from the list of active medias by the given ID and stops decoding.
*
* @param id The media ID to remove
*/
removeMediaById(id) {
const media = this._activeMedias.get(id);
if (media) {
this.removeMedia(media);
}
}
/**
* Pops the next media from the free medias array.
*/
takeFreeMedia() {
return this._freeMediaIds.pop();
}
/**
* Starts all active medias or a list of specific active medias.
*
* @param mediaIds Optional list of media IDs to start
*/
startMedias(mediaIds) {
return __awaiter(this, void 0, void 0, function* () {
if (mediaIds && mediaIds.length > 0) {
for (const media of this._activeMedias) {
if (media[0] in mediaIds) {
yield media[1].start();
}
}
}
else {
for (const media of this._activeMedias) {
yield media[1].start();
}
}
});
}
/**
* Stops all active medias or a list of specific active medias.
*
* @param mediaIds Optional list of media IDs to stop
*/
stopMedias(mediaIds) {
return __awaiter(this, void 0, void 0, function* () {
if (mediaIds && mediaIds.length > 0) {
for (const media of this._activeMedias) {
if (media[0] in mediaIds) {
yield media[1].stop();
}
}
}
else {
for (const media of this._activeMedias) {
yield media[1].stop();
}
}
});
}
/**
* Sends a message with arbitrary data to this peer.
*
* @param message Byte array of arbitrary data to send
*/
sendMessage(message) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
if (!message)
return;
yield ((_a = this._roomStream) === null || _a === void 0 ? void 0 : _a.request('SendMessage', { message, target_peer_ids: [this._id] }));
});
}
/**
* Sends user data of the peer to the server.
*/
update() {
var _a;
return __awaiter(this, void 0, void 0, function* () {
if (this._remote) {
throw new Error('Failed to flush peer user data update; not allowed to update remote peer');
}
yield ((_a = this._roomStream) === null || _a === void 0 ? void 0 : _a.request('UpdatePeer', {
user_data: this._data,
}));
});
}
/**
* Registers to peer events from `IOdinPeerEvents`.
*
* @param eventName The name of the event to listen to
* @param handler The callback to handle the event
*/
addEventListener(eventName, handler) {
this._eventTarget.addEventListener(eventName, handler);
}
}
exports.OdinPeer = OdinPeer;