ugcinc-render 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +257 -0
- package/dist/index.d.mts +1200 -0
- package/dist/index.d.ts +1200 -0
- package/dist/index.js +1487 -0
- package/dist/index.mjs +1425 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# @ugcinc/remotion
|
|
2
|
+
|
|
3
|
+
Unified Remotion rendering package for UGC Inc. Provides shared types, components, and compositions for pixel-perfect client/server rendering using the same Chromium engine.
|
|
4
|
+
|
|
5
|
+
## Why This Package?
|
|
6
|
+
|
|
7
|
+
Traditional canvas-based rendering has a fundamental problem: different canvas implementations (browser Canvas API vs server-side libraries like skia-canvas) produce subtly different results. This leads to:
|
|
8
|
+
|
|
9
|
+
- Text positioned differently between preview and final render
|
|
10
|
+
- Font metrics varying between engines
|
|
11
|
+
- Antialiasing and rendering differences
|
|
12
|
+
|
|
13
|
+
**This package solves that by using Remotion**, which renders everything through Chromium. The same browser engine runs on both:
|
|
14
|
+
- **Client preview**: `@remotion/player` - React component for preview
|
|
15
|
+
- **Server render**: `@remotion/renderer` - Headless Chromium for final output
|
|
16
|
+
|
|
17
|
+
Result: **100% pixel-perfect consistency** between preview and render.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @ugcinc/remotion remotion @remotion/player react
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### 1. Image Editor Preview (Client)
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { Player } from '@remotion/player';
|
|
31
|
+
import { ImageEditorComposition, type ImageEditorConfig } from '@ugcinc/remotion';
|
|
32
|
+
|
|
33
|
+
function ImageEditorPreview({ config }: { config: ImageEditorConfig }) {
|
|
34
|
+
const sources = {
|
|
35
|
+
background: 'https://example.com/bg.jpg',
|
|
36
|
+
'image-1': 'https://example.com/image1.jpg',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Player
|
|
41
|
+
component={ImageEditorComposition}
|
|
42
|
+
inputProps={{ config, sources }}
|
|
43
|
+
durationInFrames={1}
|
|
44
|
+
fps={1}
|
|
45
|
+
compositionWidth={config.width}
|
|
46
|
+
compositionHeight={config.height}
|
|
47
|
+
style={{ width: '100%', height: 'auto' }}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 2. Server-Side Rendering
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
import { bundle } from '@remotion/bundler';
|
|
57
|
+
import { renderStill } from '@remotion/renderer';
|
|
58
|
+
import { ImageEditorComposition } from '@ugcinc/remotion';
|
|
59
|
+
|
|
60
|
+
async function renderImage(config: ImageEditorConfig) {
|
|
61
|
+
const bundled = await bundle({
|
|
62
|
+
entryPoint: './remotion/index.ts',
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const output = await renderStill({
|
|
66
|
+
composition: {
|
|
67
|
+
id: 'ImageEditor',
|
|
68
|
+
component: ImageEditorComposition,
|
|
69
|
+
width: config.width,
|
|
70
|
+
height: config.height,
|
|
71
|
+
fps: 1,
|
|
72
|
+
durationInFrames: 1,
|
|
73
|
+
defaultProps: { config, sources },
|
|
74
|
+
},
|
|
75
|
+
serveUrl: bundled,
|
|
76
|
+
output: 'output.png',
|
|
77
|
+
chromiumOptions: {
|
|
78
|
+
gl: 'angle', // GPU acceleration
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return output;
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Types
|
|
87
|
+
|
|
88
|
+
All types are exported from the main package:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import type {
|
|
92
|
+
// Editor configs
|
|
93
|
+
ImageEditorConfig,
|
|
94
|
+
VideoEditorConfig,
|
|
95
|
+
EditorConfig,
|
|
96
|
+
Channel,
|
|
97
|
+
|
|
98
|
+
// Segments
|
|
99
|
+
TextSegment,
|
|
100
|
+
ImageSegment,
|
|
101
|
+
VideoSegment,
|
|
102
|
+
AudioSegment,
|
|
103
|
+
StaticSegment,
|
|
104
|
+
|
|
105
|
+
// Base types
|
|
106
|
+
TimeValue,
|
|
107
|
+
BorderRadiusConfig,
|
|
108
|
+
FitMode,
|
|
109
|
+
FontType,
|
|
110
|
+
FontWeight,
|
|
111
|
+
|
|
112
|
+
// Position types
|
|
113
|
+
RelativePositionConfigX,
|
|
114
|
+
RelativePositionConfigY,
|
|
115
|
+
|
|
116
|
+
// Crop types
|
|
117
|
+
DynamicCropConfig,
|
|
118
|
+
CropAxisConfig,
|
|
119
|
+
} from '@ugcinc/remotion';
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Components
|
|
123
|
+
|
|
124
|
+
Individual element components for building custom compositions:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import { TextElement, ImageElement, VideoElement } from '@ugcinc/remotion/components';
|
|
128
|
+
|
|
129
|
+
// Text with all styling options
|
|
130
|
+
<TextElement
|
|
131
|
+
segment={{
|
|
132
|
+
id: 'title',
|
|
133
|
+
type: 'text',
|
|
134
|
+
text: 'Hello World',
|
|
135
|
+
xOffset: 100,
|
|
136
|
+
yOffset: 100,
|
|
137
|
+
width: 800,
|
|
138
|
+
height: 200,
|
|
139
|
+
fontSize: 72,
|
|
140
|
+
fontType: 'tiktok',
|
|
141
|
+
fontWeight: 'bold',
|
|
142
|
+
color: '#ffffff',
|
|
143
|
+
strokeWidth: 4,
|
|
144
|
+
strokeColor: '#000000',
|
|
145
|
+
alignment: 'center',
|
|
146
|
+
verticalAlign: 'middle',
|
|
147
|
+
}}
|
|
148
|
+
/>
|
|
149
|
+
|
|
150
|
+
// Image with fit mode and border radius
|
|
151
|
+
<ImageElement
|
|
152
|
+
segment={{
|
|
153
|
+
id: 'photo',
|
|
154
|
+
type: 'image',
|
|
155
|
+
xOffset: 50,
|
|
156
|
+
yOffset: 50,
|
|
157
|
+
width: 400,
|
|
158
|
+
height: 400,
|
|
159
|
+
fit: 'cover',
|
|
160
|
+
borderRadius: 20,
|
|
161
|
+
rotation: 5,
|
|
162
|
+
}}
|
|
163
|
+
src="https://example.com/photo.jpg"
|
|
164
|
+
/>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Compositions
|
|
168
|
+
|
|
169
|
+
Pre-built compositions for complete editor rendering:
|
|
170
|
+
|
|
171
|
+
### ImageEditorComposition
|
|
172
|
+
|
|
173
|
+
Renders a static image from an ImageEditorConfig.
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
import { ImageEditorComposition } from '@ugcinc/remotion/compositions';
|
|
177
|
+
|
|
178
|
+
<ImageEditorComposition
|
|
179
|
+
config={imageEditorConfig}
|
|
180
|
+
sources={{
|
|
181
|
+
background: 'https://...',
|
|
182
|
+
'image-1': 'https://...',
|
|
183
|
+
}}
|
|
184
|
+
scale={2} // 2x resolution for retina
|
|
185
|
+
/>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### VideoEditorComposition
|
|
189
|
+
|
|
190
|
+
Renders a video from a VideoEditorConfig with timeline support.
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { VideoEditorComposition } from '@ugcinc/remotion/compositions';
|
|
194
|
+
|
|
195
|
+
<VideoEditorComposition
|
|
196
|
+
config={videoEditorConfig}
|
|
197
|
+
sources={{
|
|
198
|
+
'video-1': 'https://...',
|
|
199
|
+
'audio-1': 'https://...',
|
|
200
|
+
}}
|
|
201
|
+
textContent={{
|
|
202
|
+
'text-1': 'Dynamic text content',
|
|
203
|
+
}}
|
|
204
|
+
/>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Utilities
|
|
208
|
+
|
|
209
|
+
Helper functions for font loading and calculations:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
import {
|
|
213
|
+
preloadFonts,
|
|
214
|
+
areFontsLoaded,
|
|
215
|
+
getFontFamily,
|
|
216
|
+
calculateFitDimensions,
|
|
217
|
+
wrapText,
|
|
218
|
+
getBorderRadii,
|
|
219
|
+
} from '@ugcinc/remotion/utils';
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Hooks
|
|
223
|
+
|
|
224
|
+
React hooks for common operations:
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
import { useFontsLoaded, useImageLoader, useImagePreloader } from '@ugcinc/remotion/hooks';
|
|
228
|
+
|
|
229
|
+
function MyComponent() {
|
|
230
|
+
const fontsReady = useFontsLoaded();
|
|
231
|
+
const { loaded, images } = useImagePreloader(sources);
|
|
232
|
+
|
|
233
|
+
if (!fontsReady || !loaded) {
|
|
234
|
+
return <div>Loading...</div>;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return <ImageEditorComposition config={config} sources={sources} />;
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## GPU Acceleration
|
|
242
|
+
|
|
243
|
+
When rendering on a server with GPU, use the `--gl=angle` flag for faster frame rendering:
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
await renderMedia({
|
|
247
|
+
// ...
|
|
248
|
+
chromiumOptions: {
|
|
249
|
+
gl: 'angle', // Enable GPU acceleration
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## License
|
|
255
|
+
|
|
256
|
+
MIT
|
|
257
|
+
|