Files
remotion_service/.agents/skills/remotion-best-practices/SKILL.md
T
Daniil 6e82165566
compute / deploy (push) Has been cancelled
chore: agentic upgrade
2026-05-17 02:12:18 +03:00

158 lines
8.3 KiB
Markdown

---
name: remotion-best-practices
description: Use when writing, reviewing, or refactoring Remotion code in this repository, including compositions, dynamic metadata, @remotion/media video/audio, CLI or renderer rendering, Docker/Chromium settings, queue progress/cancellation, or render performance.
---
# Remotion Best Practices
## Overview
Apply current Remotion guidance to this Bun rendering service without losing the
project-specific details that make renders reliable: dynamic metadata, S3 input
URLs, BullMQ progress, Docker Chromium, and cleanup of generated artifacts.
## Workflow
1. Fetch current Remotion docs first with Context7. This repo pins Remotion
packages at `4.0.435`, so compare docs version badges against that version
before using newer API options.
2. Identify the layer being changed:
- Composition UI: `src/components/Composition.tsx`, `src/components/Captions.tsx`
- Composition registration and metadata: `src/components/Root.tsx`,
`src/hooks/useVideoMeta.ts`
- Render orchestration: `server/services/render_video.ts`,
`server/services/render_queue.ts`
- Runtime config: `remotion.config.ts`, `Dockerfile`, `.env.example`,
`server/config.ts`
3. Keep render behavior deterministic. A frame should be a pure function of
props, frame number, and explicitly loaded assets.
4. Verify with `bun run lint` and a focused smoke test: Remotion Studio,
`bun run render` with valid props, or the API/queue path when server behavior
changed.
## Project Map
- Runtime: Bun, React 19, Remotion `4.0.435`.
- Entry point: `src/index.ts` registers `RemotionRoot`.
- Main composition: `CaptionedVideo` in `src/components/Root.tsx`.
- Metadata: `getVideoMeta()` uses `calculateMetadata` plus
`@remotion/media-parser` `parseMedia()` to set duration, dimensions, and fps
from the input video.
- Media rendering: `CaptionsComposition` uses `@remotion/media` `Video`, with
captions overlaid in `AbsoluteFill`.
- Server rendering: `renderCaptionedVideo()` writes props JSON into `out/`,
runs `./node_modules/.bin/remotion render src/index.ts ... --props`, parses
CLI progress output, and deletes the props file in `finally`.
- Queue wrapper: BullMQ controls job concurrency through
`MAX_CONCURRENT_RENDERS`, uploads finished files to S3, sends webhooks, and
stores cancellation flags in Redis.
- Docker: Chromium and FFmpeg are installed in the image; Remotion browser
download is skipped; sandboxing is disabled through env.
## Composition Rules
- Animate with `useCurrentFrame()`, `useVideoConfig()`, `interpolate()`,
`spring()`, and `Sequence`. Do not use CSS animations, CSS transitions,
timers, or wall-clock time for render-critical motion.
- Keep props JSON-serializable. When adding composition input fields, update
`src/types/captions_composition.d.ts`, `src/components/Root.tsx`
`defaultProps`, and the server-side props object together.
- Avoid fetches or expensive async work inside frame-rendering components.
Prefer server preprocessing or `calculateMetadata()` for data that changes
duration, dimensions, fps, or props.
- Use `delayRender()` only for assets that must block a frame, such as dynamic
CSS/font loading. In new code prefer `useDelayRender()` where practical, and
always clear or cancel every handle on success and failure.
- Use `AbsoluteFill` for full-frame layers and `Sequence` for frame-based
timing. Convert seconds with the active `fps`, not a hardcoded 30 unless the
composition contract really is fixed at 30 fps.
## Metadata
- Keep dynamic duration and dimensions in `calculateMetadata`, not component
`useEffect()`. In Remotion v4, `useEffect()` can run again for render workers
and multiply API calls.
- For this repo, preserve the existing `parseMedia()` path unless deliberately
upgrading. Current Remotion docs are moving media metadata toward Mediabunny,
so check docs before adding new metadata helpers.
- Use `Math.ceil(durationInSeconds * fps)` and keep the existing minimum of one
frame so zero-length or partially unreadable metadata cannot produce invalid
compositions.
- If metadata fetching starts using `fetch()`, pass Remotion's `abortSignal` so
cancelled metadata calculations stop promptly.
- When migrating from the CLI to `@remotion/renderer`, pass the same
`inputProps` to both `selectComposition()` and `renderMedia()` so
`calculateMetadata()` and the actual render resolve the same composition.
## Media And Assets
- Local reusable assets belong in `public/` and should be referenced with
`staticFile()`. The `public/` folder must stay beside the project
`package.json`.
- Remote video URLs from S3/MinIO are valid, but they must be accessible from
the Chromium process inside Docker. Prefer presigned URLs with enough TTL for
queue wait time plus render time.
- This repo currently uses `@remotion/media` `Video`. It is frame-perfect and
fast, but respect version badges: options introduced after `4.0.435` require
a package upgrade before use.
- Do not use `objectFit` on `@remotion/media` `Video` while the project remains
on `4.0.435`; the docs mark it as `4.0.442`. Use sizing wrappers or upgrade
Remotion intentionally.
- Do not use `credentials` on `@remotion/media` `Video` while on `4.0.435`; the
docs mark it as `4.0.437`. Prefer signed public URLs for protected videos in
this version.
- Keep `Config.setVideoImageFormat("jpeg")` for regular opaque videos. Switch
to `png` only when transparency or color-accuracy requirements justify the
slower render and larger intermediate frames.
- For unsupported media, HLS, looping, alpha channels, pitch shifts, or
frame-manipulation callbacks, re-check the current docs for `@remotion/media`
`Video`, `OffthreadVideo`, and their fallback behavior before changing code.
## Render Service Rules
- The current CLI path means `remotion.config.ts` applies. If switching to
Node/Bun APIs, move needed options into `bundle()`, `selectComposition()`, or
`renderMedia()` because Remotion config is not automatically applied there.
- Keep the two concurrency knobs separate:
- BullMQ `MAX_CONCURRENT_RENDERS` controls simultaneous videos.
- Remotion render concurrency controls frame workers inside one video.
Tune both against Docker CPU and memory limits; a 4 GB / 2 CPU container can
run out of memory quickly with multiple video jobs.
- Prefer renderer callbacks (`onStart`, `onProgress`, `onBrowserLog`,
`onDownload`) if moving to `@remotion/renderer`. Keep CLI progress parsing
tolerant because CLI log text can change.
- If moving to `@remotion/renderer`, use `makeCancelSignal()` instead of only
killing a process. Keep Redis cancellation and upload abort behavior aligned.
- Preserve bounded stdout/stderr capture. Render failures should include enough
tail output for debugging without logging full user media paths or huge logs.
- Keep generated files under `out/`, remove props JSON in `finally`, and remove
rendered files after upload. Never commit render outputs or real `.env`
values.
- In Docker, keep Chromium, FFmpeg, emoji fonts, and Linux browser libraries in
sync with Remotion requirements. If browser detection changes, configure an
explicit browser executable or Remotion renderer option instead of relying on
accidental host state.
## Validation
- Always run `bun run lint` after TypeScript or Remotion changes.
- For composition/caption layout changes, run Remotion Studio or a short render
using valid props with an accessible `videoSrc`.
- For API, queue, cancellation, or upload changes, run `bun run server` and
smoke the affected `/api/render` flow, including callback/progress behavior
when touched.
- For Docker/browser/render-performance changes, smoke through
`docker compose up --build remotion` when feasible because local host Chrome
behavior is not enough evidence.
## Source Anchors
- Remotion render APIs: https://www.remotion.dev/docs/renderer/render-media
- Dynamic metadata: https://www.remotion.dev/docs/dynamic-metadata
- `delayRender()` / `useDelayRender()`: https://www.remotion.dev/docs/delay-render
- Video tag comparison: https://www.remotion.dev/docs/video-tags
- `@remotion/media` `Video`: https://www.remotion.dev/docs/media/video
- `staticFile()`: https://www.remotion.dev/docs/staticfile
- Server-side rendering and Docker links: https://www.remotion.dev/docs/ssr
- Official Remotion agent skills: https://www.remotion.dev/docs/ai/skills