@4players/odin-plugin-web 1.0.0-alpha.20 → 1.0.0-alpha.21

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 (68) hide show
  1. package/lib/plugin/index.d.ts +17 -66
  2. package/lib/plugin/index.js +1 -404
  3. package/lib/worker/shared.js +1 -0
  4. package/lib/worker/unshared.js +1 -0
  5. package/package.json +12 -9
  6. package/lib/common/msgpack.d.ts +0 -2
  7. package/lib/common/msgpack.js +0 -117
  8. package/lib/plugin/config.d.ts +0 -12
  9. package/lib/plugin/config.js +0 -22
  10. package/lib/plugin/connectionPool.d.ts +0 -17
  11. package/lib/plugin/connectionPool.js +0 -130
  12. package/lib/plugin/deviceManager.d.ts +0 -12
  13. package/lib/plugin/deviceManager.js +0 -120
  14. package/lib/plugin/h3/mainConnection.d.ts +0 -31
  15. package/lib/plugin/h3/mainConnection.js +0 -195
  16. package/lib/plugin/mainConnection.d.ts +0 -30
  17. package/lib/plugin/mainConnection.js +0 -21
  18. package/lib/plugin/mediaController.d.ts +0 -66
  19. package/lib/plugin/mediaController.js +0 -215
  20. package/lib/plugin/medias/audio-capture.d.ts +0 -30
  21. package/lib/plugin/medias/audio-capture.js +0 -224
  22. package/lib/plugin/medias/audio-playback.d.ts +0 -13
  23. package/lib/plugin/medias/audio-playback.js +0 -40
  24. package/lib/plugin/medias/video-capture.d.ts +0 -15
  25. package/lib/plugin/medias/video-capture.js +0 -69
  26. package/lib/plugin/medias/video-playback.d.ts +0 -13
  27. package/lib/plugin/medias/video-playback.js +0 -20
  28. package/lib/plugin/roomConnection.d.ts +0 -40
  29. package/lib/plugin/roomConnection.js +0 -320
  30. package/lib/plugin/rpcConnection.d.ts +0 -57
  31. package/lib/plugin/rpcConnection.js +0 -281
  32. package/lib/plugin/token.d.ts +0 -13
  33. package/lib/plugin/token.js +0 -66
  34. package/lib/plugin/webrtc/mainConnection.d.ts +0 -53
  35. package/lib/plugin/webrtc/mainConnection.js +0 -455
  36. package/lib/plugin/webrtc/websocket.d.ts +0 -3
  37. package/lib/plugin/webrtc/websocket.js +0 -56
  38. package/lib/wasm/index.d.ts +0 -97
  39. package/lib/worker/buffers.d.ts +0 -42
  40. package/lib/worker/buffers.js +0 -79
  41. package/lib/worker/common.d.ts +0 -45
  42. package/lib/worker/common.js +0 -7
  43. package/lib/worker/config.d.ts +0 -8
  44. package/lib/worker/config.js +0 -11
  45. package/lib/worker/index.d.ts +0 -3
  46. package/lib/worker/index.js +0 -1
  47. package/lib/worker/memory.d.ts +0 -9
  48. package/lib/worker/memory.js +0 -29
  49. package/lib/worker/messages.d.ts +0 -14
  50. package/lib/worker/messages.js +0 -15
  51. package/lib/worker/packet.d.ts +0 -11
  52. package/lib/worker/packet.js +0 -59
  53. package/lib/worker/shared/capture.d.ts +0 -27
  54. package/lib/worker/shared/capture.js +0 -63
  55. package/lib/worker/shared/index.d.ts +0 -3
  56. package/lib/worker/shared/index.js +0 -147
  57. package/lib/worker/shared/messages.d.ts +0 -67
  58. package/lib/worker/shared/messages.js +0 -64
  59. package/lib/worker/shared/playback.d.ts +0 -20
  60. package/lib/worker/shared/playback.js +0 -78
  61. package/lib/worker/unshared/capture.d.ts +0 -27
  62. package/lib/worker/unshared/capture.js +0 -66
  63. package/lib/worker/unshared/index.d.ts +0 -3
  64. package/lib/worker/unshared/index.js +0 -170
  65. package/lib/worker/unshared/messages.d.ts +0 -81
  66. package/lib/worker/unshared/messages.js +0 -80
  67. package/lib/worker/unshared/playback.d.ts +0 -22
  68. package/lib/worker/unshared/playback.js +0 -83
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4players/odin-plugin-web",
3
- "version": "1.0.0-alpha.20",
3
+ "version": "1.0.0-alpha.21",
4
4
  "description": "A backend plugin providing the custom WebAssembly audio processing module for ODIN web clients",
