All skills
heygen-com avatar

/remotion-to-hyperframes

@ff6e210
by HeyGenheygen-com/hyperframes55k stars
4,998

Port an existing Remotion (React) composition's source to HyperFrames HTML. Use ONLY on an explicit ask to port/convert/migrate/translate a Remotion source — one-way, Remotion-only. A passing Remotion mention, reference-only code, or "make something like my Remotion video" is a fresh build (/general-video). Unclear → /hyperframes.

Use this Skill: https://skilld.dev/gh/heygen-com/hyperframes/remotion-to-hyperframes

This session only. Nothing lands on disk.

referencesmedia.md

≈965 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Media translation: Audio, Video, Img, IFrame, staticFile

Asset paths

Remotion's staticFile("x.png") resolves to the project's public/ directory. HF uses relative paths from the composition's index.html, conventionally assets/:

<Img src={staticFile("logo.png")} />
<img src="assets/logo.png" />

When translating, copy the asset from remotion-src/public/x to hf-src/assets/x. Multiple files can be batched with a setup script; see T2's setup.sh for an example pattern.

<Audio>

<Audio src={staticFile("music.wav")} volume={0.5} />
<audio
  data-start="0"
  data-duration="6"
  data-track-index="2"
  data-volume="0.5"
  src="assets/music.wav"
></audio>

data-start and data-duration are required — the runtime needs them to schedule the audio. Default to the composition's full duration if Remotion didn't specify trim.

Volume ramps

<Audio src={staticFile("music.wav")} volume={(f) => interpolate(f, [0, 30], [0, 1])} />

Volume ramps become a data-automation volume lane on the <audio> (form in hyperframes-core/references/creator-editing-recipes.md); data-volume is the static baseline.

Trim / playbackRate

<Audio src={staticFile("music.wav")} startFrom={60} endAt={180} playbackRate={1.5} />
<audio
  data-start="0"
  data-duration="<resolved from trim>"
  data-trim-start="2"
  data-trim-end="6"
  data-playback-rate="1.5"
  src="assets/music.wav"
></audio>

startFrom / endAt are frame indexes; convert to seconds.

<Video> and <OffthreadVideo>

<Video src={staticFile("intro.mp4")} playsInline />
<OffthreadVideo src={staticFile("intro.mp4")} />
<!-- intro.mp4 has an audio stream -->
<video
  playsinline
  data-has-audio="true"
  data-start="0"
  data-duration="5"
  data-track-index="0"
  src="assets/intro.mp4"
></video>

<!-- intro.mp4 is silent (or the Remotion element is muted) -->
<video
  playsinline
  muted
  data-start="0"
  data-duration="5"
  data-track-index="0"
  src="assets/intro.mp4"
></video>

<OffthreadVideo> is a Remotion-specific optimization for headless rendering. HF runs in headless Chrome already, so the off-thread variant collapses to a regular <video>.

playsinline is required for the runtime to autoplay (browser policy); always emit it. Check the source file for an audio stream first: ffprobe -v error -select_streams a -show_entries stream=codec_type -of csv=p=0 <file> (non-empty output means it has audio). Remotion <Video> maps to <video playsinline> + data-has-audio="true" only when the file has an audio stream and the Remotion source does not set muted or volume={0}; otherwise emit muted. Silent b-roll with data-has-audio="true" aborts the render (ASSET_MEDIA_TYPE_MISMATCH).

<Img>

<Img src={staticFile("logo.png")} style={{ width: 200, height: 200 }} />
<img src="assets/logo.png" style="width: 200px; height: 200px;" />

Width/height get rounded to integer px. If the original style has animated dimensions, the GSAP tween animates them — see timing.md.

<IFrame>

<IFrame src="https://example.com" />
<iframe src="https://example.com"></iframe>

When HF detects a nested iframe in a composition, it auto-falls back to screenshot mode rather than the deterministic BeginFrame mode. This costs render performance but produces visibly-correct output. See hyperframes-vs-remotion.mdx for details.

delayRender() / continueRender()

const handle = delayRender();
useEffect(() => {
  loadAsset().then(() => continueRender(handle));
}, []);

Drop. HF waits on asset readiness via the Frame Adapter pattern — images, videos, fonts, and Lottie animations all signal load completion natively. There's nothing to do at the application level.

When the asset isn't a file

If Remotion's media source is a Buffer, dataURL, or URL.createObjectURL, the asset doesn't exist on disk and can't be copied via setup.sh. Two options:

  1. Materialize the asset at translation time — write the buffer to a file in hf-src/assets/.
  2. Embed as a data URL directly in the HTML (src="data:image/png;base64,...") for small assets (< 100 KB).

For audio/video Buffers, option 1 is preferred — base64-encoded media bloats the HTML and slows the renderer.

Source: SKILL.md on GitHub

1 warning3d3 checks · Risk SAFE
  • Gen Agent Trust Hub3d

    The skill is a specialized tool for migrating Remotion video compositions to HyperFrames HTML. It includes a security-conscious linter that identifies and blocks non-deterministic or side-effect-heavy React patterns (like useState or side-effects in useEffect) from being translated. It uses standard industry tools (ffmpeg, npm) and official vendor resources from trusted and well-known services.

  • Socket3d

    No alerts

  • Snyk3d

    Risk: MEDIUM · 1 issue

Signed by skilld at ff6e210. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 17 hours ago.

Activeupdated 4 days ago

README badge

README badge for heygen-com/hyperframes/remotion-to-hyperframes