-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathLensPlayer.tsx
More file actions
160 lines (142 loc) · 5.24 KB
/
Copy pathLensPlayer.tsx
File metadata and controls
160 lines (142 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import { ReactNode } from "react";
import { CameraKitSessionEvents, Lens, LensLaunchData, ScreenRegions } from "@snap/camera-kit";
import { CanvasType, OutputSize, SourceInput } from "./types";
import { useApplySource } from "./useApplySource";
import { useApplyLens } from "./useApplyLens";
import { usePlaybackOptions } from "./usePlaybackOptions";
import { CaptureCanvas, LiveCanvas } from "./Canvas";
/**
* Props for the LensPlayer component.
*/
export interface LensPlayerProps {
/** The media source to apply (camera, video, or image). Defaults to camera if not specified. */
source?: SourceInput;
/** Optional output size configuration for the rendering canvas. */
outputSize?: OutputSize;
/** The unique identifier of the Lens to apply. */
lensId?: string;
/** The group ID containing the Lens. Required when lensId is provided. */
lensGroupId?: string;
/** Optional launch parameters to pass to the Lens.. */
lensLaunchData?: LensLaunchData;
/** Optional async guard that must resolve before the Lens is considered ready.
* The guard is called when the lens is in loading state,
* and when the promise returned by the function resolves, it will transition to the ready state.
* If the promise doesn't resolve within 2 seconds, the ready state is forced. */
lensReadyGuard?: () => Promise<void>;
/**
* Trigger to refresh the current Lens. When this value changes,
* the Lens will be removed and reapplied with the current Lens props.
* Useful for restarting the Lens experience without moving LensPlayer
* to another component.
*/
refreshTrigger?: unknown;
/** Which canvas to render: "live" for real-time preview or "capture" for snapshot. Defaults to "live". */
canvasType?: CanvasType;
/**
* A maximum FPS, rendering will not exceed this limit.
*
* This may be useful to reduce CPU/GPU resource usage by CameraKit if, for example,
* the input media source has a low FPS – CameraKit would then not try to render more
* frequently than the source produces new frames.
*
* This may also be useful to gracefully degrade performance in situations where
* lowering FPS is preferable over alternatives.
*/
fpsLimit?: number;
/**
* Whether to mute all sounds. Unmuted by default.
*/
muted?: boolean;
/**
* Configuration object containing the complete set of active screen regions.
*
* Screen regions define areas of the screen that have special meaning for Lens rendering,
* such as safe rendering areas, UI button locations, keyboard areas, etc. This allows lenses
* to adapt their content placement based on the host application's UI layout.
*
* This value is applied as a full replacement set: regions not included in the object are
* removed. Pass `undefined` or omit this option to clear all screen regions.
*/
screenRegions?: ScreenRegions;
/**
* A callback to handle Lens playback errors.
*/
onError?: (error: CameraKitSessionEvents["detail"]["error"], lens: Lens) => void;
/** CSS class name to apply to the wrapper or canvas element. */
className?: string;
/** Inline styles to apply to the wrapper or canvas element. */
style?: React.CSSProperties;
/** Custom children to render instead of the default canvas. When provided, children are wrapped in a styled div. */
children?: ReactNode;
}
/**
* A declarative, all-in-one component for rendering Camera Kit Lenses.
*
* LensPlayer combines source management, lens application, and playback controls into a single
* component. It handles the complexity of coordinating multiple hooks and provides a simple
* prop-based API for common use cases.
*
* @example
* ```tsx
* // Basic lens player with camera source
* <LensPlayer lensId="lens-123" lensGroupId="my-group" />
*
* // With custom source and output size
* <LensPlayer
* source={{ kind: "video", element: videoElement }}
* outputSize={{ mode: "fixed", width: 1280, height: 720 }}
* lensId="lens-123"
* lensGroupId="my-group"
* />
*
* // With playback controls and error handling
* <LensPlayer
* lensId="lens-123"
* lensGroupId="my-group"
* fpsLimit={30}
* muted={true}
* onError={(error) => console.error("Playback error:", error)}
* />
*
* // With custom children instead of default canvas
* <LensPlayer lensId="lens-123" lensGroupId="my-group">
* <div>Custom UI overlaying the Lens <LiveCanvas /></div>
* </LensPlayer>
* ```
*/
export const LensPlayer: React.FC<LensPlayerProps> = ({
source,
outputSize,
lensId,
lensGroupId,
lensLaunchData,
lensReadyGuard,
refreshTrigger,
canvasType,
fpsLimit,
muted,
screenRegions,
onError,
className,
style,
children,
}) => {
usePlaybackOptions({ fpsLimit, muted, screenRegions, onError });
useApplySource(source, outputSize);
useApplyLens(lensId, lensGroupId, lensLaunchData, lensReadyGuard, refreshTrigger);
if (children) {
// If custom children were provided, we wrap them to allow styling at the outer div.
return (
<div className={className} style={style}>
{children}
</div>
);
}
// Otherwise, we render the asked (or by default live) canvas.
return canvasType === "capture" ? (
<CaptureCanvas className={className} style={style} />
) : (
<LiveCanvas className={className} style={style} />
);
};