5
5
  "homepage": "https://www.4players.io",
6
6
  "repository": {
@@ -12,33 +12,36 @@
12
12
  "types": "./lib/plugin/index.d.ts",
13
13
  "scripts": {
14
14
  "clean": "rimraf build lib",
15
- "configure": "npm-run-all -pl configure:*",
15
+ "configure": "npm-run-all configure:*",
16
16
  "configure:shared": "emcmake cmake -B build/shared -DCMAKE_BUILD_TYPE=Release -DSHARED_MEMORY=1 -S .",
17
17
  "configure:unshared": "emcmake cmake -B build/unshared -DCMAKE_BUILD_TYPE=Release -S .",
18
- "build": "npm-run-all -s configure build:wasm build:plugin build:worker",
19
- "build:wasm": "npm-run-all -pl build:wasm:* && node install-wasm.js",
20
- "build:wasm:shared": "emmake cmake --build build/shared",
21
- "build:wasm:unshared": "emmake cmake --build build/unshared",
22
- "build:worker": "ts-node src/build.ts && tsc -b ./tsconfig.worker.json",
23
- "build:plugin": "tsc --build --verbose --force",
18
+ "build": "npm-run-all -s configure build:genversion build:wasm build:bundle build:types",
19
+ "build:genversion": "genversion -se src/common/version.ts",
20
+ "build:wasm": "npm-run-all -pl build:wasm:*",
21
+ "build:wasm:shared": "emmake cmake --build build/shared -j 8",
22
+ "build:wasm:unshared": "emmake cmake --build build/unshared -j 8",
23
+ "build:bundle": "ts-node src/bundle.ts",
24
+ "build:types": "dts-bundle-generator --fail-on-class --no-banner -o lib/plugin/index.d.ts src/plugin/index.ts",
24
25
  "format": "prettier 'src/**/*.ts' --write",
25
26
  "lint": "eslint . --ext .ts",
26
27
  "test": "npm --prefix test run start",
27
28
  "bundle": "npm run build && esbuild lib/plugin/index.js --bundle --outfile=dist/plugin.js"
28
29
  },
29
30
  "dependencies": {
30
- "@4players/odin-common": "~2.7.0"
31
+ "@4players/odin-common": "~2.8.0"
31
32
  },
32
33
  "devDependencies": {
33
34
  "@types/node": "~20.14.0",
34
35
  "@typescript-eslint/eslint-plugin": "~7.16.0",
35
36
  "@typescript-eslint/parser": "~7.16.0",
37
+ "dts-bundle-generator": "^9.5.1",
36
38
  "esbuild": "~0.23.0",
37
39
  "eslint": "~8.57.0",
38
40
  "eslint-config-semistandard": "~17.0.0",
39
41
  "eslint-plugin-import": "~2.29.0",
40
42
  "eslint-plugin-node": "~11.1.0",
41
43
  "eslint-plugin-promise": "~6.1.0",
44
+ "genversion": "^3.2.0",
42
45
  "npm-run-all2": "~6.1.0",
43
46
  "prettier": "~3.3.0",
44
47
  "rimraf": "~5.0.0",
@@ -1,2 +0,0 @@
1
- export declare function getByteSize(buffer: Uint8Array, offset: number): number | undefined;
2
- export declare function getNextOffset(buffer: Uint8Array, offset: number): number | undefined;
@@ -1,117 +0,0 @@
1
- export function getByteSize(buffer, offset) {
2
- const nextOffset = getNextOffset(buffer, offset);
3
- return nextOffset !== undefined ? nextOffset - offset : undefined;
4
- }
5
- export function getNextOffset(buffer, offset) {
6
- if (offset >= buffer.length)
7
- return undefined;
8
- const tag = buffer[offset++];
9
- switch (tag) {
10
- case 0xc0:
11
- case 0xc2:
12
- case 0xc3:
13
- return offset;
14
- case 0xc4:
15
- return skipBytes(buffer, offset + 1, read8bit(buffer, offset));
16
- case 0xc5:
17
- return skipBytes(buffer, offset + 2, read16bit(buffer, offset));
18
- case 0xc6:
19
- return skipBytes(buffer, offset + 4, read32bit(buffer, offset));
20
- case 0xc7:
21
- return skipBytes(buffer, offset + 2, read8bit(buffer, offset));
22
- case 0xc8:
23
- return skipBytes(buffer, offset + 3, read16bit(buffer, offset));
24
- case 0xc9:
25
- return skipBytes(buffer, offset + 5, read32bit(buffer, offset));
26
- case 0xca:
27
- return skipBytes(buffer, offset, 4);
28
- case 0xcb:
29
- return skipBytes(buffer, offset, 8);
30
- case 0xcc:
31
- return skipBytes(buffer, offset, 1);
32
- case 0xcd:
33
- return skipBytes(buffer, offset, 2);
34
- case 0xce:
35
- return skipBytes(buffer, offset, 4);
36
- case 0xcf:
37
- return skipBytes(buffer, offset, 8);
38
- case 0xd0:
39
- return skipBytes(buffer, offset, 1);
40
- case 0xd1:
41
- return skipBytes(buffer, offset, 2);
42
- case 0xd2:
43
- return skipBytes(buffer, offset, 4);
44
- case 0xd3:
45
- return skipBytes(buffer, offset, 8);
46
- case 0xd4:
47
- return skipBytes(buffer, offset, 2);
48
- case 0xd5:
49
- return skipBytes(buffer, offset, 3);
50
- case 0xd6:
51
- return skipBytes(buffer, offset, 5);
52
- case 0xd7:
53
- return skipBytes(buffer, offset, 9);
54
- case 0xd8:
55
- return skipBytes(buffer, offset, 17);
56
- case 0xd9:
57
- return skipBytes(buffer, offset + 1, read8bit(buffer, offset));
58
- case 0xda:
59
- return skipBytes(buffer, offset + 2, read16bit(buffer, offset));
60
- case 0xdb:
61
- return skipBytes(buffer, offset + 4, read32bit(buffer, offset));
62
- case 0xdc:
63
- return skipObjects(buffer, offset + 2, read16bit(buffer, offset));
64
- case 0xdd:
65
- return skipObjects(buffer, offset + 4, read32bit(buffer, offset));
66
- case 0xde:
67
- return skipObjects(buffer, offset + 2, read16bit(buffer, offset) * 2);
68
- case 0xdf:
69
- return skipObjects(buffer, offset + 4, read32bit(buffer, offset) * 2);
70
- default:
71
- if ((tag & 0x80) === 0x00)
72
- return offset;
73
- if ((tag & 0xf0) === 0x80) {
74
- return skipObjects(buffer, offset, (tag & 0x0f) * 2);
75
- }
76
- if ((tag & 0xf0) === 0x90)
77
- return skipObjects(buffer, offset, tag & 0x0f);
78
- if ((tag & 0xe0) === 0xa0)
79
- return skipBytes(buffer, offset, tag & 0x1f);
80
- if ((tag & 0xe0) === 0xe0)
81
- return offset;
82
- throw new Error('invalid msgpack');
83
- }
84
- }
85
- function skipBytes(buffer, offset, bytes) {
86
- const newOffset = offset + bytes;
87
- return isFinite(newOffset) ? newOffset : undefined;
88
- }
89
- function skipObjects(buffer, offset, objects) {
90
- if (!isFinite(objects))
91
- return undefined;
92
- for (let i = 0; i < objects; i++) {
93
- const newOffset = getNextOffset(buffer, offset);
94
- if (newOffset === undefined)
95
- return undefined;
96
- offset = newOffset;
97
- }
98
- return offset;
99
- }
100
- function read8bit(bytes, offset) {
101
- if (offset > bytes.length)
102
- return NaN;
103
- return bytes[offset];
104
- }
105
- function read16bit(bytes, offset) {
106
- if (offset + 2 > bytes.length)
107
- return NaN;
108
- return (bytes[offset] << 8) | bytes[offset + 1];
109
- }
110
- function read32bit(bytes, offset) {
111
- if (offset + 4 > bytes.length)
112
- return NaN;
113
- return ((bytes[offset] << 24) |
114
- (bytes[offset + 1] << 16) |
115
- (bytes[offset + 2] << 8) |
116
- bytes[offset + 3]);
117
- }
@@ -1,12 +0,0 @@
1
- import { Logger } from '@4players/odin-common';
2
- export declare const HealthCheckTimeout = 1000;
3
- export declare const ClockJumpCheckInterval = 1000;
4
- export declare const ClockJumpThreshold = 10000;
5
- export declare const MainConnectionPingInterval: undefined;
6
- export declare const WebRtcIceTimeout = 3000;
7
- export declare const WebRtcTimeout = 10000;
8
- export declare const ConnectTimeout = 5000;
9
- export declare const MinTokenLifetime = 60000;
10
- export declare const MinTokenRefreshInterval = 5000;
11
- export declare const ConnectInterval: number[];
12
- export declare const logger: Logger;
@@ -1,22 +0,0 @@
1
- import { Logger } from '@4players/odin-common';
2
- export const HealthCheckTimeout = 1000; /* ms */
3
- export const ClockJumpCheckInterval = 1000; /* ms */
4
- export const ClockJumpThreshold = 10000; /* ms */
5
- export const MainConnectionPingInterval = undefined; /* disabled, was 10000 ms */
6
- export const WebRtcIceTimeout = 3000; /* ms */
7
- export const WebRtcTimeout = 10000; /* ms */
8
- export const ConnectTimeout = 5000; /* ms */
9
- export const MinTokenLifetime = 60000; /* 1min */
10
- export const MinTokenRefreshInterval = 5000; /* 5sec */
11
- export const ConnectInterval = [0, 100, 200, 200, 500, 1000, 2000]; /* ms */
12
- let loggerInstance;
13
- const projectName = 'odin-plugin-web';
14
- function createLogger() {
15
- return new Logger(projectName, {
16
- tags: [],
17
- });
18
- }
19
- if (!loggerInstance) {
20
- loggerInstance = createLogger();
21
- }
22
- export const logger = loggerInstance;
@@ -1,17 +0,0 @@
1
- import { Result } from '@4players/odin-common';
2
- import { DatagramHandler, MainConnection } from './mainConnection';
3
- import { Transport } from './index';
4
- export declare class ConnectionPool {
5
- readonly onDatagram: DatagramHandler;
6
- private _LastConnectionId;
7
- private readonly _ConnectionsByUrl;
8
- private readonly _ConnectionsById;
9
- private readonly _Close;
10
- get closed(): boolean;
11
- constructor(onDatagram: DatagramHandler);
12
- sendDatagram(connectionId: number, packet: Uint8Array): void;
13
- acquireConnection(transport: Transport, address: string, signal: AbortSignal): Promise<Result<MainConnection> | 'closed'>;
14
- releaseConnection(connection: MainConnection): void;
15
- checkHealth(): Promise<void>;
16
- close(): void;
17
- }
@@ -1,130 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { failure, nextTick, success } from '@4players/odin-common';
11
- import { ClockJumpCheckInterval, ClockJumpThreshold, logger } from './config';
12
- import { createMainConnection, } from './mainConnection';
13
- export class ConnectionPool {
14
- get closed() {
15
- return this._Close.signal.aborted;
16
- }
17
- constructor(onDatagram) {
18
- this.onDatagram = onDatagram;
19
- this._LastConnectionId = 0;
20
- this._ConnectionsByUrl = new Map();
21
- this._ConnectionsById = new Map();
22
- this._Close = new AbortController();
23
- let lastCheckAt = Date.now();
24
- const clockJumpDetector = setInterval(() => {
25
- const elapsed = Math.abs(Date.now() - lastCheckAt);
26
- if (elapsed > ClockJumpThreshold)
27
- this.checkHealth();
28
- lastCheckAt = Date.now();
29
- }, ClockJumpCheckInterval);
30
- addEventListener('offline', () => this.checkHealth(), {
31
- signal: this._Close.signal,
32
- });
33
- this._Close.signal.addEventListener('abort', () => {
34
- clearInterval(clockJumpDetector);
35
- for (const entry of this._ConnectionsById.values()) {
36
- if (entry.status === 'ready') {
37
- entry.connection.close();
38
- }
39
- }
40
- this._ConnectionsById.clear();
41
- this._ConnectionsByUrl.clear();
42
- }, { once: true });
43
- }
44
- sendDatagram(connectionId, packet) {
45
- const connection = this._ConnectionsById.get(connectionId);
46
- if (connection !== undefined && connection.status === 'ready') {
47
- connection.connection.sendDatagram(packet);
48
- }
49
- }
50
- acquireConnection(transport, address, signal) {
51
- return __awaiter(this, void 0, void 0, function* () {
52
- logger.log(['Connection'], 'ConnectionPool.acquireConnection(): transport, address', transport, address);
53
- yield nextTick(); // slow down acquireConnection
54
- if (this.closed)
55
- return 'closed';
56
- const key = create_connection_key(transport, address);
57
- let entry = this._ConnectionsByUrl.get(key);
58
- if (entry === undefined ||
59
- (entry.status === 'ready' && entry.connection.closed)) {
60
- // Create a new Connection
61
- const id = this._LastConnectionId++;
62
- const promise = createMainConnection(id, transport, address, this.onDatagram, signal);
63
- entry = { status: 'init', id, promise, references: 1 };
64
- this._ConnectionsByUrl.set(key, entry);
65
- this._ConnectionsById.set(id, entry);
66
- const connection = yield promise;
67
- logger.log(['Connection'], 'ConnectionPool.acquireConnection(): MainConnection resolved.', connection);
68
- if (connection.type !== 'Success') {
69
- this._ConnectionsByUrl.delete(key);
70
- this._ConnectionsById.delete(id);
71
- return connection;
72
- }
73
- entry = {
74
- status: 'ready',
75
- connection: connection.value,
76
- references: entry.references,
77
- };
78
- this._ConnectionsByUrl.set(key, entry);
79
- this._ConnectionsById.set(id, entry);
80
- return success(entry.connection);
81
- }
82
- else if (entry.status === 'init') {
83
- logger.log(['Connection'], 'ConnectionPool.acquireConnection(): Found a MainConnection but it is still in init state.');
84
- // Wait for the connection to connect
85
- entry.references += 1;
86
- const onAbort = new Promise((accept) => signal.addEventListener('abort', () => accept(), { once: true }));
87
- const result = yield Promise.race([entry.promise, onAbort]);
88
- logger.log(['Connection'], 'ConnectionPool.acquireConnection(): MainConnection was in init state but is now resolved', result);
89
- if (result === undefined)
90
- return failure('aborted');
91
- return result;
92
- }
93
- else {
94
- // Return the connection
95
- logger.log(['Connection'], 'ConnectionPool.acquireConnection(): Found a MainConnection and return it');
96
- entry.references += 1;
97
- return success(entry.connection);
98
- }
99
- });
100
- }
101
- releaseConnection(connection) {
102
- logger.log(['Connection'], 'ConnectionPool.releaseConnection()');
103
- const entry = this._ConnectionsById.get(connection.id);
104
- logger.log(['Connection'], 'ConnectionPool.releaseConnection() entry refs', entry === null || entry === void 0 ? void 0 : entry.references);
105
- if (entry === undefined)
106
- return;
107
- if (entry.status === 'init') {
108
- logger.log(['Connection'], 'ConnectionPool.releaseConnection(): MainConnection state is init, return.');
109
- return;
110
- }
111
- entry.references -= 1;
112
- if (entry.references === 0) {
113
- logger.log(['Connection'], 'ConnectionPool.releaseConnection(): References is 0, close the MainConnection.');
114
- entry.connection.close();
115
- this._ConnectionsByUrl.delete(create_connection_key(connection.transport, connection.address));
116
- this._ConnectionsById.delete(connection.id);
117
- }
118
- }
119
- checkHealth() {
120
- return __awaiter(this, void 0, void 0, function* () {
121
- yield Promise.all(Array.from(this._ConnectionsById.values()).map((entry) => entry.status === 'ready' ? entry.connection.healthCheck() : undefined));
122
- });
123
- }
124
- close() {
125
- this._Close.abort();
126
- }
127
- }
128
- function create_connection_key(transport, address) {
129
- return `${transport} ${address}`;
130
- }
@@ -1,12 +0,0 @@
1
- import { MediaController, Device } from './mediaController';
2
- import { DeviceParameters } from './index';
3
- import { Backend, Result } from '@4players/odin-common';
4
- export declare function openCaptureDevice(controller: MediaController, parameters: DeviceParameters, apm: Backend.ApmConfig): Promise<Result<MediaStreamAudioSourceNode>>;
5
- export declare function stopMediaStream(ms: MediaStream): void;
6
- export declare function enumerateDevices(): Promise<Device[]>;
7
- /**
8
- * Requests audio and video browser permissions. Optionally, requests either audio or video permissions.
9
- * @private
10
- * @throws
11
- */
12
- export declare function requestMediaPermissions(): Promise<boolean>;
@@ -1,120 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { Device } from './mediaController';
11
- import { logger } from './index';
12
- import { failure, sleep, success, } from '@4players/odin-common';
13
- let hasAudioPermissions = false;
14
- export function openCaptureDevice(controller, parameters, apm) {
15
- return __awaiter(this, void 0, void 0, function* () {
16
- const deviceId = parameters.device
17
- ? { exact: parameters.device.device.deviceId }
18
- : undefined;
19
- let stream;
20
- try {
21
- const result = yield Promise.race([
22
- navigator.mediaDevices.getUserMedia({
23
- audio: {
24
- echoCancellation: apm.echoCanceller,
25
- noiseSuppression: apm.noiseSuppression !== 'None',
26
- autoGainControl: apm.gainController,
27
- // @ts-ignore chrome fix
28
- echoCancellationType: 'system',
29
- // sampleRate: 48000,
30
- deviceId,
31
- },
32
- }),
33
- sleep(30000, 'timeout'),
34
- ]);
35
- if (result === 'timeout')
36
- return failure('getUserMedia; timeout');
37
- hasAudioPermissions = true;
38
- stream = result;
39
- }
40
- catch (reason) {
41
- return failure(`getUserMedia; ${reason}`);
42
- }
43
- const sampleRate = stream.getAudioTracks()[0].getSettings().sampleRate;
44
- const context = yield controller.audioContexts.acquire(sampleRate);
45
- return success(context.createMediaStreamSource(stream));
46
- });
47
- }
48
- export function stopMediaStream(ms) {
49
- ms.getTracks().forEach((track) => {
50
- track.stop();
51
- ms.removeTrack(track);
52
- });
53
- }
54
- export function enumerateDevices() {
55
- return __awaiter(this, void 0, void 0, function* () {
56
- hasAudioPermissions = yield requestMediaPermissions();
57
- const mediaDeviceInfos = yield navigator.mediaDevices.enumerateDevices();
58
- const devices = [];
59
- let outputDeviceIndex = 0;
60
- let inputDeviceIndex = 0;
61
- for (const mediaDeviceInfo of mediaDeviceInfos) {
62
- if (mediaDeviceInfo.kind === 'audioinput') {
63
- if (inputDeviceIndex === 0) {
64
- devices.push(new Device(mediaDeviceInfo, true));
65
- }
66
- else {
67
- devices.push(new Device(mediaDeviceInfo, false));
68
- }
69
- inputDeviceIndex++;
70
- }
71
- if (mediaDeviceInfo.kind === 'audiooutput') {
72
- if (outputDeviceIndex === 0) {
73
- devices.push(new Device(mediaDeviceInfo, true));
74
- }
75
- else {
76
- devices.push(new Device(mediaDeviceInfo, false));
77
- }
78
- outputDeviceIndex++;
79
- }
80
- }
81
- return devices;
82
- });
83
- }
84
- /**
85
- * Requests audio and video browser permissions. Optionally, requests either audio or video permissions.
86
- * @private
87
- * @throws
88
- */
89
- export function requestMediaPermissions() {
90
- return __awaiter(this, void 0, void 0, function* () {
91
- if (hasAudioPermissions)
92
- return true;
93
- const constraints = {};
94
- constraints.audio = {
95
- sampleRate: undefined,
96
- deviceId: '',
97
- autoGainControl: false,
98
- noiseSuppression: false,
99
- advanced: undefined,
100
- aspectRatio: undefined,
101
- echoCancellation: false,
102
- channelCount: 0,
103
- facingMode: undefined,
104
- frameRate: 0,
105
- };
106
- logger.debug(['Device'], 'requestMediaPermissions(): constraints', constraints);
107
- try {
108
- const ms = yield navigator.mediaDevices.getUserMedia(constraints);
109
- ms === null || ms === void 0 ? void 0 : ms.getTracks().forEach((track) => {
110
- track.stop();
111
- ms.removeTrack(track);
112
- });
113
- }
114
- catch (e) {
115
- logger.error(['Device'], `requestMediaPermissions(): Requesting permissions for ${'audio'} failed.`, e);
116
- return false;
117
- }
118
- return true;
119
- });
120
- }
@@ -1,31 +0,0 @@
1
- import { ConnectionStatus, type DatagramHandler, type MainConnection } from '../mainConnection';
2
- import { MainCommands, MainNotifications, PeerId, Result } from '@4players/odin-common';
3
- import { Transport } from '..';
4
- import { Token } from '../token';
5
- import { RpcConnection, TypedRpcConnection } from '../rpcConnection';
6
- export declare class H3MainConnection implements MainConnection {
7
- readonly id: number;
8
- readonly address: string;
9
- readonly connection: WebTransport;
10
- readonly rpc: TypedRpcConnection<MainCommands, MainNotifications>;
11
- readonly closeController: AbortController;
12
- status: ConnectionStatus;
13
- readonly closePromise: Promise<'closed'>;
14
- readonly datagramWriter: WritableStreamDefaultWriter<Uint8Array>;
15
- get closeSignal(): AbortSignal;
16
- get transport(): Transport;
17
- get closed(): boolean;
18
- static create(id: number, address: string, onDatagram: DatagramHandler, signal: AbortSignal): Promise<Result<MainConnection>>;
19
- private constructor();
20
- waitForConnected(): Promise<void>;
21
- close(): void;
22
- joinRoom(token: Token, roomId: string, userData: Uint8Array, position: [number, number, number]): Promise<'closed' | Result<RpcConnection>>;
23
- getReconnectToken(peerId: PeerId): Promise<Result<Token>>;
24
- healthCheck(): Promise<boolean>;
25
- sendDatagram(datagram: Uint8Array): void;
26
- startLocalVideo(mediaId: number, track: MediaStreamTrack): void;
27
- stopLocalVideo(mediaId: number): void;
28
- startRemoteVideo(mediaId: number): Promise<MediaStreamTrack>;
29
- stopRemoteVideo(mediaId: number): void;
30
- private _Request;
31
- }