Live video on the AT Protocol
1import { ComAtprotoModerationCreateReport } from "@atproto/api";
2import { ChatMessageViewHydrated } from "streamplace";
3
4export enum PlayerProtocol {
5 WEBRTC = "webrtc",
6 HLS = "hls",
7 PROGRESSIVE_MP4 = "progressive-mp4",
8 PROGRESSIVE_WEBM = "progressive-webm",
9}
10
11export enum PlayerStatus {
12 START = "start",
13 PLAYING = "playing",
14 STALLED = "stalled",
15 SUSPEND = "suspend",
16 WAITING = "waiting",
17 PAUSE = "pause",
18 MUTE = "mute",
19}
20
21export type PlayerStatusTracker = Partial<Record<PlayerStatus, number>>;
22
23export enum IngestMediaSource {
24 USER = "user",
25 DISPLAY = "display",
26}
27
28export interface PlayerState {
29 id: string;
30 selectedRendition: string;
31 setSelectedRendition: (rendition: string) => void;
32 protocol: PlayerProtocol;
33 setProtocol: (protocol: PlayerProtocol) => void;
34
35 /** Source */
36 src: string;
37
38 /** Function to set the source URL */
39 setSrc: (src: string) => void;
40
41 /** Flag indicating if ingest (stream input) is currently starting */
42 ingestStarting: boolean;
43
44 /** Function to set the ingestStarting flag */
45 setIngestStarting: (ingestStarting: boolean) => void;
46
47 /** Flag indicating if ingest is live */
48 ingestLive: boolean;
49 setIngestLive: (ingestLive: boolean) => void;
50
51 /** Current connection state of ingest RTP/RTC peer connection */
52 ingestConnectionState: RTCPeerConnectionState | null;
53
54 /** Function to update the ingest connection state */
55 setIngestConnectionState: (state: RTCPeerConnectionState | null) => void;
56
57 ingestMediaSource?: IngestMediaSource;
58 setIngestMediaSource?: (source: IngestMediaSource) => void;
59
60 ingestCamera: "user" | "environment";
61 setIngestCamera: (camera: "user" | "environment") => void;
62
63 ingestAutoStart?: boolean;
64 setIngestAutoStart?: (autoStart: boolean) => void;
65
66 /** Timestamp (number) when ingest started, or null if not started */
67 ingestStarted: number | null;
68
69 /** Function to set the ingestStarted timestamp */
70 setIngestStarted: (timestamp: number | null) => void;
71
72 /** Player fullscreen state */
73 fullscreen: boolean;
74
75 /** Function to set the fullscreen state */
76 setFullscreen: (isFullscreen: boolean) => void;
77
78 /** Current player status */
79 status: PlayerStatus;
80
81 /** Function to update the player status */
82 setStatus: (status: PlayerStatus) => void;
83
84 /** Current playback time in seconds */
85 playTime: number;
86
87 /** Function to set the current playback time */
88 setPlayTime: (playTime: number) => void;
89
90 /** Flag indicating if player is in offline state */
91 /** Reference to the video element for direct manipulation (used for PiP) */
92 videoRef:
93 | React.MutableRefObject<HTMLVideoElement | null>
94 | ((instance: HTMLVideoElement | null) => void)
95 | null
96 | undefined;
97
98 /** Function to set the video reference */
99 setVideoRef: (
100 videoRef:
101 | React.MutableRefObject<HTMLVideoElement | null>
102 | ((instance: HTMLVideoElement | null) => void)
103 | null
104 | undefined,
105 ) => void;
106
107 pipAction: (() => void) | undefined;
108 /** Function to set the Picture-in-Picture action */
109 setPipAction: (action: (() => void) | undefined) => void;
110
111 /** Player element width (CSS value or number) */
112 playerWidth?: string | number;
113 /** Function to set the player width */
114 setPlayerWidth: (width: number) => void;
115
116 /** Player element height (CSS value or number) */
117 playerHeight?: string | number;
118 /** Function to set the player height */
119 setPlayerHeight: (height: number) => void;
120
121 /** Flag indicating if player is in Picture-in-Picture mode */
122 pipMode: boolean;
123
124 /** Function to set the Picture-in-Picture mode */
125 setPipMode: (pipMode: boolean) => void;
126
127 /** Flag indicating if mute was forced by system (e.g., autoplay policy) */
128 muteWasForced: boolean;
129
130 /** Function to set the muteWasForced flag */
131 setMuteWasForced: (muteWasForced: boolean) => void;
132
133 /** Flag indicating if autoplay failed and needs user interaction */
134 autoplayFailed: boolean;
135
136 /** Function to set the autoplayFailed flag */
137 setAutoplayFailed: (autoplayFailed: boolean) => void;
138
139 /** Flag indicating if the player is embedded in another context */
140 embedded: boolean;
141
142 /** Function to set the embedded flag */
143 setEmbedded: (embedded: boolean) => void;
144
145 /** Flag indicating if player controls should be shown */
146 showControls: boolean;
147 controlsTimeout?: NodeJS.Timeout | undefined;
148
149 /** Function to set the showControls flag */
150 setShowControls: (showControls: boolean) => void;
151
152 telemetry: boolean;
153 setTelemetry: (telemetry: boolean) => void;
154
155 playerEvent: (
156 url: string,
157 time: string,
158 eventType: string,
159 meta: { [key: string]: any },
160 ) => void;
161
162 clearControlsTimeout: () => void;
163
164 setUserInteraction: () => void;
165
166 showDebugInfo: boolean;
167 setShowDebugInfo: (showDebugInfo: boolean) => void;
168
169 /** Message to be moderated */
170 modMessage: ChatMessageViewHydrated | null;
171
172 /** Function to set the mod message */
173 setModMessage: (message: ChatMessageViewHydrated | null) => void;
174
175 /** URL to send player events to (if not default) */
176 reportingURL: string | null;
177
178 /** Function to set the reporting URL */
179 setReportingURL: (reportingURL: string | null) => void;
180
181 /** Is the report modal open? */
182 reportModalOpen: boolean;
183
184 /** Function to set the report modal open state */
185 setReportModalOpen: (reportModalOpen: boolean) => void;
186
187 /** Subject to report */
188 reportSubject: ComAtprotoModerationCreateReport.InputSchema["subject"] | null;
189
190 /** Function to set the report subject */
191 setReportSubject: (
192 subject: ComAtprotoModerationCreateReport.InputSchema["subject"] | null,
193 ) => void;
194}
195
196export type PlayerEvent = {
197 id?: string;
198 time: string;
199 playerId: string;
200 eventType: string;
201 meta: { [key: string]: any };
202};