Communitygithub.com

carissadarmafissaleha/remotion

Panduan Master Komprehensif untuk Pembuatan Video secara Programmatis dengan React dan Remotion. Rancang, rakit, animasikan, sinkronkan audio narasi/VO, dan render video motion graphic profesional (16:9 explainer, 9:16 vertical shorts/TikTok/Reels) secara programmatis menggunakan React, Remotion 4.x, Spring physics, GSAP, Tailwind/CSS, dan CLI rendering dengan akselerasi hardware. Gunakan skill ini setiap kali pengguna meminta membuat video berbasis Remotion, merender MP4, membuat kinetic typography, transisi adegan (Series/TransitionSeries), sinkronisasi voiceover, atau optimasi performa render.

remotion 是什么?

Skill ini adalah panduan lengkap untuk membuat video sinematik secara programmatis menggunakan React dan Remotion 4.x. Skill ini mencakup arsitektur komposisi dan konfigurasi root, primitif tata letak dan timeline seperti Sequence dan Series, fisika animasi dengan spring() dan interpolate(), kinetic typography dengan efek kata per kata, sinkronisasi voiceover, pra-pemuatan aset async dengan delayRender, dan template motion grafis profesional 8 tahap. Skill ini juga menyediakan perintah CLI untuk rendering video dengan akselerasi hardware (--gl=angle) dan konkurensi tinggi, serta panduan pemecahan masalah umum. Dengan skill ini, pengguna dapat membuat video explainer 16:9, vertikal shorts untuk TikTok/Reels, atau konten motion grafis lainnya dengan kualitas sinematik dan performa optimal.

兼容平台~Claude Code~Codex CLI~Cursor✓Antigravity
npx skills add https://github.com/carissadarmafissaleha/office-nara/tree/main/skills/remotion

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Panduan Master Remotion — Pembuatan Video Programmatis dalam React

Remotion memungkinkan pembuatan video sinematik dengan kode React murni. Setiap frame video diperlakukan sebagai status deterministik (frame) => UI, menghasilkan visual 60 FPS sempurna tanpa jeda atau frame drop.


1. Arsitektur Komposisi & Konfigurasi Root

A. Titik Masuk Root (Root.tsx)

import { Composition } from 'remotion';
import { MainExplainer } from './compositions/MainExplainer';
import { VerticalShort } from './compositions/VerticalShort';

export const RemotionRoot: React.FC = () => {
  return (
    <>
      {/* 16:9 Lanskap Sinematik Explainer */}
      <Composition
        id="MainExplainer-1080p"
        component={MainExplainer}
        durationInFrames={30 * 32} // 32 detik @ 30 FPS = 960 frames
        fps={30}
        width={1920}
        height={1080}
        defaultProps={{
          title: 'Misteri Mencairnya Puncak Es Dunia',
          author: 'NARA Studio',
          themeColor: '#f97316',
        }}
      />

      {/* 9:16 Vertikal TikTok / Reels / Shorts */}
      <Composition
        id="VerticalShort-60fps"
        component={VerticalShort}
        durationInFrames={60 * 15} // 15 detik @ 60 FPS = 900 frames
        fps={60}
        width={1080}
        height={1920}
      />
    </>
  );
};

B. Aturan Durasi & FPS

  • 16:9 YouTube / Explainer: Rekomendasi 30 fps (seimbang antara kecepatan rendering & kehalusan gerak) atau 60 fps untuk kinetic typography ultra-crisp.
  • Durasi Frame: Selalu hitung durationInFrames = Math.round(seconds * fps).
  • Zero Jitter: Jangan gunakan setInterval atau setTimeout. Selalu gunakan useCurrentFrame() dan useVideoConfig().

2. Tata Letak & Primitif Timeline

AbsoluteFill

Dasar dari seluruh layer adegan. Otomatis position: absolute; inset: 0; width: 100%; height: 100%;:

