@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
text/typescript
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)};
}`;
}
}