ugcinc-render
v1.5.3
Published
Unified rendering package for UGC Inc - shared types, components, and compositions for pixel-perfect client/server rendering
Maintainers
Readme
@ugcinc/remotion
Unified Remotion rendering package for UGC Inc. Provides shared types, components, and compositions for pixel-perfect client/server rendering using the same Chromium engine.
Why This Package?
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:
- Text positioned differently between preview and final render
- Font metrics varying between engines
- Antialiasing and rendering differences
This package solves that by using Remotion, which renders everything through Chromium. The same browser engine runs on both:
- Client preview:
@remotion/player- React component for preview - Server render:
@remotion/renderer- Headless Chromium for final output
Result: 100% pixel-perfect consistency between preview and render.
Installation
npm install @ugcinc/remotion remotion @remotion/player reactQuick Start
1. Image Editor Preview (Client)
import { Player } from '@remotion/player';
import { ImageEditorComposition, type ImageEditorConfig } from '@ugcinc/remotion';
function ImageEditorPreview({ config }: { config: ImageEditorConfig }) {
const sources = {
background: 'https://example.com/bg.jpg',
'image-1': 'https://example.com/image1.jpg',
};
return (
<Player
component={ImageEditorComposition}
inputProps={{ config, sources }}
durationInFrames={1}
fps={1}
compositionWidth={config.width}
compositionHeight={config.height}
style={{ width: '100%', height: 'auto' }}
/>
);
}2. Server-Side Rendering
import { bundle } from '@remotion/bundler';
import { renderStill } from '@remotion/renderer';
import { ImageEditorComposition } from '@ugcinc/remotion';
async function renderImage(config: ImageEditorConfig) {
const bundled = await bundle({
entryPoint: './remotion/index.ts',
});
const output = await renderStill({
composition: {
id: 'ImageEditor',
component: ImageEditorComposition,
width: config.width,
height: config.height,
fps: 1,
durationInFrames: 1,
defaultProps: { config, sources },
},
serveUrl: bundled,
output: 'output.png',
chromiumOptions: {
gl: 'angle', // GPU acceleration
},
});
return output;
}Types
All types are exported from the main package:
import type {
// Editor configs
ImageEditorConfig,
VideoEditorConfig,
EditorConfig,
Channel,
// Segments
TextSegment,
ImageSegment,
VideoSegment,
AudioSegment,
StaticSegment,
// Base types
TimeValue,
BorderRadiusConfig,
FitMode,
FontType,
FontWeight,
// Position types
RelativePositionConfigX,
RelativePositionConfigY,
// Crop types
DynamicCropConfig,
CropAxisConfig,
} from '@ugcinc/remotion';Components
Individual element components for building custom compositions:
import { TextElement, ImageElement, VideoElement } from '@ugcinc/remotion/components';
// Text with all styling options
<TextElement
segment={{
id: 'title',
type: 'text',
text: 'Hello World',
xOffset: 100,
yOffset: 100,
width: 800,
height: 200,
fontSize: 72,
fontType: 'tiktok',
fontWeight: 'bold',
color: '#ffffff',
strokeWidth: 4,
strokeColor: '#000000',
alignment: 'center',
verticalAlign: 'middle',
}}
/>
// Image with fit mode and border radius
<ImageElement
segment={{
id: 'photo',
type: 'image',
xOffset: 50,
yOffset: 50,
width: 400,
height: 400,
fit: 'cover',
borderRadius: 20,
rotation: 5,
}}
src="https://example.com/photo.jpg"
/>Compositions
Pre-built compositions for complete editor rendering:
ImageEditorComposition
Renders a static image from an ImageEditorConfig.
import { ImageEditorComposition } from '@ugcinc/remotion/compositions';
<ImageEditorComposition
config={imageEditorConfig}
sources={{
background: 'https://...',
'image-1': 'https://...',
}}
scale={2} // 2x resolution for retina
/>VideoEditorComposition
Renders a video from a VideoEditorConfig with timeline support.
import { VideoEditorComposition } from '@ugcinc/remotion/compositions';
<VideoEditorComposition
config={videoEditorConfig}
sources={{
'video-1': 'https://...',
'audio-1': 'https://...',
}}
textContent={{
'text-1': 'Dynamic text content',
}}
/>Utilities
Helper functions for font loading and calculations:
import {
preloadFonts,
areFontsLoaded,
getFontFamily,
calculateFitDimensions,
wrapText,
getBorderRadii,
} from '@ugcinc/remotion/utils';Hooks
React hooks for common operations:
import { useFontsLoaded, useImageLoader, useImagePreloader } from '@ugcinc/remotion/hooks';
function MyComponent() {
const fontsReady = useFontsLoaded();
const { loaded, images } = useImagePreloader(sources);
if (!fontsReady || !loaded) {
return <div>Loading...</div>;
}
return <ImageEditorComposition config={config} sources={sources} />;
}GPU Acceleration
When rendering on a server with GPU, use the --gl=angle flag for faster frame rendering:
await renderMedia({
// ...
chromiumOptions: {
gl: 'angle', // Enable GPU acceleration
},
});License
MIT