import { AbsoluteFill } from 'remotion';

export const SceneBackground: React.FC = () => {
  return (
    <AbsoluteFill style={{ backgroundColor: '#090812', overflow: 'hidden' }}>
      {/* Konten visual */}
    </AbsoluteFill>
  );
};

Sequence vs Series

  • Sequence: Menempatkan elemen pada waktu absolut (from dan durationInFrames). Ideal untuk audio latar, watermark, overlay HUD, atau elemen yang saling tumpang tindih.
  • Series: Mengurutkan adegan secara sekuensial otomatis tanpa perlu menghitung offset frame manual.
import { Series, Sequence, Audio, staticFile } from 'remotion';

export const VideoStory: React.FC = () => {
  return (
    <AbsoluteFill>
      {/* Audio Musik Latar Sepanjang Video */}
      <Audio src={staticFile('audio/ambient_score.mp3')} volume={0.35} />

      {/* Urutan Adegan Otomatis */}
      <Series>
        <Series.Sequence durationInFrames={120}>
          <HookScene />
        </Series.Sequence>
        <Series.Sequence durationInFrames={180}>
          <ProblemScene />
        </Series.Sequence>
        <Series.Sequence durationInFrames={240}>
          <SolutionScene />
        </Series.Sequence>
        <Series.Sequence durationInFrames={150}>
          <CallToActionScene />
        </Series.Sequence>
      </Series>
    </AbsoluteFill>
  );
};

3. Fisika Animasi: spring() & interpolate()

A. Formula Pegas Alami (spring())

Gunakan spring() untuk menghasilkan gerakan fisika nyata (menghilangkan kesan kaku "PowerPoint"):

import { spring, useCurrentFrame, useVideoConfig } from 'remotion';

const frame = useCurrentFrame();
const { fps } = useVideoConfig();

// 1. Snappy Pop (Teks/Badge Muncul Menghentak)
const popScale = spring({
  frame,
  fps,
  config: { damping: 10, mass: 0.4, stiffness: 180 },
});

// 2. Smooth Drift (Kamera Meluncur Halus)
const smoothSlide = spring({
  frame,
  fps,
  config: { damping: 20, mass: 1.2, stiffness: 60 },
});

// 3. Bouncy Drop (Ikon/Partikel Jatuh Memantul)
const bounce = spring({
  frame: frame - 10, // delay 10 frame
  fps,
  config: { damping: 8, mass: 0.6, stiffness: 140 },
});

B. Pemetaan Nilai Halus (interpolate())

import { interpolate, Easing } from 'remotion';

// Transisi Alpha & Rotasi dengan Easing Bezier
const opacity = interpolate(frame, [0, 20], [0, 1], {
  extrapolateRight: 'clamp',
});

const rotateY = interpolate(frame, [0, 60], [-45, 0], {
  easing: Easing.bezier(0.16, 1, 0.3, 1),
  extrapolateRight: 'clamp',
});

4. Kinetic Typography & Sinkronisasi Voiceover

A. Staggered Word Reveal (Teks Muncul Kata per Kata)

import React from 'react';
import { useCurrentFrame, useVideoConfig, spring, interpolate } from 'remotion';

interface KineticTextProps {
  sentence: string;
  startFrame?: number;
  wordDelay?: number;
}

export const KineticText: React.FC<KineticTextProps> = ({
  sentence,
  startFrame = 0,
  wordDelay = 4, // 4 frame jarak antar kata
}) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const words = sentence.split(' ');

  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: '12px', justifyContent: 'center' }}>
      {words.map((word, idx) => {
        const wordStart = startFrame + idx * wordDelay;
        const progress = spring({
          frame: frame - wordStart,
          fps,
          config: { damping: 12, mass: 0.4, stiffness: 160 },
        });

        const translateY = interpolate(progress, [0, 1], [40, 0]);
        const opacity = interpolate(progress, [0, 1], [0, 1]);

        return (
          <span
            key={idx}
            style={{
              display: 'inline-block',
              transform: `translateY(${translateY}px)`,
              opacity,
              fontSize: '48px',
              fontWeight: 800,
              color: idx === 0 ? '#f97316' : '#ffffff',
              letterSpacing: '-1px',
              fontFamily: "'JetBrains Mono', sans-serif",
            }}
          >
            {word}
          </span>
        );
      })}
    </div>
  );
};

