@evatrilvideo/ai-video-package
v1.0.23
Published
@evatrilvideo/ai-video-package
Readme
@evatrilvideo/ai-video-package
A React + Remotion package that contains reusable invitation video frames, visual elements, transitions, font registration, video-data mapping, and the main Remotion composition.
This README documents only the functionality and structure contained inside this package.
Table of Contents
Overview
Package Information
Technology
Package Structure
Main Flow
Main Files
VideoComposition
Frame Registry
Frames
Elements and Animations
Transitions
Video Data Mapper
Font Registration
Image Preloading
Preview Assets
Remotion Root
Adding a New Frame
Adding a New Element or Animation
Adding a New Transition
Adding a New Data Field
Frame Duration
Usage Flow
Development Notes
Overview
@evatrilvideo/ai-video-package is a reusable video-template package built with React and Remotion.
The package contains:
Reusable video frame components
Reusable visual elements and animations
Reusable transition components
A centralized frame registry
Backend-data normalization through mapVideoData()
Font registration and loading
Image preloading helpers
Preview asset utilities
The main Remotion composition
The package is designed so that a video can be assembled from a list of registered frame names and a videoData object.
Package Information
Current package configuration:
{ "name": "@evatrilvideo/ai-video-package", "version": "1.0.10", "type": "module", "main": "src/remotionRoot.jsx", "exports": { ".": "./src/remotionRoot.jsx" } }
Peer Dependencies
The package expects:
React >= 18 React DOM >= 18 Remotion ^4.0.0
The package entry point is:
src/remotionRoot.jsx
Technology
Technology Purpose
React Video UI and reusable components
Remotion Programmatic video composition and rendering
JavaScript / JSX Package implementation
FontFace API Dynamic font loading
Remotion Sequence Frame timeline sequencing
Remotion delayRender / Asset and font loading control continueRender
Remotion prefetch Preview asset preloading
Package Structure
video-templates/ │ ├── package.json │ └── src/ │ ├── compositions.jsx ├── frameRegistry.js ├── videoDataMapper.js ├── remotionRoot.jsx │ ├── fonts/ │ ├── index.js │ └── registerFonts.js │ └── Invitations/ │ ├── Elements/ │ ├── reusable animations │ ├── visual effects │ └── transitions │ ├── Frames/ │ └── video frame components │ ├── hooks/ │ ├── useImagePreload.js │ └── usePreloadImages.js │ └── utils/ └── previewAssets.js
Main Flow
The internal package flow is:
videoData + frame list │ ▼ VideoComposition │ ▼ mapVideoData() │ ▼ normalized data │ ▼ frameRegistry │ ▼ Frame Component │ ├── Elements / Animations │ └── Transitions │ ▼ Remotion Sequence │ ▼ Video Render
The package does not itself define an external application, database, admin panel, or AI-generation service. Those systems can provide data or media to the package, but they are outside this package.
Main Files
src/remotionRoot.jsx
The main Remotion entry point.
Responsibilities:
Registers the Remotion root
Creates the Video composition
Loads fonts before rendering continues
Defines video dimensions
Defines FPS
Defines default props
src/compositions.jsx
Contains VideoComposition.
Responsibilities:
Receives frames
Receives videoData
Normalizes videoData
Finds each frame in frameRegistry
Calculates each frame's starting position
Creates Remotion components
Passes normalized data to each frame
src/frameRegistry.js
Contains the mapping between frame IDs and frame components.
Each registry entry contains:
{ component: FrameComponent, duration: 150 }
The current registry contains the package's registered frame components.
src/videoDataMapper.js
Contains:
mapVideoData(videoData)
It converts the incoming video data into a normalized object that can be consumed by different frame components.
The mapper also preserves the original:
eventData occasion extraData
and spreads the original videoData into the returned object.
VideoComposition
VideoComposition is the main internal composition component.
export const VideoComposition = ({ frames = [], videoData = {} }) => { const normalizedData = mapVideoData(videoData);
// ... };
Processing Flow
For every frame name:
frame name ↓ frameRegistry[frameName] ↓ frame component ↓ frame duration ↓ Remotion Sequence
The component uses:
<Sequence
key={${frameName}-${index}}
from={currentStart}
durationInFrames={duration}
<FrameComponent {...normalizedData} />
This means every registered frame receives the normalized video data as props.
Frame Registry
File:
src/frameRegistry.js
The registry connects a frame name with its component and duration.
Example:
F01042026_01: { component: F01042026_01, duration: 150 }
The frame name used in the frames array must match the registry key exactly.
Example:
const frames = [ "F01042026_01", "F01042026_02", "F01042026_03" ];
If a frame name is not found:
const frameConfig = frameRegistry[frameName];
if (!frameConfig) return null;
the frame is skipped.
Frames
Frame components are located in:
src/Invitations/Frames/
The package contains a large collection of registered frames for different invitation designs and occasions.
Frame names follow patterns such as:
F01042026_01 F01042026_02 F01042026_03
F30072026_01 F30072026_02
F17062026_01 F17062026_02
The exact frame naming convention is already established by the package's existing files and registry.
A frame is responsible for its own visual composition.
A frame can contain:
Backgrounds
Text
Images
Decorative elements
Animations
Other reusable components
Elements and Animations
Reusable visual components are located in:
src/Invitations/Elements/
The package contains elements such as:
BalloonPhotoReveal28072026.jsx BirdsFlyAnimation14042026.jsx BlowingLeaves28012026.jsx Butterflies20012026.jsx CandleGlowReveal01072026.jsx FallingPetals27062026.jsx FloatingBalloons26022026.jsx FlowersSide20012026.jsx OpeningGate20012026.jsx PhotoOrbitReveal08072026.jsx SmokeEffect14042026.jsx TextAnimation16032026.jsx WalkingSequenceAnimation27032026.jsx WordReveal28012026.jsx
These components are reusable building blocks for frames.
For example:
Frame ├── Text ├── Image ├── FallingPetals ├── Butterflies └── Other Elements
This keeps common visual effects separate from individual frame components.
Transitions
Transitions are also stored in:
src/Invitations/Elements/
The package uses the T_ naming pattern for transition components.
Examples:
T_CornerFlip05022026.jsx T_Curtain_LeftRight20012026.jsx T_Diagonal12022026.jsx T_FadeTransition.jsx T_FlowerCurtain16022026.jsx T_HoldSlide03022026.jsx T_InkSmoke20012026.jsx T_MultiDirectionPageCurl11032026.jsx T_OpenPageReveal17032026.jsx T_PageCurl10032026.jsx T_PageFlip28012026.jsx T_ParticleSwarmTransition03072026.jsx T_Spread13032026.jsx T_WallPainting06072026.jsx T_Zoom0503202601.jsx T_ZoomFocus27032026.jsx
A transition is a reusable visual effect intended to control movement or transformation between visual states.
The transition components are part of the package itself; their configuration or selection can be handled by an external application.
Video Data Mapper
File:
src/videoDataMapper.js
The main function is:
mapVideoData(videoData)
The mapper reads:
videoData ├── eventData │ └── occasion │ └── extraData
It supports multiple naming styles for several fields.
For example:
videoData?.eventData videoData?.event_data videoData?.eventdata
are accepted for the event data object.
Similarly:
eventData?.occasion_data eventData?.occasionData eventData?.occasiondata
are accepted for occasion data.
And:
videoData?.extraData videoData?.extra_data videoData?.extradata
are accepted for extra data.
Normalized Data
The mapper creates normalized properties for the frames.
Wedding Data
firstName secondName
firstPhoto secondPhoto
firstSideNote secondSideNote
The wedding fields are mapped from bride/groom information.
Birthday / Haldi / Mehendi / Religious Function
name invitedBy celebrationAge photo
Engagement
brideName groomName
bridePhoto groomPhoto
Baby Shower
name1 name2
photo1 photo2
specialannouncementmessage
Naming Ceremony
gender
Reception / Festival / Walima / Bachelor Party
host
Thread Ceremony / Annaprasanna
parentsName
House Warming
specialNote
Corporate Event
eventTitle companyName eventType eventDescription
Anniversary
anniversaryYear
Temple Anniversary
templeAnniversary organizationName
Death Anniversary
deathAnniversary
Funeral / Antim Sanskar
birthAndPassingDates dashakarmaDate
Common Data
The mapper also provides:
welcomeMessage invitationMessage familyMember
venueName venueAddress occasionDate eventDateTime
Original Data
The mapper keeps the original nested objects:
eventData occasion extraData
It also includes the original videoData properties:
return { // normalized fields
eventData, occasion, extraData,
...videoData, };
This allows a frame to use normalized properties while still having access to the original data when required.
Font Registration
Font files and font-loading logic are located in:
src/fonts/
The package exports:
export { registerFonts } from "./registerFonts";
The main implementation is:
src/fonts/registerFonts.js
The package currently registers these font families:
Great Vibes Dancing Script Italic Playfair Display Noto Sans Devanagari Noto Naskh Arabic Noto Serif Oriya Noto Serif Kannada Noto Sans Gurmukhi
The fonts are loaded through the browser FontFace API.
Font Loading Flow
The root component uses:
delayRender() ↓ registerFonts() ↓ FontFace.load() ↓ document.fonts.add() ↓ document.fonts.ready ↓ continueRender()
This prevents Remotion from continuing while the font-loading process is still running.
Font loading uses timeouts so that one unavailable font does not keep the rendering process waiting indefinitely.
Current timeout values:
Font loading timeout: 15000 ms document.fonts.ready: 5000 ms
Image Preloading
The package contains:
src/Invitations/hooks/useImagePreload.js
The hook:
useImagePreload(src)
is designed to preload and decode an image before continuing Remotion rendering.
It uses:
delayRender() continueRender()
and loads images with:
img.crossOrigin = "anonymous";
If image loading fails, the hook logs a warning and continues rendering instead of leaving Remotion permanently blocked.
Preview Assets
Preview asset utilities are located at:
src/Invitations/utils/previewAssets.js
The package defines:
S3_ELEMENTS_BASE
for the package's remote element assets.
The utility provides:
isMobilePreviewRuntime()
which checks whether the current browser viewport is a mobile-sized preview.
It also provides:
usePreviewAssets(imageSources)
for preview asset preparation.
Preview Asset Flow
The preview asset utility:
Image Sources ↓ Remove empty values ↓ Remove duplicates ↓ Remotion prefetch() ↓ Blob URL ↓ Image loading ↓ Image decoding ↓ Decoded image cache ↓ continueRender()
The decoded image cache is stored on:
window.__decodedImagesCache
This helps avoid repeatedly decoding the same preview image.
usePreloadImages
File:
src/Invitations/hooks/usePreloadImages.js
This hook is a small wrapper around:
usePreviewAssets(imageSources)
Usage:
const { assetsReady, sources } = usePreloadImages(imageSources);
It allows frame components to prepare their preview assets through the shared preview utility.
Remotion Root
File:
src/remotionRoot.jsx
The package defines the Remotion composition:
<Composition id="Video" component={VideoComposition} durationInFrames={10000} fps={30} width={1080} height={1920} defaultProps={{ frames: [], videoData: {}, }} />
Current composition settings:
Property Value
Composition ID Video Width 1080 Height 1920 FPS 30 Default duration 10000 frames
The video format is therefore:
1080 × 1920 9:16 portrait 30 FPS
The file finishes by registering the root:
registerRoot(Root);
Adding a New Frame
To add a new frame:
- Create the frame component
Create a file inside:
src/Invitations/Frames/
Example:
F25092026_01.jsx
Example component:
export const F25092026_01 = ({ firstName, secondName, }) => { return ( <div style={{ width: 1080, height: 1920, }} > {firstName} {secondName} ); };
- Import the frame into frameRegistry.js
import { F25092026_01 } from "./Invitations/Frames/F25092026_01";
- Register the frame
F25092026_01: { component: F25092026_01, duration: 150 },
- Use the frame name
The frame can then be supplied through the frames array:
[ "F25092026_01" ]
The name must exactly match the registry key.
Adding a New Element or Animation
Create the component inside:
src/Invitations/Elements/
Example:
MyAnimation.jsx
Example:
export const MyAnimation = ({ children }) => { return ( <> {children} </> ); };
Then import it into the frame where it is needed:
import { MyAnimation } from "../Elements/MyAnimation";
Use it:
Reusable visual logic should generally live in Elements/ instead of being duplicated across multiple frames.
Adding a New Transition
Create the transition inside:
src/Invitations/Elements/
Follow the existing T_ naming convention.
Example:
T_MyTransition.jsx
Then implement the transition component and import it into the frame or composition where it is required.
Example:
export const T_MyTransition = ({ children }) => { return ( <> {children} </> ); };
Adding a New Data Field
When a new frame requires a data field that is not currently normalized, add the mapping to:
src/videoDataMapper.js
For example, if the incoming data contains:
extraData?.couple_tagline
you can expose it as:
coupleTagline: extraData?.couple_tagline || extraData?.coupleTagline || extraData?.coupletagline || "",
The frame can then use:
Keep backend-to-frame field normalization in videoDataMapper.js rather than repeating it inside individual frames.
Frame Duration
Frame durations in the registry are measured in frames, not seconds.
The package runs at:
30 FPS
Therefore:
30 frames = 1 second 60 frames = 2 seconds 90 frames = 3 seconds 120 frames = 4 seconds 150 frames = 5 seconds 180 frames = 6 seconds 210 frames = 7 seconds 300 frames = 10 seconds
Formula:
seconds = frames / 30
For example:
150 / 30 = 5 seconds
Frame Timeline
VideoComposition builds the timeline sequentially.
For example:
[ "F01042026_01", "F01042026_02", "F01042026_03" ]
with durations:
F01042026_01 → 150 frames F01042026_02 → 180 frames F01042026_03 → 150 frames
creates:
0 │ ├──────── Frame 1 ────────┤ 0 149 │ ├──────── Frame 2 ─────────┤ 150 329 │ ├──── Frame 3 ────┤ 330 479
The next frame starts where the previous frame ends.
Usage Flow
The package expects the consuming Remotion environment to provide:
{ frames: [ "F01042026_01", "F01042026_02", "F01042026_03" ],
videoData: { // event data } }
The internal processing is:
frames │ ▼ VideoComposition │ ├── mapVideoData(videoData) │ ▼ normalizedData │ ▼ frames.map(...) │ ▼ frameRegistry[frameName] │ ├── component └── duration │ ▼ │ ▼ <FrameComponent {...normalizedData} />
Development Notes
Keep frame IDs consistent
The same frame ID must be used consistently between:
Frame file ↓ Import ↓ Registry key ↓ frames array
For example:
F01042026_01
must match exactly.
Keep reusable visual logic in Elements
If an animation or visual effect is used by multiple frames, place it in:
src/Invitations/Elements/
instead of duplicating the implementation.
Keep data normalization in one place
Use:
src/videoDataMapper.js
for converting incoming data into frame-friendly props.
This keeps frame components simpler.
Keep frame registration centralized
All renderable frames should be registered in:
src/frameRegistry.js
so that VideoComposition can resolve them by name.
Keep loading logic safe
When adding assets that must be loaded before rendering, use the existing Remotion loading pattern:
delayRender() ↓ load asset ↓ continueRender()
and make sure failures cannot leave the composition permanently waiting.
Internal Package Summary
The package can be understood through these core layers:
┌──────────────────────────────────────────┐ │ Remotion Root │ │ remotionRoot.jsx │ └───────────────────┬──────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ Video Composition │ │ compositions.jsx │ └───────────────────┬──────────────────────┘ │ ┌─────────┴─────────┐ ▼ ▼ ┌─────────────────┐ ┌───────────────────┐ │ Video Data │ │ Frame Registry │ │ Mapper │ │ frameRegistry.js │ └────────┬────────┘ └─────────┬─────────┘ │ │ │ ▼ │ ┌─────────────────┐ │ │ Frame Components│ │ │ Frames/ │ │ └────────┬────────┘ │ │ │ ▼ │ ┌─────────────────┐ │ │ Elements │ │ │ Animations │ │ │ Transitions │ │ └─────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ Normalized Props │ └──────────────────────────────────────────┘
Package Responsibility
This package is responsible for:
✓ Remotion composition ✓ Frame components ✓ Frame registry ✓ Frame sequencing ✓ Video-data normalization ✓ Reusable visual elements ✓ Animations ✓ Transitions ✓ Font registration ✓ Image preloading ✓ Preview asset preparation
External systems may provide the input data or media, but those systems are not part of this package.
End
@evatrilvideo/ai-video-package provides the reusable React + Remotion building blocks required to compose invitation videos from registered frames, normalized data, reusable elements, transitions, and assets.
Video Effects System
@evatrilvideo/ai-video-package supports a dynamic, registry-driven video effect system. It allows backend services and admin panels to inject visual overlays (such as falling petals or flying butterflies) and camera transitions (such as zoom-in and zoom-out) directly into compositions via input props without modifying template code.
1. Architecture & Flow
Effects in the package are categorized into two types:
| Effect Type | Description | Rendering Mechanism | Examples |
| :--- | :--- | :--- | :--- |
| wrapper | Camera / Zoom Movements: Applies continuous scale/transform animations to the underlying video frames. | Wraps <AbsoluteFill> frames via reduce | ZoomIn27092026, ZoomOut27092026 |
| component | Visual Overlays: Floating transparent layers rendered on top of the video frames. | Rendered as foreground siblings via <EffectRenderer> | FallingPetals27062026, Butterflies20012026 |
Visual Pipeline:
Backend / Admin Payload
│
▼
inputProps: {
frames: [...],
effects: [...],
videoData: {...}
}
│
▼
VideoComposition
│
┌──────────────┴──────────────┐
│ │
▼ ▼
wrapperEffects overlayEffects(type === "wrapper") (type === "component") │ │ ▼ ▼ Wraps Frames via reduce EffectRenderer <ZoomIn27092026 {...props}> │ Frame 1 ▼ Frame 2 effectRegistry │ ▼ Foreground Overlays
2. Core Files & Responsibilities
1. src/effectRegistry.js
The central registry linking effect keys with their React components and execution types (wrapper or component).
import { Butterflies20012026 } from "./Invitations/Elements/Butterflies20012026";
import { FallingPetals27062026 } from "./Invitations/Elements/FallingPetals27062026";
import { ZoomIn27092026 } from "./Invitations/Elements/ZoomIn27092026";
import { ZoomOut27092026 } from "./Invitations/Elements/ZoomOut27092026";
export const effectRegistry = {
FallingPetals27062026: {
type: "component",
component: FallingPetals27062026,
},
Butterflies20012026: {
type: "component",
component: Butterflies20012026,
},
ZoomIn27092026: {
type: "wrapper",
component: ZoomIn27092026,
},
ZoomOut27092026: {
type: "wrapper",
component: ZoomOut27092026,
},
};
2. src/effectRenderer.jsx
Responsible for mounting overlay (component) effects. It gracefully verifies that the requested effectKey exists in the registry.
3. src/compositions.jsx
The master composition orchestrator:
Sequences static frames.
Wraps the frames inside active wrapper effects (e.g. ZoomIn, ZoomOut).
Renders component overlays (e.g. FallingPetals, Butterflies) on top.
3. Registered Effects Reference
A. Camera / Zoom Effects (type: "wrapper")
1. ZoomIn27092026
Smoothly scales into the video scene over a specified frame window.
Registry Key: "ZoomIn27092026"
Props (props object):
startFrame (number, default: 0): Video frame when zooming starts.
endFrame (number, default: durationInFrames): Video frame when zoom finishes.
startScale (number, default: 1.0): Starting scale factor (1.0 = 100%).
endScale (number, default: 1.20): Target scale factor (1.20 = 120%).
duration (number, optional): Total animation duration in frames.
isMobilePreview (boolean, default: false): Disables hardware transform acceleration for mobile viewports.
2. ZoomOut27092026
Smoothly pulls back from an enlarged scale to a normal or smaller scale.
Registry Key: "ZoomOut27092026"
Props (props object):
startFrame (number, default: 0): Video frame when zoom-out begins.
endFrame (number, default: durationInFrames): Video frame when zoom-out reaches target scale.
startScale (number, default: 1.20): Starting enlarged scale factor.
endScale (number, default: 1.0): Target normal scale factor.
duration (number, optional): Total animation duration in frames.
isMobilePreview (boolean, default: false): Disables hardware transform acceleration for mobile viewports.
B. Visual Overlay Effects (type: "component")
3. FallingPetals27062026
Renders realistic floating and swaying flower petals over the video.
Registry Key: "FallingPetals27062026"
Props (props object):
count (number, default: 30): Number of petals generated simultaneously.
color (string, default: "#d94b5b"): Color tint applied to the petals.
petalImage (string, optional): Custom image URL for petal texture.
speed (number, default: 0.08): Downward falling velocity.
sway (number, default: 15): Amplitude of horizontal swaying.
size (number, default: 2.5): Scale factor of petal size.
startFrame (number, default: 0): Timeline frame when petals start falling.
endFrame (number, default: end of composition): Timeline frame when petals fade out.
4. Butterflies20012026
Renders flying animated butterflies with natural flapping and path easing.
Registry Key: "Butterflies20012026"
Props (props object):
src (string, Required): Public URL of the butterfly asset (e.g. S3 WebP image).
startX (number, default: 400): Starting X coordinate (in 1080 canvas pixels).
startY (number, default: height + 120): Starting Y coordinate.
endX (number, optional): Ending X coordinate.
endY (number, default: -250): Ending Y coordinate.
duration (number, default: 8): Flight duration in seconds.
size (number, default: 160): Butterfly dimension in pixels.
startFrame (number, default: 0): Timeline frame when flight starts.
4. Backend / API JSON Payload Examples
Example 1: Full Cinematic Setup (Zoom In + Falling Petals)
json
{
"frames": [
"F20012026_01",
"F20012026_02",
"F20012026_03"
],
"effects": [
{
"effect_key": "ZoomIn27092026",
"props": {
"startFrame": 0,
"endFrame": 300,
"startScale": 1.0,
"endScale": 1.15
}
},
{
"effect_key": "FallingPetals27062026",
"props": {
"count": 25,
"color": "#e05263"
}
}
],
"videoData": {
"eventData": {
"bride_name": "Pooja",
"groom_name": "Rahul"
}
}
}
Example 2: Flying Butterfly Overlay Only
json
{
"frames": ["F01042026_01"],
"effects": [
{
"effect_key": "Butterflies20012026",
"props": {
"src": "https://storage.evatril.com/video-themes/elements/20012026-butterfly.webp",
"size": 150,
"duration": 9
}
}
],
"videoData": {}
}
Example 3: Clean Video (No Effects)
json
{
"frames": ["F01042026_01", "F01042026_02"],
"effects": [],
"videoData": {}
}
5. Adding a New Effect in the Future
A. To add a new Visual Overlay (e.g. Snow, Sparkles, Fireflies):
Create your component in src/Invitations/Elements/MyOverlayEffect.jsx.
Ensure it renders inside <AbsoluteFill style={{ pointerEvents: "none" }}>.
Register in src/effectRegistry.js:
javascript
import { MyOverlayEffect } from "./Invitations/Elements/MyOverlayEffect";
export const effectRegistry = {
// ...
MyOverlayEffect: {
type: "component",
component: MyOverlayEffect,
},
};
B. To add a new Camera / Wrapper Effect (e.g. Pan, Tilt, Camera Shake):
Create your component in src/Invitations/Elements/MyCameraEffect.jsx.
Ensure it accepts { children } and wraps them:
jsx
export const MyCameraEffect = ({ children, ...props }) => {
// calculate animation values with useCurrentFrame()
return (
<AbsoluteFill style={{ transform: `...` }}>
{children}
</AbsoluteFill>
);
};
Register in src/effectRegistry.js with type: "wrapper":
javascript
MyCameraEffect: {
type: "wrapper",
component: MyCameraEffect,
},
6. Admin Panel Implementation Guidelines
When managing effects in the Admin Panel or Template Creator:
Camera Animation Selector (Single Select):
Provide dropdown options:
None (no zoom)
Subtle Zoom In (1.0x -> 1.15x)
Deep Zoom In (1.0x -> 1.30x)
Zoom Out (1.20x -> 1.0x)
Stores the selected key and injects it into the effects payload.
Atmosphere / Foreground Effects (Multi-Select Checkboxes):
[x] Falling Rose Petals (FallingPetals27062026)
[x] Flying Butterflies (Butterflies20012026)
Custom Parameters (Optional Sliders):
Density/Count slider for Petals (range: 10 – 50).
Color picker for Petals.
S3 URL selector for custom butterfly assets.
12:16 PM