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 (streamer did) */
36 src: string;
37
38 /** Function to set the source URL */
39 setSrc: (src: string) => void;
40
41 /** Flag indicating if ingest is live */
42 ingestLive: boolean;
43 setIngestLive: (ingestLive: boolean) => void;
44
45 /** Current connection state of ingest RTP/RTC peer connection */
46 ingestConnectionState: RTCPeerConnectionState | null;
47
48 /** Function to update the ingest connection state */
49 setIngestConnectionState: (state: RTCPeerConnectionState | null) => void;
50
51 ingestMediaSource?: IngestMediaSource;
52 setIngestMediaSource?: (source: IngestMediaSource) => void;
53
54 ingestCamera: "user" | "environment";
55 setIngestCamera: (camera: "user" | "environment") => void;
56
57 ingestAutoStart?: boolean;
58 setIngestAutoStart?: (autoStart: boolean) => void;
59
60 /** stop ingest process, again with a slight delay to allow UI to update */
61 stopIngest: () => void;
62
63 /** Timestamp (number) when ingest started, or null if not started */
64 ingestStarted: number | null;
65
66 /** Function to set the ingestStarted timestamp */
67 setIngestStarted: (timestamp: number | null) => void;
68
69 /** Player fullscreen state */
70 fullscreen: boolean;
71
72 /** Function to set the fullscreen state */
73 setFullscreen: (isFullscreen: boolean) => void;
74
75 /** Current player status */
76 status: PlayerStatus;
77
78 /** Function to update the player status */
79 setStatus: (status: PlayerStatus) => void;
80
81 /** Current playback time in seconds */
82 playTime: number;
83
84 /** Function to set the current playback time */
85 setPlayTime: (playTime: number) => void;
86
87 /** Flag indicating if player is in offline state */
88 /** Reference to the video element for direct manipulation (used for PiP) */
89 videoRef:
90 | React.MutableRefObject<HTMLVideoElement | null>
91 | ((instance: HTMLVideoElement | null) => void)
92 | null
93 | undefined;
94
95 /** Function to set the video reference */
96 setVideoRef: (
97 videoRef:
98 | React.MutableRefObject<HTMLVideoElement | null>
99 | ((instance: HTMLVideoElement | null) => void)
100 | null
101 | undefined,
102 ) => void;
103
104 pipAction: (() => void) | undefined;
105 /** Function to set the Picture-in-Picture action */
106 setPipAction: (action: (() => void) | undefined) => void;
107
108 /** Player element width (CSS value or number) */
109 playerWidth?: string | number;
110 /** Function to set the player width */
111 setPlayerWidth: (width: number) => void;
112
113 /** Player element height (CSS value or number) */
114 playerHeight?: string | number;
115 /** Function to set the player height */
116 setPlayerHeight: (height: number) => void;
117
118 /** Flag indicating if player is in Picture-in-Picture mode */
119 pipMode: boolean;
120
121 /** Function to set the Picture-in-Picture mode */
122 setPipMode: (pipMode: boolean) => void;
123
124 /** Flag indicating if mute was forced by system (e.g., autoplay policy) */
125 muteWasForced: boolean;
126
127 /** Function to set the muteWasForced flag */
128 setMuteWasForced: (muteWasForced: boolean) => void;
129
130 /** Flag indicating if autoplay failed and needs user interaction */
131 autoplayFailed: boolean;
132
133 /** Function to set the autoplayFailed flag */
134 setAutoplayFailed: (autoplayFailed: boolean) => void;
135
136 /** Flag indicating if the player is embedded in another context */
137 embedded: boolean;
138
139 /** Function to set the embedded flag */
140 setEmbedded: (embedded: boolean) => void;
141
142 /** Flag indicating if player controls should be shown */
143 showControls: boolean;
144 controlsTimeout?: NodeJS.Timeout | undefined;
145
146 /** Function to set the showControls flag */
147 setShowControls: (showControls: boolean) => void;
148
149 telemetry: boolean;
150 setTelemetry: (telemetry: boolean) => void;
151
152 playerEvent: (
153 url: string,
154 time: string,
155 eventType: string,
156 meta: { [key: string]: any },
157 ) => void;
158
159 clearControlsTimeout: () => void;
160
161 setUserInteraction: () => void;
162
163 showDebugInfo: boolean;
164 setShowDebugInfo: (showDebugInfo: boolean) => void;
165
166 /** Message to be moderated */
167 modMessage: ChatMessageViewHydrated | null;
168
169 /** Function to set the mod message */
170 setModMessage: (message: ChatMessageViewHydrated | null) => void;
171
172 /** URL to send player events to (if not default) */
173 reportingURL: string | null;
174
175 /** Function to set the reporting URL */
176 setReportingURL: (reportingURL: string | null) => void;
177
178 /** Is the report modal open? */
179 reportModalOpen: boolean;
180
181 /** Function to set the report modal open state */
182 setReportModalOpen: (reportModalOpen: boolean) => void;
183
184 /** Subject to report */
185 reportSubject: ComAtprotoModerationCreateReport.InputSchema["subject"] | null;
186
187 /** Function to set the report subject */
188 setReportSubject: (
189 subject: ComAtprotoModerationCreateReport.InputSchema["subject"] | null,
190 ) => void;
191}
192
193export type PlayerEvent = {
194 id?: string;
195 time: string;
196 playerId: string;
197 eventType: string;
198 meta: { [key: string]: any };
199};