UNPKG

@jellyfish-dev/ts-client-sdk

Version:
513 lines 20.9 kB
import { BandwidthLimit, Endpoint, SimulcastConfig, TrackBandwidthLimit, TrackContext, TrackEncoding, MetadataParser, WebRTCEndpointEvents } from "./webrtc"; import TypedEmitter from "typed-emitter"; import { ReconnectConfig } from "./reconnection"; import { AuthErrorReason } from "./auth"; export type Peer<PeerMetadata, TrackMetadata> = Endpoint<PeerMetadata, TrackMetadata> & { type: "webrtc"; }; export type Component<PeerMetadata, TrackMetadata> = Omit<Endpoint<PeerMetadata, TrackMetadata>, "type"> & { type: "recording" | "hls" | "file" | "rtsp" | "sip"; }; /** * Events emitted by the client with their arguments. */ export interface MessageEvents<PeerMetadata, TrackMetadata> { /** * Emitted when the websocket connection is closed * * @param {CloseEvent} event - Close event object from the websocket */ socketClose: (event: CloseEvent) => void; /** * Emitted when occurs an error in the websocket connection * * @param {Event} event - Event object from the websocket */ socketError: (event: Event) => void; /** * Emitted when the websocket connection is opened * * @param {Event} event - Event object from the websocket */ socketOpen: (event: Event) => void; /** Emitted when authentication is successful */ authSuccess: () => void; /** Emitted when authentication fails */ authError: (reason: AuthErrorReason) => void; /** Emitted when the connection is closed */ disconnected: () => void; /** * Called when peer was accepted. */ joined: (peerId: string, peers: Peer<PeerMetadata, TrackMetadata>[], components: Component<PeerMetadata, TrackMetadata>[]) => void; /** * Called when peer was not accepted * @param metadata - Pass through for client application to communicate further actions to frontend */ joinError: (metadata: any) => void; /** * Called when data in a new track arrives. * * This callback is always called after {@link MessageEvents.trackAdded}. * It informs user that data related to the given track arrives and can be played or displayed. */ trackReady: (ctx: TrackContext<PeerMetadata, TrackMetadata>) => void; /** * Called each time the peer which was already in the room, adds new track. Fields track and stream will be set to null. * These fields will be set to non-null value in {@link MessageEvents.trackReady} */ trackAdded: (ctx: TrackContext<PeerMetadata, TrackMetadata>) => void; /** * Called when some track will no longer be sent. * * It will also be called before {@link MessageEvents.peerLeft} for each track of this peer. */ trackRemoved: (ctx: TrackContext<PeerMetadata, TrackMetadata>) => void; /** * Called each time peer has its track metadata updated. */ trackUpdated: (ctx: TrackContext<PeerMetadata, TrackMetadata>) => void; /** * Called each time new peer joins the room. */ peerJoined: (peer: Peer<PeerMetadata, TrackMetadata>) => void; /** * Called each time peer leaves the room. */ peerLeft: (peer: Peer<PeerMetadata, TrackMetadata>) => void; /** * Called each time peer has its metadata updated. */ peerUpdated: (peer: Peer<PeerMetadata, TrackMetadata>) => void; /** * Called each time new peer joins the room. */ componentAdded: (peer: Component<PeerMetadata, TrackMetadata>) => void; /** * Called each time peer leaves the room. */ componentRemoved: (peer: Component<PeerMetadata, TrackMetadata>) => void; /** * Called each time peer has its metadata updated. */ componentUpdated: (peer: Component<PeerMetadata, TrackMetadata>) => void; /** * Called in case of errors related to multimedia session e.g. ICE connection. */ connectionError: (message: string) => void; /** * Currently, this callback is only invoked when DisplayManager in RTC Engine is * enabled and simulcast is disabled. * * Called when priority of video tracks have changed. * @param enabledTracks - list of tracks which will be sent to client from SFU * @param disabledTracks - list of tracks which will not be sent to client from SFU */ tracksPriorityChanged: (enabledTracks: TrackContext<PeerMetadata, TrackMetadata>[], disabledTracks: TrackContext<PeerMetadata, TrackMetadata>[]) => void; /** * Called every time the server estimates client's bandiwdth. * * @param {bigint} estimation - client's available incoming bitrate estimated * by the server. It's measured in bits per second. */ bandwidthEstimationChanged: (estimation: bigint) => void; targetTrackEncodingRequested: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["targetTrackEncodingRequested"]>[0]) => void; localTrackAdded: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["localTrackAdded"]>[0]) => void; localTrackRemoved: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["localTrackRemoved"]>[0]) => void; localTrackReplaced: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["localTrackReplaced"]>[0]) => void; localTrackBandwidthSet: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["localTrackBandwidthSet"]>[0]) => void; localTrackEncodingBandwidthSet: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["localTrackEncodingBandwidthSet"]>[0]) => void; localTrackEncodingEnabled: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["localTrackEncodingEnabled"]>[0]) => void; localTrackEncodingDisabled: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["localTrackEncodingDisabled"]>[0]) => void; localEndpointMetadataChanged: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["localEndpointMetadataChanged"]>[0]) => void; localTrackMetadataChanged: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["localTrackMetadataChanged"]>[0]) => void; disconnectRequested: (event: Parameters<WebRTCEndpointEvents<PeerMetadata, TrackMetadata>["disconnectRequested"]>[0]) => void; } export type SignalingUrl = { /** * Protocol of the websocket server * Default is `"ws"` */ protocol?: string; /** * Host of the websocket server * Default is `"localhost:5002"` */ host?: string; /** * Path of the websocket server * Default is `"/socket/peer/websocket"` */ path?: string; }; /** Configuration object for the client */ export interface ConnectConfig<PeerMetadata> { /** Metadata for the peer */ peerMetadata: PeerMetadata; /** Token for authentication */ token: string; signaling?: SignalingUrl; } export type CreateConfig<PeerMetadata, TrackMetadata> = { peerMetadataParser?: MetadataParser<PeerMetadata>; trackMetadataParser?: MetadataParser<TrackMetadata>; reconnect?: ReconnectConfig | boolean; }; declare const JellyfishClient_base: new <PeerMetadata_1, TrackMetadata_1>() => TypedEmitter<Required<MessageEvents<PeerMetadata_1, TrackMetadata_1>>>; /** * JellyfishClient is the main class to interact with Jellyfish. * * @example * ```typescript * const client = new JellyfishClient<PeerMetadata, TrackMetadata>(); * const peerToken = "YOUR_PEER_TOKEN"; * * // You can listen to events emitted by the client * client.on("joined", (peerId, peersInRoom) => { * console.log("join success"); * }); * * // Start the peer connection * client.connect({ * peerMetadata: {}, * isSimulcastOn: false, * token: peerToken * }); * * // Close the peer connection * client.disconnect(); * ``` * * You can register callbacks to handle the events emitted by the Client. * * @example * ```typescript * * client.on("trackReady", (ctx) => { * console.log("On track ready"); * }); * ``` */ export declare class JellyfishClient<PeerMetadata, TrackMetadata> extends JellyfishClient_base<PeerMetadata, TrackMetadata> { private websocket; private webrtc; private removeEventListeners; status: "new" | "initialized"; private connectConfig; private reconnectManager; private readonly peerMetadataParser; private readonly trackMetadataParser; constructor(config?: CreateConfig<PeerMetadata, TrackMetadata>); /** * Uses the {@link !WebSocket} connection and {@link !WebRTCEndpoint | WebRTCEndpoint} to join to the room. Registers the callbacks to * handle the events emitted by the {@link !WebRTCEndpoint | WebRTCEndpoint}. Make sure that peer metadata is serializable. * * @example * ```typescript * const client = new JellyfishClient<PeerMetadata, TrackMetadata>(); * * client.connect({ * peerMetadata: {}, * token: peerToken * }); * ``` * * @param {ConnectConfig} config - Configuration object for the client */ connect(config: ConnectConfig<PeerMetadata>): void; private initConnection; private initWebsocket; /** * Retrieves statistics related to the RTCPeerConnection. * These statistics provide insights into the performance and status of the connection. * * @return {Promise<RTCStatsReport>} * * @external RTCPeerConnection#getStats() * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/getStats | MDN Web Docs: RTCPeerConnection.getStats()} */ getStatistics(selector?: MediaStreamTrack | null): Promise<RTCStatsReport>; /** * Returns a snapshot of currently received remote tracks. * * @example * if (client.getRemoteTracks()[trackId]?.simulcastConfig?.enabled) { * client.setTargetTrackEncoding(trackId, encoding); * } */ getRemoteTracks(): Readonly<Record<string, TrackContext<PeerMetadata, TrackMetadata>>>; /** * Returns a snapshot of currently received remote endpoints. */ getRemoteEndpoints(): Record<string, Endpoint<PeerMetadata, TrackMetadata>>; /** * Returns a snapshot of currently received remote peers. */ getRemotePeers(): Record<string, Peer<PeerMetadata, TrackMetadata>>; getRemoteComponents(): Record<string, Component<PeerMetadata, TrackMetadata>>; getLocalEndpoint(): Endpoint<PeerMetadata, TrackMetadata> | null; getBandwidthEstimation(): bigint; private setupCallbacks; /** * Register a callback to be called when the event is emitted. * Full list of callbacks can be found here {@link MessageEvents}. * * @example * ```ts * const callback = ()=>{ }; * * client.on("onJoinSuccess", callback); * ``` * * @param event - Event name from {@link MessageEvents} * @param listener - Callback function to be called when the event is emitted * @returns This */ on<E extends keyof MessageEvents<PeerMetadata, TrackMetadata>>(event: E, listener: Required<MessageEvents<PeerMetadata, TrackMetadata>>[E]): this; /** * Remove a callback from the list of callbacks to be called when the event is emitted. * * @example * ```ts * const callback = ()=>{ }; * * client.on("onJoinSuccess", callback); * * client.off("onJoinSuccess", callback); * ``` * * @param event - Event name from {@link MessageEvents} * @param listener - Reference to function to be removed from called callbacks * @returns This */ off<E extends keyof MessageEvents<PeerMetadata, TrackMetadata>>(event: E, listener: Required<MessageEvents<PeerMetadata, TrackMetadata>>[E]): this; private handleWebRTCNotInitialized; /** * Adds track that will be sent to the RTC Engine. * * @example * ```ts * const localStream: MediaStream = new MediaStream(); * try { * const localAudioStream = await navigator.mediaDevices.getUserMedia( * { audio: true } * ); * localAudioStream * .getTracks() * .forEach((track) => localStream.addTrack(track)); * } catch (error) { * console.error("Couldn't get microphone permission:", error); * } * * try { * const localVideoStream = await navigator.mediaDevices.getUserMedia( * { video: true } * ); * localVideoStream * .getTracks() * .forEach((track) => localStream.addTrack(track)); * } catch (error) { * console.error("Couldn't get camera permission:", error); * } * * localStream * .getTracks() * .forEach((track) => client.addTrack(track, localStream)); * ``` * * @param track - Audio or video track e.g. from your microphone or camera. * @param stream - Stream that this track belongs to. * @param trackMetadata - Any information about this track that other peers will receive in * {@link MessageEvents.peerJoined}. E.g. this can source of the track - wheather it's screensharing, webcam or some * other media device. * @param simulcastConfig - Simulcast configuration. By default, simulcast is disabled. For more information refer to * {@link !SimulcastConfig | SimulcastConfig}. * @param maxBandwidth - Maximal bandwidth this track can use. Defaults to 0 which is unlimited. This option has no * effect for simulcast and audio tracks. For simulcast tracks use {@link JellyfishClient.setTrackBandwidth}. * @returns {string} Returns id of added track */ addTrack(track: MediaStreamTrack, stream: MediaStream, trackMetadata?: TrackMetadata, simulcastConfig?: SimulcastConfig, maxBandwidth?: TrackBandwidthLimit): Promise<string>; /** * Replaces a track that is being sent to the RTC Engine. * * @example * ```ts * // setup camera * let localStream: MediaStream = new MediaStream(); * try { * localVideoStream = await navigator.mediaDevices.getUserMedia( * VIDEO_CONSTRAINTS * ); * localVideoStream * .getTracks() * .forEach((track) => localStream.addTrack(track)); * } catch (error) { * console.error("Couldn't get camera permission:", error); * } * let oldTrackId; * localStream * .getTracks() * .forEach((track) => trackId = webrtc.addTrack(track, localStream)); * * // change camera * const oldTrack = localStream.getVideoTracks()[0]; * let videoDeviceId = "abcd-1234"; * navigator.mediaDevices.getUserMedia({ * video: { * ...(VIDEO_CONSTRAINTS as {}), * deviceId: { * exact: videoDeviceId, * }, * } * }) * .then((stream) => { * let videoTrack = stream.getVideoTracks()[0]; * webrtc.replaceTrack(oldTrackId, videoTrack); * }) * .catch((error) => { * console.error('Error switching camera', error); * }) * ``` * * @param {string} trackId - Id of audio or video track to replace. * @param {MediaStreamTrack} newTrack - New audio or video track. * @param {TrackMetadata} [newTrackMetadata] - Optional track metadata to apply to the new track. If no track metadata is passed, the * old track metadata is retained. * @returns {Promise<boolean>} Success */ replaceTrack(trackId: string, newTrack: MediaStreamTrack, newTrackMetadata?: TrackMetadata): Promise<void>; /** * Updates maximum bandwidth for the track identified by trackId. This value directly translates to quality of the * stream and, in case of video, to the amount of RTP packets being sent. In case trackId points at the simulcast * track bandwidth is split between all of the variant streams proportionally to their resolution. * * @param {string} trackId * @param {BandwidthLimit} bandwidth In kbps * @returns {Promise<boolean>} Success */ setTrackBandwidth(trackId: string, bandwidth: BandwidthLimit): Promise<boolean>; /** * Updates maximum bandwidth for the given simulcast encoding of the given track. * * @param {string} trackId - Id of the track * @param {string} rid - Rid of the encoding * @param {BandwidthLimit} bandwidth - Desired max bandwidth used by the encoding (in kbps) * @returns */ setEncodingBandwidth(trackId: string, rid: string, bandwidth: BandwidthLimit): Promise<boolean>; /** * Removes a track from connection that was being sent to the RTC Engine. * * @example * ```ts * // setup camera * let localStream: MediaStream = new MediaStream(); * try { * localVideoStream = await navigator.mediaDevices.getUserMedia( * VIDEO_CONSTRAINTS * ); * localVideoStream * .getTracks() * .forEach((track) => localStream.addTrack(track)); * } catch (error) { * console.error("Couldn't get camera permission:", error); * } * * let trackId * localStream * .getTracks() * .forEach((track) => trackId = webrtc.addTrack(track, localStream)); * * // remove track * webrtc.removeTrack(trackId) * ``` * * @param {string} trackId - Id of audio or video track to remove. */ removeTrack(trackId: string): Promise<void>; /** * Sets track encoding that server should send to the client library. * * The encoding will be sent whenever it is available. If chosen encoding is temporarily unavailable, some other * encoding will be sent until chosen encoding becomes active again. * * @example * ```ts * webrtc.setTargetTrackEncoding(incomingTrackCtx.trackId, "l") * ``` * * @param {string} trackId - Id of track * @param {TrackEncoding} encoding - Encoding to receive */ setTargetTrackEncoding(trackId: string, encoding: TrackEncoding): void; /** * Enables track encoding so that it will be sent to the server. * * @example * ```ts * const trackId = webrtc.addTrack(track, stream, {}, {enabled: true, active_encodings: ["l", "m", "h"]}); * webrtc.disableTrackEncoding(trackId, "l"); * // wait some time * webrtc.enableTrackEncoding(trackId, "l"); * ``` * * @param {string} trackId - Id of track * @param {TrackEncoding} encoding - Encoding that will be enabled */ enableTrackEncoding(trackId: string, encoding: TrackEncoding): void; /** * Disables track encoding so that it will be no longer sent to the server. * * @example * ```ts * const trackId = webrtc.addTrack(track, stream, {}, {enabled: true, active_encodings: ["l", "m", "h"]}); * webrtc.disableTrackEncoding(trackId, "l"); * ``` * * @param {string} trackId - Id of track * @param {rackEncoding} encoding - Encoding that will be disabled */ disableTrackEncoding(trackId: string, encoding: TrackEncoding): void; /** * Updates the metadata for the current peer. * * @param peerMetadata - Data about this peer that other peers will receive upon joining. * * If the metadata is different from what is already tracked in the room, the event {@link MessageEvents.peerUpdated} will * be emitted for other peers in the room. */ updatePeerMetadata: (peerMetadata: PeerMetadata) => void; /** * Updates the metadata for a specific track. * * @param trackId - TrackId (generated in addTrack) of audio or video track. * @param trackMetadata - Data about this track that other peers will receive upon joining. * * If the metadata is different from what is already tracked in the room, the event {@link MessageEvents.trackUpdated} will * be emitted for other peers in the room. */ updateTrackMetadata: (trackId: string, trackMetadata: TrackMetadata) => void; /** * Leaves the room. This function should be called when user leaves the room in a clean way e.g. by clicking a * dedicated, custom button `disconnect`. As a result there will be generated one more media event that should be sent * to the RTC Engine. Thanks to it each other peer will be notified that peer left in {@link MessageEvents.peerLeft}, */ leave: () => void; private isOpen; /** * Disconnect from the room, and close the websocket connection. Tries to leave the room gracefully, but if it fails, * it will close the websocket anyway. * * @example * ```typescript * const client = new JellyfishClient<PeerMetadata, TrackMetadata>(); * * client.connect({ ... }); * * client.disconnect(); * ``` */ disconnect(): void; } export {}; //# sourceMappingURL=JellyfishClient.d.ts.map