B. Sinkronisasi Voiceover & SFX

  • Tempatkan file audio di folder public/audio/.
  • Gunakan staticFile('audio/file.mp3').
  • Buat transisi audio fade in/fade out menggunakan properti volume:
<Audio
  src={staticFile('audio/naskah_vo.mp3')}
  volume={(f) =>
    interpolate(f, [0, 15, 880, 900], [0, 1, 1, 0], {
      extrapolateLeft: 'clamp',
      extrapolateRight: 'clamp',
    })
  }
/>

5. Aset Async & Pra-pemuatan (delayRender)

Ketika video memuat font kustom, gambar eksternal, atau data API, Remotion HARUS diberi tahu agar tidak merender frame kosong:

import { delayRender, continueRender } from 'remotion';
import { useEffect, useState } from 'react';

export const DynamicScene: React.FC = () => {
  const [handle] = useState(() => delayRender('Memuat Font & Asset'));

  useEffect(() => {
    document.fonts.ready.then(() => {
      continueRender(handle);
    });
  }, [handle]);

  return <AbsoluteFill>...</AbsoluteFill>;
};

6. Template & Resep Motion Grafis NARA

Formula 8 Tahap Sinematik (Anti-PPT)

  1. Scene 1: Cold Hook (00-03s) → Visual misteri + Tipografi kinetik besar.
  2. Scene 2: Problem Stated (04-07s) → Visual es runtuh / grafik merah membara.
  3. Scene 3: Deep Dive Data (08-12s) → Angka statistik berhitung naik (Math.floor).
  4. Scene 4: Dynamic Scale Shift (13-16s) → Perubahan skala makro ke mikro.
  5. Scene 5: Human Impact (17-20s) → Karakter kartun bereaksi di canvas.
  6. Scene 6: Solution Revelation (21-25s) → Visual beralih ke warna hijau/oranye terang.
  7. Scene 7: Action Steps (26-29s) → 3 poin kartu melayang 3D.
  8. Scene 8: Climax & CTA (30-32s) → Logo studio pulse + audio whoosh drop.

7. Eksekusi Render CLI & Akselerasi Hardware

A. Render Video Tunggal (1080p 60fps)

npx remotion render src/remotion/index.ts MainExplainer-1080p out/output.mp4 --gl=angle

B. Render Cepat dengan Konkurensi Tinggi

npx remotion render src/remotion/index.ts MainExplainer-1080p out/output.mp4 --concurrency=8 --gl=angle --jpeg-quality=90

C. Flag Rendering Penting

  • --gl=angle: Menggunakan akselerasi GPU DirectX di Windows (jauh lebih cepat dari software rasterizer).
  • --gl=swiftshader: Fallback software jika GPU tidak tersedia di container/CI.
  • --concurrency=N: Jumlah core CPU yang digunakan untuk render paralel.
  • --muted: Merender tanpa audio stream jika hanya butuh visual.
  • --props='{"title":"Baru"}': Melewatkan parameter dinamis via JSON command line.

8. Panduan Pemecahan Masalah

  1. Layar Hitam / Gambar Tidak Muncul: Pastikan aset berada di folder public/ dan dipanggil dengan staticFile('nama_file').
  2. Video Macet Saat Render: Cek apakah ada infinite loop di useMemo atau komponen React yang tidak menutup delayRender.
  3. Audio Out of Sync: Pastikan nilai fps komposisi sama persis dengan perhitungan detik voiceover (seconds = frames / fps).

相关技能