From 649c32bf3cfc4270a527b9e4ee488917703396b0 Mon Sep 17 00:00:00 2001 From: Thomas Frivold Date: Sat, 9 Mar 2024 18:24:00 +0200 Subject: [PATCH] Add more types --- rollup.config.js | 34 +++- src/model/connectionStatusConstants.ts | 4 +- src/utils/ServerSocket.ts | 3 +- src/utils/index.ts | 3 +- src/utils/types.ts | 209 +++++++++++++++++++++++++ src/webrtc/MediaDevices.ts | 63 ++++++-- src/webrtc/P2pRtcManager.ts | 11 +- src/webrtc/RtcManagerDispatcher.ts | 12 +- src/webrtc/VegaRtcManager.ts | 11 +- src/webrtc/index.ts | 1 + src/webrtc/mediaConstraints.ts | 15 +- src/webrtc/types.ts | 136 ++++++++++++++++ tests/utils/ServerSocket.spec.ts | 5 +- tests/webrtc/MediaDevices.spec.ts | 14 +- tests/webrtc/mediaConstraints.spec.ts | 5 +- 15 files changed, 468 insertions(+), 58 deletions(-) create mode 100644 src/utils/types.ts create mode 100644 src/webrtc/types.ts diff --git a/rollup.config.js b/rollup.config.js index 0656032..8726416 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -35,14 +35,32 @@ const external = [...dependencies, ...peerDependencies]; module.exports = [ // Esm build of lib, to be used with bundlers { - input: { webrtc: "src/webrtc/index.ts", utils: "src/utils/index.ts", model: "src/model/index.ts" }, - - output: [ - { - format: "esm", // set ES modules - dir: "dist", // indicate not create a single-file - }, - ], + input: "src/webrtc/index.ts", + output: { + file: "dist/webrtc/index.esm.js", + format: "esm", + exports: "named", + }, + plugins, + external, + }, + { + input: "src/utils/index.ts", + output: { + file: "dist/utils/index.esm.js", + format: "esm", + exports: "named", + }, + plugins, + external, + }, + { + input: "src/model/index.ts", + output: { + file: "dist/model/index.esm.js", + format: "esm", + exports: "named", + }, plugins, external, }, diff --git a/src/model/connectionStatusConstants.ts b/src/model/connectionStatusConstants.ts index 85097e2..cf7b820 100644 --- a/src/model/connectionStatusConstants.ts +++ b/src/model/connectionStatusConstants.ts @@ -1,4 +1,6 @@ -export const EVENTS = { +import { RtcEvents } from "src/webrtc/types"; + +export const EVENTS: Record = { CLIENT_CONNECTION_STATUS_CHANGED: "client_connection_status_changed", STREAM_ADDED: "stream_added", RTC_MANAGER_CREATED: "rtc_manager_created", diff --git a/src/utils/ServerSocket.ts b/src/utils/ServerSocket.ts index ebd0264..deb968e 100644 --- a/src/utils/ServerSocket.ts +++ b/src/utils/ServerSocket.ts @@ -2,6 +2,7 @@ import { io } from "socket.io-client"; import adapter from "webrtc-adapter"; import { ReconnectManager } from "./ReconnectManager"; import { PROTOCOL_RESPONSES } from "../model/protocol"; +import { RtcManager } from "src/webrtc"; const DEFAULT_SOCKET_PATH = "/protocol/socket.io/v4"; @@ -73,7 +74,7 @@ export class ServerSocket { }); } - setRtcManager(rtcManager?: any) { + setRtcManager(rtcManager?: RtcManager) { if (this._reconnectManager) { this._reconnectManager.rtcManager = rtcManager; } diff --git a/src/utils/index.ts b/src/utils/index.ts index bb08180..8f49513 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -8,4 +8,5 @@ export * from "./optimalBitrate"; export * from "./ReconnectManager"; export * from "./ServerSocket"; export * from "./transportSettings"; -export { default as fromLocation } from "./urls"; +export * from "./types"; +export * from "./urls"; diff --git a/src/utils/types.ts b/src/utils/types.ts new file mode 100644 index 0000000..b775673 --- /dev/null +++ b/src/utils/types.ts @@ -0,0 +1,209 @@ +export interface Credentials { + credentials: { + uuid: string; + }; + hmac: string; + userId: string; +} + +/* + Socket +*/ + +export interface SocketConf { + host?: string; + path?: string; + reconnectionDelay?: number; + reconnectoinDelayMax?: number; + timeout?: number; + autoConnect?: boolean; +} + +export interface SocketManager { + on: (eventName: string, callback: (args: unknown) => void) => void; +} + +export interface ClientRole { + roleName: string; +} + +export interface SignalKnocker { + clientId: string; + displayName: string | null; + imageUrl: string | null; + liveVideo: boolean; + userAvatarUrl: string | null; + userId: string | null; +} + +export interface SignalClient { + displayName: string; + id: string; + streams: string[]; + isAudioEnabled: boolean; + isVideoEnabled: boolean; + role: ClientRole; + startedCloudRecordingAt: string | null; +} + +export interface AudioEnabledEvent { + clientId: string; + isAudioEnabled: boolean; +} + +export interface ChatMessage { + id: string; + messageType: "text"; + roomName: string; + senderId: string; + sig: string; + text: string; + timestamp: string; + userId: string; +} + +export interface CloudRecordingStartedEvent { + error?: string; + startedAt?: string; +} + +export interface ClientLeftEvent { + clientId: string; +} +export interface NewClientEvent { + client: SignalClient; + room?: { + session: { + createdAt: string; + id: string; + } | null; + }; +} + +export interface ClientKickedEvent { + clientId: string; +} + +export interface KnockerLeftEvent { + clientId: string; +} + +export interface KnockAcceptedEvent { + clientId: string; + metadata: { + roomKey: string; + roomName: string; + }; + resolution: "accepted"; +} + +export interface KnockRejectedEvent { + clientId: string; + resolution: "rejected"; +} + +export interface RoomJoinedEvent { + error?: string; + isLocked: boolean; + room?: { + clients: SignalClient[]; + knockers: SignalKnocker[]; + session: { + createdAt: string; + id: string; + } | null; + }; + selfId: string; +} + +export interface RoomKnockedEvent { + clientId: string; + displayName: string | null; + imageUrl: string | null; + liveVideo: boolean; +} + +export interface RoomSessionEndedEvent { + roomSessionId: string; +} + +export interface ScreenshareStartedEvent { + clientId: string; + streamId: string; + hasAudioTrack: boolean; +} + +export interface ScreenshareStoppedEvent { + clientId: string; + streamId: string; +} + +export interface VideoEnabledEvent { + clientId: string; + isVideoEnabled: boolean; +} + +export interface ClientMetadataReceivedEvent { + type: string; + payload: { clientId: string; displayName: string }; +} + +export interface SignalEvents { + audio_enabled: AudioEnabledEvent; + client_left: ClientLeftEvent; + client_kicked: ClientKickedEvent; + client_metadata_received: ClientMetadataReceivedEvent; + cloud_recording_started: CloudRecordingStartedEvent; + cloud_recording_stopped: void; + chat_message: ChatMessage; + connect: void; + connect_error: void; + device_identified: void; + disconnect: void; + knock_handled: KnockAcceptedEvent | KnockRejectedEvent; + knocker_left: KnockerLeftEvent; + new_client: NewClientEvent; + room_joined: RoomJoinedEvent; + room_knocked: RoomKnockedEvent; + room_left: void; + room_session_ended: RoomSessionEndedEvent; + screenshare_started: ScreenshareStartedEvent; + screenshare_stopped: ScreenshareStoppedEvent; + streaming_stopped: void; + video_enabled: VideoEnabledEvent; +} + +export interface IdentifyDeviceRequest { + deviceCredentials: Credentials; +} + +export interface JoinRoomRequest { + config: { isAudioEnabled: boolean; isVideoEnabled: boolean }; + organizationId: string; + roomName: string; + displayName?: string; +} + +export interface KnockRoomRequest { + displayName: string; + imageUrl: string | null; + kickFromOtherRooms: boolean; + liveVideo: boolean; + organizationId: string; + roomKey: string | null; + roomName: string; +} + +export interface SignalRequests { + chat_message: { text: string }; + enable_audio: { enabled: boolean }; + enable_video: { enabled: boolean }; + handle_knock: { action: "accept" | "reject"; clientId: string; response: unknown }; + identify_device: IdentifyDeviceRequest; + join_room: JoinRoomRequest; + knock_room: KnockRoomRequest; + leave_room: void; + send_client_metadata: { type: string; payload: { displayName?: string } }; + start_recording: { recording: string }; + stop_recording: void; +} diff --git a/src/webrtc/MediaDevices.ts b/src/webrtc/MediaDevices.ts index c37b17d..489feb3 100644 --- a/src/webrtc/MediaDevices.ts +++ b/src/webrtc/MediaDevices.ts @@ -1,5 +1,12 @@ import getConstraints from "./mediaConstraints"; import Logger from "../utils/Logger"; +import { + GetConstraintsOptions, + GetDeviceDataResult, + GetStreamOptions, + GetStreamResult, + GetUpdatedDevicesResult, +} from "./types"; const logger = new Logger(); @@ -19,7 +26,7 @@ function removeDuplicates(devices: any) { ); } -export async function enumerate() { +export async function enumerate(): Promise { const devices = await global.navigator.mediaDevices.enumerateDevices(); const filteredDevices = removeDuplicates(devices); return filteredDevices; @@ -70,7 +77,12 @@ export function getUserMedia(constraints: any) { }); } -function getSettingsFromTrack(kind: string, track: any, devices: any, lastUsedId: any) { +function getSettingsFromTrack( + kind: string, + track?: MediaStreamTrack | null, + devices?: MediaDeviceInfo[], + lastUsedId?: string +) { let settings: any = { deviceId: null }; if (!track) { @@ -107,7 +119,7 @@ function getSettingsFromTrack(kind: string, track: any, devices: any, lastUsedId // Okay. As if the above wasn't hacky enough (it was), this // is even more, basically see what we sent before // It's really sad if we get down to this point. - settings.deviceId = track.getConstraints()?.deviceId?.exact; + settings.deviceId = track.getConstraints()?.deviceId; settings.broken = 1; // just a hint return settings; } @@ -117,7 +129,21 @@ function getSettingsFromTrack(kind: string, track: any, devices: any, lastUsedId * * @returns {{video: {deviceId}, audio: {deviceId}}} - the ids are null if not found */ -export function getDeviceData({ audioTrack, videoTrack, devices, stoppedVideoTrack, lastAudioId, lastVideoId }: any) { +export function getDeviceData({ + audioTrack, + videoTrack, + devices, + stoppedVideoTrack, + lastAudioId, + lastVideoId, +}: { + audioTrack?: MediaStreamTrack | null; + videoTrack?: MediaStreamTrack | null; + devices: MediaDeviceInfo[]; + stoppedVideoTrack?: boolean; + lastAudioId?: string | undefined; + lastVideoId?: string | undefined; +}): GetDeviceDataResult { const usable = (d: any) => (d?.readyState === "live" ? d : null); videoTrack = usable(videoTrack) || stoppedVideoTrack; audioTrack = usable(audioTrack); @@ -171,8 +197,8 @@ async function getTrack({ primerTrack, }: { kind: "audio" | "video"; - deviceId: string; - type: string; + deviceId?: boolean | string; + type?: string; fallback: any; primerTrack: any; }) { @@ -211,7 +237,10 @@ async function constrainTrack(track: any, constraints: any) { } } -export async function getStream2(constraintOpt: any, additionalOpts: any = {}) { +export async function getStream2( + constraintOpt: GetConstraintsOptions, + additionalOpts: GetStreamOptions = {} +): Promise { const { audioId, videoId, devices, type, options } = constraintOpt; const { replaceStream, fallback } = additionalOpts; const hasGrantedPermissions = !!devices.find((d: any) => d.label !== ""); @@ -329,7 +358,10 @@ export async function getStream2(constraintOpt: any, additionalOpts: any = {}) { * @param options.fallback - try to give working stream * @returns {Promise<{stream, error=null}>} */ -export async function getStream(constraintOpt: any, { replaceStream, fallback = true }: any = {}) { +export async function getStream( + constraintOpt: any, + { replaceStream, fallback = true }: GetStreamOptions = {} +): Promise { let error: any; let newConstraints: any; let retryConstraintOpt: any; @@ -535,7 +567,19 @@ export function compareLocalDevices(before: any, after: any) { return changesByKind; } -export function getUpdatedDevices({ oldDevices, newDevices, currentAudioId, currentVideoId, currentSpeakerId }: any) { +export function getUpdatedDevices({ + oldDevices, + newDevices, + currentAudioId, + currentVideoId, + currentSpeakerId, +}: { + oldDevices: MediaDeviceInfo[]; + newDevices: MediaDeviceInfo[]; + currentAudioId?: string | undefined; + currentVideoId?: string | undefined; + currentSpeakerId?: string | undefined; +}): GetUpdatedDevicesResult { const changesByKind = compareLocalDevices(oldDevices, newDevices); const changedDevices: any = {}; const addedDevices: any = {}; @@ -544,6 +588,7 @@ export function getUpdatedDevices({ oldDevices, newDevices, currentAudioId, curr ["videoinput", currentVideoId], ["audiooutput", currentSpeakerId], ].forEach(([kind, currentDeviceId]) => { + kind = kind || ""; const changes = changesByKind[kind]; if (!changes) { return; diff --git a/src/webrtc/P2pRtcManager.ts b/src/webrtc/P2pRtcManager.ts index 7b054d6..4b84cf3 100644 --- a/src/webrtc/P2pRtcManager.ts +++ b/src/webrtc/P2pRtcManager.ts @@ -15,6 +15,7 @@ import checkIp from "check-ip"; import validate from "uuid-validate"; import rtcManagerEvents from "./rtcManagerEvents"; import Logger from "../utils/Logger"; +import { RtcManager } from "./types"; const logger = new Logger(); @@ -35,7 +36,7 @@ if (browserName === "chrome") { }); } -export default class P2pRtcManager { +export default class P2pRtcManager implements RtcManager { _selfId: any; _roomName: any; _roomSessionId: any; @@ -138,7 +139,7 @@ export default class P2pRtcManager { session.maybeRestrictRelayBandwidth(); } - addNewStream(streamId: string, stream: any) { + addNewStream(streamId: string, stream: MediaStream) { if (stream === this.localStreams[streamId]) { // this can happen after reconnect. We do not want to add the stream to the // peerconnection again. @@ -179,7 +180,7 @@ export default class P2pRtcManager { return; } - replaceTrack(oldTrack: any, newTrack: any) { + replaceTrack(oldTrack: MediaStreamTrack, newTrack: MediaStreamTrack) { if (oldTrack && oldTrack.kind === "audio") { this._stopMonitoringAudioTrack(oldTrack); } @@ -189,7 +190,7 @@ export default class P2pRtcManager { return this._replaceTrackToPeerConnections(oldTrack, newTrack); } - accept({ clientId, shouldAddLocalVideo }: { clientId: any; shouldAddLocalVideo?: any }) { + accept({ clientId, shouldAddLocalVideo }: { clientId: string; shouldAddLocalVideo?: boolean }) { return this.acceptNewStream({ streamId: clientId, clientId, shouldAddLocalVideo }); } @@ -1217,7 +1218,7 @@ export default class P2pRtcManager { }: { streamId: string; clientId: string; - shouldAddLocalVideo: boolean; + shouldAddLocalVideo?: boolean; }) { let session = this._getSession(clientId); if (session && streamId !== clientId) { diff --git a/src/webrtc/RtcManagerDispatcher.ts b/src/webrtc/RtcManagerDispatcher.ts index 1fc8dd0..bbe25fe 100644 --- a/src/webrtc/RtcManagerDispatcher.ts +++ b/src/webrtc/RtcManagerDispatcher.ts @@ -2,10 +2,12 @@ import P2pRtcManager from "./P2pRtcManager"; import { PROTOCOL_RESPONSES } from "../model/protocol"; import * as CONNECTION_STATUS from "../model/connectionStatusConstants"; import VegaRtcManager from "./VegaRtcManager"; +import { ServerSocket } from "src/utils"; +import { RtcManager, RtcEvents } from "./types"; export default class RtcManagerDispatcher { - emitter: any; - currentManager: any; + emitter: { emit: (eventName: K, args?: RtcEvents[K]) => void }; + currentManager: RtcManager | null; constructor({ emitter, @@ -13,8 +15,8 @@ export default class RtcManagerDispatcher { webrtcProvider, features, }: { - emitter: any; - serverSocket: any; + emitter: { emit: (eventName: K, args?: RtcEvents[K]) => void }; + serverSocket: ServerSocket; webrtcProvider: any; features: any; }) { @@ -22,7 +24,7 @@ export default class RtcManagerDispatcher { this.currentManager = null; serverSocket.on( PROTOCOL_RESPONSES.ROOM_JOINED, - ({ room, selfId, error, eventClaim }: { room: any; selfId: any; error: any; eventClaim: any }) => { + ({ room, selfId, error, eventClaim }: { room: any; selfId: any; error: any; eventClaim: string }) => { if (error) return; // ignore error responses which lack room const config = { selfId, diff --git a/src/webrtc/VegaRtcManager.ts b/src/webrtc/VegaRtcManager.ts index dece94e..821f08f 100644 --- a/src/webrtc/VegaRtcManager.ts +++ b/src/webrtc/VegaRtcManager.ts @@ -14,6 +14,7 @@ import createMicAnalyser from "./VegaMicAnalyser"; import { maybeTurnOnly } from "../utils/transportSettings"; import VegaMediaQualityMonitor from "./VegaMediaQualityMonitor"; import Logger from "../utils/Logger"; +import { RtcManager } from "./types"; const logger = new Logger(); @@ -27,7 +28,7 @@ const OUTBOUND_SCREEN_OUTBOUND_STREAM_ID = uuidv4(); if (browserName === "chrome") window.document.addEventListener("beforeunload", () => (unloading = true)); -export default class VegaRtcManager { +export default class VegaRtcManager implements RtcManager { _selfId: any; _room: any; _roomSessionId: any; @@ -35,7 +36,7 @@ export default class VegaRtcManager { _serverSocket: any; _webrtcProvider: any; _features: any; - _eventClaim: any; + _eventClaim?: any; _vegaConnection: any; _micAnalyser: any; _micAnalyserDebugger: any; @@ -94,7 +95,7 @@ export default class VegaRtcManager { serverSocket: any; webrtcProvider: any; features?: any; - eventClaim?: any; + eventClaim?: string; deviceHandlerFactory?: any; }) { const { session, iceServers, sfuServer, mediaserverConfigTtlSeconds } = room; @@ -1018,7 +1019,7 @@ export default class VegaRtcManager { * * @param {string} eventClaim */ - setEventClaim(eventClaim: any) { + setEventClaim(eventClaim: string) { this._eventClaim = eventClaim; this._vegaConnection?.message("eventClaim", { eventClaim }); @@ -1075,7 +1076,7 @@ export default class VegaRtcManager { * @param {ignored} _activeBreakout * @param {string} eventClaim */ - disconnect(clientIdOrStreamId: string, _activeBreakout: any, eventClaim: any) { + disconnect(clientIdOrStreamId: string, _activeBreakout: any, eventClaim?: string) { logger.info("disconnect() [clientIdOrStreamId:%s, eventClaim:%s]", clientIdOrStreamId, eventClaim); if (this._clientStates.has(clientIdOrStreamId)) { diff --git a/src/webrtc/index.ts b/src/webrtc/index.ts index 1db2b79..2c07df7 100644 --- a/src/webrtc/index.ts +++ b/src/webrtc/index.ts @@ -18,6 +18,7 @@ export * from "./sdpModifier"; export { default as Session } from "./Session"; export { default as SfuV2Parser } from "./SfuV2Parser"; export * from "./statsHelper"; +export * from "./types"; export { default as VegaConnection } from "./VegaConnection"; export { default as VegaMediaQualityMonitor } from "./VegaMediaQualityMonitor"; export { default as createMicAnalyser } from "./VegaMicAnalyser"; diff --git a/src/webrtc/mediaConstraints.ts b/src/webrtc/mediaConstraints.ts index 81951d8..3338f9f 100644 --- a/src/webrtc/mediaConstraints.ts +++ b/src/webrtc/mediaConstraints.ts @@ -1,4 +1,5 @@ import adapter from "webrtc-adapter"; +import { GetConstraintsOptions, GetMediaConstraintsOptions } from "./types"; const isSafari = adapter.browserDetails.browser === "safari"; @@ -18,17 +19,7 @@ export function getMediaConstraints({ resolution, simulcast, widescreen, -}: { - disableAEC?: boolean; - disableAGC?: boolean; - hd?: boolean; - lax?: boolean; - lowDataMode?: boolean; - preferredDeviceIds: { audioId: any; videoId: any }; - resolution?: any; - simulcast?: boolean; - widescreen?: boolean; -}) { +}: GetMediaConstraintsOptions) { let HIGH_HEIGHT: any = 480; let LOW_HEIGHT: any = 240; @@ -80,7 +71,7 @@ export function getMediaConstraints({ /** * High level mediaConstraints helper */ -export default function getConstraints({ devices, videoId, audioId, options, type = "ideal" }: any) { +export default function getConstraints({ devices, videoId, audioId, options, type = "ideal" }: GetConstraintsOptions) { const audioDevices = devices.filter((d: any) => d.kind === "audioinput"); const videoDevices = devices.filter((d: any) => d.kind === "videoinput"); const useDefaultAudio = !audioId || !audioDevices.some((d: any) => d.deviceId === audioId); diff --git a/src/webrtc/types.ts b/src/webrtc/types.ts new file mode 100644 index 0000000..ecb9aa9 --- /dev/null +++ b/src/webrtc/types.ts @@ -0,0 +1,136 @@ +/* + RTC +*/ +export enum RtcEventNames { + rtc_manager_created = "rtc_manager_created", + stream_added = "stream_added", +} + +export interface RtcManager { + acceptNewStream: ({ + activeBreakout, + clientId, + shouldAddLocalVideo, + streamId, + }: { + activeBreakout: boolean; + clientId: string; + shouldAddLocalVideo: boolean; + streamId: string; + }) => void; + addNewStream(streamId: string, stream: MediaStream, isAudioEnabled: boolean, isVideoEnabled: boolean): void; + disconnect(streamId: string, activeBreakout: boolean, eventClaim?: string): void; + disconnectAll(): void; + replaceTrack(oldTrack: MediaStreamTrack, newTrack: MediaStreamTrack): void; + removeStream(streamId: string, _stream: MediaStream, requestedByClientId: string | null): void; + shouldAcceptStreamsFromBothSides?: () => boolean; + updateStreamResolution(streamId: string, ignored: null, resolution: { width: number; height: number }): void; + sendStatsCustomEvent(eventName: string, data: unknown): void; + isInitializedWith({ selfId, roomName, isSfu }: { selfId: string; roomName: string; isSfu: boolean }): boolean; + setEventClaim?(eventClaim: string): void; +} + +export interface RtcManagerCreatedPayload { + rtcManager: RtcManager; +} + +export interface RtcStreamAddedPayload { + clientId: string; + stream: MediaStream; + streamId: string | undefined; + streamType: "webcam" | "screenshare" | undefined; +} + +export interface RtcClientConnectionStatusChangedPayload { + streamIds: string[]; + clientId: string; + status: string; + previous: string; +} + +export interface RtcLocalStreamTrackAddedPayload { + streamId: string; + tracks: MediaStreamTrack[]; + screenShare: boolean; +} + +export interface RtcLocalStreamTrackRemovedPayload { + stream: MediaStream; + track: MediaStreamTrack; +} + +export type RtcEvents = { + client_connection_status_changed: RtcClientConnectionStatusChangedPayload; + stream_added: RtcStreamAddedPayload; + rtc_manager_created: RtcManagerCreatedPayload; + rtc_manager_destroyed: void; + local_stream_track_added: RtcLocalStreamTrackAddedPayload; + local_stream_track_removed: RtcLocalStreamTrackRemovedPayload; + remote_stream_track_added: void; + remote_stream_track_removed: void; +}; + +/* + Media Devices +*/ + +export type GetMediaConstraintsOptions = { + disableAEC: boolean; + disableAGC: boolean; + hd: boolean; + lax: boolean; + lowDataMode: boolean; + preferredDeviceIds: { + audioId?: boolean | string | null | { ideal?: string | null; exact?: string | null }; + videoId?: boolean | string | null | { ideal?: string | null; exact?: string | null }; + }; + resolution?: string; + simulcast: boolean; + widescreen: boolean; + usingAspectRatio16x9: boolean; +}; + +export type GetConstraintsOptions = { + devices: MediaDeviceInfo[]; + audioId?: boolean | string; + videoId?: boolean | string; + type?: "ideal" | "exact"; + options: Omit; +}; + +export type GetStreamOptions = { + replaceStream?: MediaStream; + fallback?: boolean; +}; + +export type GetStreamResult = { + error?: unknown; + replacedTracks?: MediaStreamTrack[]; + stream: MediaStream; +}; + +export type GetUpdatedDevicesResult = { + addedDevices: { + audioinput?: { deviceId: string; label: string; kind: string }; + videoinput?: { deviceId: string; label: string; kind: string }; + audiooutput?: { deviceId: string; label: string; kind: string }; + }; + changedDevices: { + audioinput?: { deviceId: string; label: string; kind: string }; + videoinput?: { deviceId: string; label: string; kind: string }; + audiooutput?: { deviceId: string; label: string; kind: string }; + }; +}; + +export type GetDeviceDataResult = { + audio: { + deviceId: string; + label: string; + kind: string; + }; + video: { + deviceId: string; + label: string; + kind: string; + }; +}; diff --git a/tests/utils/ServerSocket.spec.ts b/tests/utils/ServerSocket.spec.ts index 98603cd..10057f0 100644 --- a/tests/utils/ServerSocket.spec.ts +++ b/tests/utils/ServerSocket.spec.ts @@ -1,3 +1,4 @@ +import { RtcManager } from "src/webrtc"; import { PROTOCOL_RESPONSES } from "../../src/model/protocol"; import { ReconnectManager } from "../../src/utils/ReconnectManager"; import { ServerSocket } from "../../src/utils/ServerSocket"; @@ -58,7 +59,7 @@ describe("ServerSocket", () => { it("should accept an rtcManager with glitchfree on", () => { const serverSocket = new ServerSocket("https://localhost", null, true); - const mockManager = jest.fn(); + const mockManager = jest.fn() as any; serverSocket.setRtcManager(mockManager); @@ -70,7 +71,7 @@ describe("ServerSocket", () => { delete serverSocket._reconnectManager; - expect(() => serverSocket.setRtcManager({})).not.toThrow(); + expect(() => serverSocket.setRtcManager({} as any)).not.toThrow(); }); }); diff --git a/tests/webrtc/MediaDevices.spec.ts b/tests/webrtc/MediaDevices.spec.ts index d1eebed..b3ada56 100644 --- a/tests/webrtc/MediaDevices.spec.ts +++ b/tests/webrtc/MediaDevices.spec.ts @@ -226,7 +226,7 @@ describe("getDeviceData", () => { it("empty stream", () => { const stream = helpers.createMockedMediaStream([]); - const res = MediaDevices.getDeviceData({ stream }); + const res = MediaDevices.getDeviceData({ stream } as any); expect(res).toEqual({ audio: { deviceId: null }, video: { deviceId: null } }); }); @@ -236,7 +236,7 @@ describe("getDeviceData", () => { const res = MediaDevices.getDeviceData({ audioTrack: null, - videoTrack: vtrack, + videoTrack: vtrack as any, devices: [], }); @@ -250,7 +250,7 @@ describe("getDeviceData", () => { const atrack = helpers.createMockedMediaStreamTrack({ id: "audiotrack", kind: "audio" }); const res = MediaDevices.getDeviceData({ - audioTrack: atrack, + audioTrack: atrack as any, devices: [], }); @@ -265,8 +265,8 @@ describe("getDeviceData", () => { const stopVtrack = helpers.createMockedMediaStreamTrack({ id: "stopVtrack", kind: "video" }); const res = MediaDevices.getDeviceData({ - audioTrack: atrack, - stoppedVideoTrack: stopVtrack, + audioTrack: atrack as any, + stoppedVideoTrack: stopVtrack as any, devices: [], }); @@ -292,7 +292,7 @@ describe("getDeviceData", () => { const res = MediaDevices.getDeviceData({ audioTrack: atrack, videoTrack: vtrack, - devices, + devices: devices as any, }); expect(res).toEqual({ @@ -311,7 +311,7 @@ describe("getDeviceData", () => { const res = MediaDevices.getDeviceData({ audioTrack: null, videoTrack: null, - devices, + devices: devices as any, lastVideoId: videoId, }); diff --git a/tests/webrtc/mediaConstraints.spec.ts b/tests/webrtc/mediaConstraints.spec.ts index 191a4e6..11e881f 100644 --- a/tests/webrtc/mediaConstraints.spec.ts +++ b/tests/webrtc/mediaConstraints.spec.ts @@ -8,9 +8,10 @@ describe("getConstraints", () => { const adev1 = { kind: "audioinput", deviceId: "adev1" }; const result = getConstraints({ - devices: [vdev1, adev1], + devices: [vdev1, adev1] as any, videoId: "v", audioId: false, + options: {} as any, }); expect(result).toEqual({ video: expect.any(Object) }); @@ -29,7 +30,7 @@ describe("getMediaConstraints", () => { ({ lowDataMode, simulcast, expected }) => { const preferredDeviceIds = { audioId: "audioId", videoId: "videoId" }; - const result = getMediaConstraints({ lowDataMode, preferredDeviceIds, simulcast }); + const result = getMediaConstraints({ lowDataMode, preferredDeviceIds, simulcast } as any); expect(result.video.frameRate).toBe(expected); }