UNPKG

@livepeer/core-web

Version:

Livepeer UI Kit's core web library, for adding reactive stores to video elements.

216 lines (213 loc) 8.9 kB
import { MediaControllerStore } from '@livepeer/core/media'; import { ClientStorage } from '@livepeer/core/storage'; import { StoreApi } from 'zustand/vanilla'; type BroadcastStatus = "live" | "pending" | "idle"; type AudioDeviceId = "default" | `ID${string}`; type VideoDeviceId = "default" | "screen" | `ID${string}`; type MediaDeviceIds = { audioinput: AudioDeviceId; videoinput: VideoDeviceId; }; type MediaDeviceInfoExtended = Omit<MediaDeviceInfo, "label" | "toJSON"> & { /** * This is a convenience field added to MediaDeviceInfo to help easily add a device picker. * * For security reasons, the label field will blank unless an active media stream exists * or the user has granted persistent permission for media device access. The set of device labels * could otherwise be used as part of a fingerprinting mechanism to identify a user. * * When the label field is not blank, these are the same value. Otherwise, the value is a friendly default. */ friendlyName: string; /** * For security reasons, the label field is blank unless an active media stream exists * or the user has granted persistent permission for media device access. The set of device labels * could otherwise be used as part of a fingerprinting mechanism to identify a user. * * We override it here to be null when it is blank, for easier developer usage. */ label: string | null; }; declare const getBroadcastDeviceInfo: (version: string) => BroadcastDeviceInformation; type BroadcastDeviceInformation = { version: string; /** If the environment supports mediaDevices */ isMediaDevicesSupported: boolean; /** If the environment supports RTCPeerConnection */ isRTCPeerConnectionSupported: boolean; /** If the environment supports sharing display media */ isDisplayMediaSupported: boolean; }; type BroadcastControlsState = { /** The last time that a force renegotiation was requested (this is triggered on an error) */ requestedForceRenegotiateLastTime: number; /** The last time that the device list was requested */ requestedUpdateDeviceListLastTime: number; /** The requested audio input device ID */ requestedAudioInputDeviceId: AudioDeviceId; /** The requested video input device ID */ requestedVideoInputDeviceId: VideoDeviceId | null; /** The previous video input device ID, used when screenshare ends */ previousVideoInputDeviceId: VideoDeviceId | null; /** The original microphone track, stored for swapping with silent track */ microphoneTrack: MediaStreamTrack | null; /** * The internal list of the current media devices from the browser. */ mediaDevices: MediaDeviceInfo[] | null; }; type InitialBroadcastProps = { /** * The aspect ratio for the container element */ aspectRatio: number | null; /** * Whether audio is initially enabled for the broadcast. * * Set to false to initialize the broadcast to not request an audio track. */ audio: boolean | Omit<MediaTrackConstraints, "deviceId">; /** * The creatorId for the current broadcast. */ creatorId: string | null; /** * Whether hotkeys are enabled. Defaults to `true`. Allows users to use keyboard shortcuts for broadcast control. * * This is highly recommended to adhere to ARIA guidelines. */ hotkeys: boolean; /** * Whether the WebRTC stream should attempt to initialize immediately after the user grants * permission to their video/audio input. * * Defaults to `false`, where preview is shown and then once the stream is enabled, it sends * media to the server. */ forceEnabled?: boolean; /** * Whether video is initially enabled for the broadcast. * * Set to false to initialize the broadcast to not request a video track. */ video: boolean | Omit<MediaTrackConstraints, "deviceId">; /** * @deprecated in favor of `iceServers` * * Whether to disable ICE gathering. * * Set to true to disable ICE gathering. This is useful for testing purposes. */ noIceGathering?: boolean; /** * Whether to send a silent audio track if the audio is disabled. * * Set to true to send a silent audio track if the audio is disabled. */ silentAudioTrack?: boolean; /** * The ICE servers to use. * * If not provided, the default ICE servers will be used. */ iceServers?: RTCIceServer | RTCIceServer[]; /** * Whether the video stream should be mirrored (horizontally flipped). * * Set to true to broadcast a mirrored view. * Defaults to `false`. */ mirrored?: boolean; }; type BroadcastAriaText = { audioTrigger: string; start: string; screenshareTrigger: string; videoTrigger: string; }; type BroadcastState = { /** The ARIA text for the current state. */ aria: BroadcastAriaText; /** If the broadcast audio track is turned on. */ audio: boolean; /** Whether the broadcast is currently enabled, or in "preview" mode. */ enabled: boolean; /** Whether the broadcast store is hydrated. */ hydrated: boolean; /** * A list of the current media devices. This will change when permissions change, or when * a user starts sharing their display. */ mediaDevices: MediaDeviceInfoExtended[] | null; /** The MediaStream for the current broadcast. */ mediaStream: MediaStream | null; /** Whether the broadcast component is mounted. */ mounted: boolean; /** The RTCPeerConnection for the current broadcast. */ peerConnection: RTCPeerConnection | null; /** The status of the current broadcast. */ status: BroadcastStatus; /** * The WHIP ingest URL to use for the broadcast. */ ingestUrl: string | null; /** If the broadcast video track is turned on. */ video: boolean; /** The currently selected media devices. */ mediaDeviceIds: MediaDeviceIds; /** The initial props passed into the component. */ __initialProps: InitialBroadcastProps; /** The broadcast device information and support. */ __device: BroadcastDeviceInformation; /** The controls state. */ __controls: BroadcastControlsState; __controlsFunctions: { requestDeviceListInfo: () => void; requestForceRenegotiate: () => void; requestMediaDeviceId: (deviceId: AudioDeviceId, type: keyof MediaDeviceIds) => void; rotateAudioSource: () => void; rotateVideoSource: () => void; setIngestUrl: (ingestUrl: string) => void; setInitialState: (ids: MediaDeviceIds, audio: boolean, video: boolean) => void; setPeerConnection: (peerConnection: RTCPeerConnection) => void; setStatus: (status: BroadcastStatus) => void; setMediaDeviceIds: (mediaDevices: Partial<MediaDeviceIds>) => void; toggleAudio: () => void; toggleDisplayMedia: () => void; toggleEnabled: () => void; toggleVideo: () => void; updateDeviceList: (mediaDevices: MediaDeviceInfo[]) => void; updateMediaStream: (mediaStream: MediaStream) => void; }; }; type BroadcastStore = StoreApi<BroadcastState> & { subscribe: { (listener: (selectedState: BroadcastState, previousSelectedState: BroadcastState) => void): () => void; <U>(selector: (state: BroadcastState) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: { equalityFn?: (a: U, b: U) => boolean; fireImmediately?: boolean; }): () => void; }; persist: { onFinishHydration: (fn: (state: BroadcastState) => void) => () => void; }; }; declare const createBroadcastStore: ({ ingestUrl, device, storage, initialProps, }: { ingestUrl: string | null | undefined; device: BroadcastDeviceInformation; storage: ClientStorage; initialProps: Partial<InitialBroadcastProps>; }) => { store: BroadcastStore; destroy: () => void; }; declare const addBroadcastEventListeners: (element: HTMLMediaElement, store: BroadcastStore, mediaStore: MediaControllerStore) => { destroy: () => void; }; /** * Creates a silent audio track to use when audio is muted but we still want * to send an audio track. This helps maintain connection stability while muted. * @returns MediaStreamTrack A silent audio track */ declare const createSilentAudioTrack: () => MediaStreamTrack; export { type AudioDeviceId, type BroadcastAriaText, type BroadcastControlsState, type BroadcastDeviceInformation, type BroadcastState, type BroadcastStatus, type BroadcastStore, type InitialBroadcastProps, type MediaDeviceIds, type MediaDeviceInfoExtended, type VideoDeviceId, addBroadcastEventListeners, createBroadcastStore, createSilentAudioTrack, getBroadcastDeviceInfo };