UNPKG

@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

150 lines (131 loc) 4.49 kB
import { HMSTrackType } from './HMSTrackType'; import AnalyticsEventFactory from '../../analytics/AnalyticsEventFactory'; import { stringifyMediaStreamTrack } from '../../utils/json'; import HMSLogger from '../../utils/logger'; import { HMSMediaStream } from '../streams'; export type HMSTrackSource = 'regular' | 'screen' | 'plugin' | 'audioplaylist' | 'videoplaylist' | string; export abstract class HMSTrack { /** * @internal */ readonly stream: HMSMediaStream; source?: HMSTrackSource; peerId?: string; transceiver?: RTCRtpTransceiver; /** * @internal to print as a helpful identifier alongside logs */ logIdentifier = ''; /** The native mediastream track, for local, this changes on mute/unmute(for video), * and on device change. * @internal */ nativeTrack: MediaStreamTrack; /** * Firefox doesn't respect the track id as sent from the backend when calling peerconnection.ontrack callback. This * breaks correlation of future track updates from backend. So we're storing the sdp track id as present in the * original offer along with the track as well and will let this override the native track id for any correlation * purpose. * This applies for remote tracks only. * @internal */ private sdpTrackId?: string; /** * @internal * The local track id is changed on mute/unmute or when device id changes, this is abstracted as an internal * detail of HMSTrack and the variable is used for this enacapsulation where the first track id is remembered * and treated as the fixed track id for this HMSTrack. This simplifies things for the user of the sdk who * do not have to worry about changing track IDs. * This applies for local tracks only. */ private firstTrackId?: string; abstract readonly type: HMSTrackType; public get enabled(): boolean { return this.nativeTrack.enabled; } /** * firstTrackId => encapsulates change in local track ids * sdpTrackId => fixes remote track updates correlation on firefox */ public get trackId(): string { return this.firstTrackId || this.sdpTrackId || this.nativeTrack.id; } getMediaTrackSettings(): MediaTrackSettings { return this.nativeTrack.getSettings(); } /** * Get performance metrics from attached plugins (e.g., effects SDK). * Override in subclasses that support plugins. * @returns Object with plugin names as keys and their metrics as values, or undefined */ getPluginsMetrics(): Record<string, Record<string, unknown> | undefined> | undefined { return undefined; } async setEnabled(value: boolean): Promise<void> { this.nativeTrack.enabled = value; } protected constructor(stream: HMSMediaStream, track: MediaStreamTrack, source?: HMSTrackSource) { this.stream = stream; this.nativeTrack = track; this.source = source; } /** * @internal */ setSdpTrackId(sdpTrackId: string) { this.sdpTrackId = sdpTrackId; } /** * @internal */ protected setFirstTrackId(trackId: string) { this.firstTrackId = trackId; } isTrackNotPublishing = () => { return this.nativeTrack.readyState === 'ended' || this.nativeTrack.muted; }; /** * @internal * It will send event to analytics when interruption start/stop */ sendInterruptionEvent({ started, reason }: { started: boolean; reason: string }) { const track = this.nativeTrack; return AnalyticsEventFactory.interruption({ started, type: this.type, reason, deviceInfo: { deviceId: track.getSettings().deviceId, groupId: track.getSettings().groupId, }, trackInfo: { label: track.label, enabled: track.enabled, muted: track.muted, readyState: track.readyState, settings: track.getSettings(), }, }); } /** * @internal * take care of - * 1. https://bugs.chromium.org/p/chromium/issues/detail?id=1232649 * 2. stopping any tracks * 3. plugins related cleanups and stopping */ cleanup() { HMSLogger.d('[HMSTrack]', 'Stopping track', this.toString()); this.nativeTrack?.stop(); } toString() { return `{ streamId: ${this.stream.id}; peerId: ${this.peerId}; trackId: ${this.trackId}; mid: ${this.transceiver?.mid || '-'}; logIdentifier: ${this.logIdentifier}; source: ${this.source}; enabled: ${this.enabled}; nativeTrack: ${stringifyMediaStreamTrack(this.nativeTrack)}; }`; } }