@100mslive/hms-video-store
Version:
@100mslive Core SDK which abstracts the complexities of webRTC while providing a reactive store for data management with a unidirectional data flow
227 lines (226 loc) • 12.7 kB
TypeScript
import { HMSNotifications } from './HMSNotifications';
import { Diagnostics } from '../diagnostics';
import { HMSSessionFeedback } from '../end-call-feedback';
import { IHMSActions } from '../IHMSActions';
import { IHMSStore } from '../IHMSStore';
import { HMSAudioPlugin, HMSChangeMultiTrackStateRequest as SDKHMSChangeMultiTrackStateRequest, HMSChangeTrackStateRequest as SDKHMSChangeTrackStateRequest, HMSException as SDKHMSException, HMSLocalAudioTrack as SDKHMSLocalAudioTrack, HMSLocalTrack as SDKHMSLocalTrack, HMSLogLevel, HMSMediaStreamPlugin, HMSPluginSupportResult, HMSScreenShareConfig, HMSTrack as SDKHMSTrack, HMSVideoPlugin } from '../internal';
import * as sdkTypes from '../internal';
import { MessageNotification } from '../notification-manager';
import { HMSChangeMultiTrackStateParams, HMSGenericTypes, HMSMessage, HMSPeer, HMSPeerListIteratorOptions, HMSRoleName, HMSTrackID, HMSTrackSource, IHMSPlaylistActions, IHMSSessionStoreActions } from '../schema';
import { HMSSdk } from '../sdk';
import { HMSRoleChangeRequest } from '../selectors';
import { FindPeerByNameRequestParams } from '../signal/interfaces';
import { HMSStats } from '../webrtc-stats';
/**
* This class implements the IHMSActions interface for 100ms SDK. It connects with SDK
* and takes control of data management by letting every action pass through it. The
* passed in store is ensured to be the single source of truth reflecting current
* room related data at any point in time.
*
* @privateRemarks
* Things to keep in mind while updating store -
* 1. Treat setState as an atomic operation, if an action results in multiple changes,
* the changes should all happen within single setState function.
* 2. While updating the state it's very important to not update the reference if
* something is unchanged. Copy data in same reference object don't assign new
* object.
* 3. Mental Model(1) - Actions from backend -> Listeners of this class -> update store -> views update themselves
* eg. for this - peer added, remote muted etc.
* 4. Mental Model(2) - Actions from local -> View calls actions -> update store -> views update themselves
* eg. local track enabled, join, leave etc.
* 5. State is immutable, a new copy with new references is created when there is a change,
* if you try to modify state outside of setState, there'll be an error.
*/
export declare class HMSSDKActions<T extends HMSGenericTypes = {
sessionStore: Record<string, any>;
}> implements IHMSActions<T> {
private readonly sdk;
private readonly store;
private isRoomJoinCalled;
private hmsNotifications;
private ignoredMessageTypes;
private actionBatcher;
audioPlaylist: IHMSPlaylistActions;
videoPlaylist: IHMSPlaylistActions;
sessionStore: IHMSSessionStoreActions<T['sessionStore']>;
private beamSpeakerLabelsLogger?;
constructor(store: IHMSStore<T>, sdk: HMSSdk, notificationManager: HMSNotifications<T>);
submitSessionFeedback(feedback: HMSSessionFeedback, eventEndpoint?: string): Promise<void>;
getLocalTrack(trackID: string): SDKHMSLocalTrack | undefined;
get interactivityCenter(): import("../session-store/interactivity-center").InteractivityCenter;
setPlaylistSettings(settings: sdkTypes.HMSPlaylistSettings): void;
refreshDevices(): Promise<void>;
unblockAudio(): Promise<void>;
setVolume(value: number, trackId?: HMSTrackID): Promise<void>;
setAudioOutputDevice(deviceId: string): Promise<void>;
setPreferredLayer(trackId: string, layer: sdkTypes.HMSPreferredSimulcastLayer): Promise<void>;
getNativeTrackById(trackId: string): MediaStreamTrack | undefined;
getTrackById(trackId: string): SDKHMSTrack | SDKHMSLocalAudioTrack | undefined;
getAuthTokenByRoomCode(tokenRequest: sdkTypes.TokenRequest, tokenRequestOptions?: sdkTypes.TokenRequestOptions): Promise<string>;
preview(config: sdkTypes.HMSPreviewConfig): Promise<void>;
cancelMidCallPreview(): Promise<void>;
join(config: sdkTypes.HMSConfig): Promise<void>;
leave(): Promise<void>;
setScreenShareEnabled(enabled: boolean, config?: HMSScreenShareConfig): Promise<void>;
addTrack(track: MediaStreamTrack, type?: HMSTrackSource): Promise<void>;
removeTrack(trackId: string): Promise<void>;
setLocalAudioEnabled(enabled: boolean): Promise<void>;
setLocalVideoEnabled(enabled: boolean): Promise<void>;
setEnabledTrack(trackID: string, enabled: boolean): Promise<void>;
autoSelectAudioOutput(delay?: number): Promise<void>;
setAudioSettings(settings: Partial<sdkTypes.HMSAudioTrackSettings>): Promise<void>;
setVideoSettings(settings: Partial<sdkTypes.HMSVideoTrackSettings>): Promise<void>;
switchCamera(): Promise<void>;
sendMessage(message: string): void;
sendBroadcastMessage(message: string, type?: string): Promise<void>;
sendGroupMessage(message: string, roles: string[], type?: string): Promise<void>;
sendDirectMessage(message: string, peerID: string, type?: string): Promise<void>;
private updateMessageInStore;
setMessageRead(readStatus: boolean, messageId?: string): void;
attachVideo(trackID: string, videoElement: HTMLVideoElement): Promise<void>;
detachVideo(trackID: string, videoElement: HTMLVideoElement): Promise<void>;
addPluginToVideoTrack(plugin: HMSVideoPlugin, pluginFrameRate?: number): Promise<void>;
addPluginsToVideoStream(plugins: HMSMediaStreamPlugin[]): Promise<void>;
removePluginsFromVideoStream(plugins: HMSMediaStreamPlugin[]): Promise<void>;
addPluginToAudioTrack(plugin: HMSAudioPlugin): Promise<void>;
validateVideoPluginSupport(plugin: HMSVideoPlugin): HMSPluginSupportResult;
validateAudioPluginSupport(plugin: HMSAudioPlugin): HMSPluginSupportResult;
removePluginFromVideoTrack(plugin: HMSVideoPlugin): Promise<void>;
removePluginFromAudioTrack(plugin: HMSAudioPlugin): Promise<void>;
changeRole(forPeerId: string, toRole: string, force?: boolean): Promise<void>;
changeRoleOfPeer(forPeerId: string, toRole: string, force?: boolean): Promise<void>;
changeRoleOfPeersWithRoles(roles: HMSRoleName[], toRole: HMSRoleName): Promise<void>;
acceptChangeRole(request: HMSRoleChangeRequest): Promise<void>;
raiseLocalPeerHand(): Promise<void>;
lowerLocalPeerHand(): Promise<void>;
raiseRemotePeerHand(peerId: string): Promise<void>;
lowerRemotePeerHand(peerId: string): Promise<void>;
getPeer(peerId: string): Promise<HMSPeer | undefined>;
findPeerByName(options: FindPeerByNameRequestParams): Promise<{
offset: number;
eof: boolean | undefined;
peers: HMSPeer[];
}>;
getPeerListIterator(options?: HMSPeerListIteratorOptions): {
hasNext: () => boolean;
next: () => Promise<HMSPeer[]>;
findPeers: () => Promise<HMSPeer[]>;
getTotal: () => number;
};
initAppData(appData: Record<string, any>): void;
setAppData(key: string, value: any, merge?: boolean): void;
/**
* @privateRemarks
* there is no corresponding sdk method for rejecting change role but as the store also maintains the full
* state of current pending requests, this method allows it to clean up when the request is rejected
*/
rejectChangeRole(request: HMSRoleChangeRequest): void;
endRoom(lock: boolean, reason: string): Promise<void>;
removePeer(peerID: string, reason: string): Promise<void>;
startRTMPOrRecording(params: sdkTypes.RTMPRecordingConfig): Promise<void>;
stopRTMPAndRecording(): Promise<void>;
startHLSStreaming(params?: sdkTypes.HLSConfig): Promise<void>;
stopHLSStreaming(params?: sdkTypes.StopHLSConfig): Promise<void>;
startTranscription(params: sdkTypes.TranscriptionConfig): Promise<void>;
stopTranscription(params: sdkTypes.TranscriptionConfig): Promise<void>;
sendHLSTimedMetadata(metadataList: sdkTypes.HLSTimedMetadata[]): Promise<void>;
changeName(name: string): Promise<void>;
changeMetadata(metadata: string | any): Promise<void>;
setSessionMetadata(metadata: any): Promise<void>;
populateSessionMetadata(): Promise<void>;
setRemoteTrackEnabled(trackID: HMSTrackID | HMSTrackID[], enabled: boolean): Promise<void>;
setRemoteTracksEnabled(params: HMSChangeMultiTrackStateParams): Promise<void>;
setLogLevel(level: HMSLogLevel): void;
setFrameworkInfo(frameworkInfo: sdkTypes.HMSFrameworkInfo): void;
ignoreMessageTypes(msgTypes: string[], replace?: boolean): void;
enableBeamSpeakerLabelsLogging(): Promise<void>;
initDiagnostics(): Diagnostics;
private resetState;
getDebugInfo(): import("../schema").DebugInfo | undefined;
private sdkJoinWithListeners;
private onSFUMigration;
private onRemovedFromRoom;
private onDeviceChange;
private sdkPreviewWithListeners;
private onNetworkQuality;
private onSessionStoreUpdate;
private onPollsUpdate;
private onWhiteboardUpdate;
private startScreenShare;
private stopScreenShare;
private attachVideoInternal;
/**
* This is a very important function as it's responsible for maintaining the source of
* truth with maximum efficiency. The efficiency comes from the fact that the only
* those portions of the store are updated which have actually changed.
* While making a change in this function don't use functions like map, reduce etc.
* which return a new copy of the data. Use Object.assign etc. to ensure that if the data
* doesn't change reference is also not changed.
* The UI and selectors rely on the fact that the store is immutable that is if there is
* any change and only if there is a change, they'll get a new copy of the data they're
* interested in with a new reference.
* @protected
*/
protected syncRoomState(action: string): void;
protected onPreview(sdkRoom: sdkTypes.HMSRoom): void;
protected onJoin(sdkRoom: sdkTypes.HMSRoom): void;
protected onRoomUpdate(type: sdkTypes.HMSRoomUpdate, room: sdkTypes.HMSRoom): void;
protected onPeerUpdate(type: sdkTypes.HMSPeerUpdate, sdkPeer: sdkTypes.HMSPeer | sdkTypes.HMSPeer[]): void;
protected onTrackUpdate(type: sdkTypes.HMSTrackUpdate, track: SDKHMSTrack, peer: sdkTypes.HMSPeer): void;
protected onMessageReceived(message: MessageNotification): void;
protected putMessageInStore(hmsMessage: HMSMessage): void;
protected onAudioLevelUpdate(sdkSpeakers: sdkTypes.HMSSpeaker[]): void;
/**
* The connection quality update is sent for all peers(one needs to know of) every time.
*/
protected onConnectionQualityUpdate(newQualities: sdkTypes.HMSConnectionQuality[]): void;
protected onChangeTrackStateRequest(request: SDKHMSChangeTrackStateRequest): void;
protected onChangeMultiTrackStateRequest(request: SDKHMSChangeMultiTrackStateRequest): void;
protected onReconnected(): void;
protected onReconnecting(sdkError: SDKHMSException): void;
protected onError(sdkException: SDKHMSException): void;
private handleTrackRemove;
private setEnabledSDKTrack;
private setSDKLocalVideoTrackSettings;
private setSDKLocalAudioTrackSettings;
private getMediaSettings;
private getPreviewFields;
private setTrackVolume;
/**
* Tells if the trackID is for local peer and video unmute is in process
* @private
*/
private localAndVideoUnmuting;
private logPossibleInconsistency;
private addRemoveVideoPlugin;
private addRemoveMediaStreamVideoPlugins;
private addRemoveAudioPlugin;
/**
* convert new role change requests to store format and save.
* keep only one request at a time in store till we figure out how to handle multiple requests at the same time
*/
private onRoleChangeRequest;
private removeRoleChangeRequest;
private onRoleUpdate;
private getStoreLocalTrackIDfromSDKTrack;
private setProgress;
private syncPlaylistState;
private sendPeerUpdateNotification;
private updateMidCallPreviewRoomState;
private setSessionStoreValueLocally;
private getSDKHMSPeer;
/**
* setState is separate so any future changes to how state change can be done from one place.
* @param fn
* @param name
*/
private setState;
/**
* @internal
* This will be used by beam to check if the recording should continue, it will pass __hms.stats
* It will poll at a fixed interval and start an exit timer if the method fails twice consecutively
* The exit timer is stopped if the method returns true before that
* @param hmsStats
*/
hasActiveElements(hmsStats: HMSStats): boolean;
}