0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Remotionで始めるコードによる動画制作入門

Posted at

はじめに

Remotionは、Reactコンポーネントを書くだけで動画を自動生成できるオープンソースのフレームワークで、Node.js環境で動作します。
Webアプリ開発の感覚でアニメーションやテキスト、音声を組み合わせられるため、チュートリアル動画やSNS用動画をプログラマブルに量産したい人にとても向いています。


第1章 Remotionとは何か

Remotionは「Reactコンポーネント=動画の1シーン」という発想で、Reactの再利用性や状態管理をそのまま動画制作に転用できるフレームワークです。
CSSやSVG、Canvas、WebGLなど既存のWeb技術を組み合わせ、コードでレイアウトや動き、エフェクトを細かく制御しながら、最終的にはMP4などの動画ファイルとしてレンダリングできます。

// src/Root.tsx
import {Composition} from 'remotion';
import {MyFirstVideo} from './MyFirstVideo';

export const RemotionRoot: React.FC = () => {
  return (
    <>
      <Composition
        id="MyFirstVideo"
        component={MyFirstVideo}
        durationInFrames={150}
        fps={30}
        width={1280}
        height={720}
      />
    </>
  );
};

第2章 開発環境とプロジェクト作成

Remotionを使うには、少なくともNode 16以上またはBun 1.0.3以上が必要で、npmやpnpmなど普段のJavaScriptプロジェクトとほぼ同じ環境で動作します。
公式テンプレートを使うと、ReactとRemotionがあらかじめ設定された「Hello World」プロジェクトが生成され、npm run devnpm run remotionでブラウザ上のスタジオをすぐに起動できます。

# 新規プロジェクト作成(公式CLIを利用)
npx create-video my-remotion-project

cd my-remotion-project

# 開発サーバー起動(Remotion Studio)
npm run remotion

第3章 コンポジションの基本概念

Remotionでは「コンポジション(Composition)」が動画の単位で、ID、フレーム数、FPS、解像度、使用コンポーネントなどを一括して定義します。
複数のコンポジションを定義して、用途に応じたサイズや長さの動画プリセットを用意しておけば、一つのコードベースからYouTube横長版やスマホ縦長版を簡単に切り替えられます。

// src/Root.tsx
import {Composition} from 'remotion';
import {PromoVideo} from './PromoVideo';
import {StoryVideo} from './StoryVideo';

export const RemotionRoot: React.FC = () => (
  <>
    <Composition
      id="Promo-16-9"
      component={PromoVideo}
      durationInFrames={300}
      fps={30}
      width={1920}
      height={1080}
    />
    <Composition
      id="Story-9-16"
      component={StoryVideo}
      durationInFrames={450}
      fps={30}
      width={1080}
      height={1920}
    />
  </>
);

第4章 最初の動画コンポーネントを書く

動画の中身は通常のReact関数コンポーネントとして実装し、JSXでテキストや画像などを配置します。
背景色やフォントサイズなどもスタイルオブジェクトで指定できるため、Webページを作る感覚で画面全体のデザインを構築できます。

// src/MyFirstVideo.tsx
import React from 'react';

export const MyFirstVideo: React.FC = () => {
  return (
    <div
      style={{
        flex: 1,
        backgroundColor: '#1e293b',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        color: 'white',
        fontSize: 80,
        fontFamily: 'sans-serif',
      }}
    >
      はじめてのRemotion動画
    </div>
  );
};

第5章 useCurrentFrameでアニメーション

useCurrentFrameフックを使うと、現在のフレーム番号を取得でき、これを基に位置やサイズ、色などを毎フレーム計算してアニメーションを実現します。
三角関数や補間式を利用すれば、振り子のような揺れやバウンド、フェードイン・フェードアウトなどの動きを柔軟に設計できます。

// src/WavingTitle.tsx
import {useCurrentFrame} from 'remotion';

export const WavingTitle: React.FC = () => {
  const frame = useCurrentFrame();
  const amplitude = 20;
  const translateY = Math.sin(frame / 10) * amplitude;

  return (
    <div
      style={{
        flex: 1,
        backgroundColor: '#020617',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        color: '#f97316',
        fontSize: 72,
        transform: `translateY(${translateY}px)`,
      }}
    >
      フレームで動くタイトル
    </div>
  );
};

第6章 useVideoConfigで時間とサイズを扱う

useVideoConfigフックは、コンポジションのFPSや総フレーム数、幅や高さを返し、時間計算やレスポンシブな配置に役立ちます。
例えば「3秒かけてフェードインしたい」といった場合も、FPSから必要なフレーム数を割り出して透明度を線形に変化させる実装が簡単になります。

// src/FadeInText.tsx
import {useCurrentFrame, useVideoConfig} from 'remotion';

export const FadeInText: React.FC = () => {
  const frame = useCurrentFrame();
  const {fps, width, height} = useVideoConfig();

  const fadeInDuration = 3 * fps;
  const opacity = Math.min(frame / fadeInDuration, 1);

  return (
    <div
      style={{
        width,
        height,
        backgroundColor: 'black',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        color: 'white',
        fontSize: 64,
        opacity,
      }}
    >
      ゆっくりフェードインするテキスト
    </div>
  );
};

第7章 Sequenceでシーンを区切る

<Sequence>コンポーネントは、特定のフレームから指定した長さだけ子要素を表示する仕組みで、これを使うとシーンの切り替えやテロップの表示タイミング管理が容易になります。
複数のシーケンスを重ねれば、背景シーンの上に別タイミングのテキストや画像をオーバーレイするような構成も自然に表現できます。

// src/SequencedStory.tsx
import {Sequence} from 'remotion';

const Intro: React.FC = () => (
  <h1 style={{color: 'white'}}>Remotionへようこそ</h1>
);

const Middle: React.FC = () => (
  <h1 style={{color: 'white'}}>コードで動画を作ろう</h1>
);

const Outro: React.FC = () => (
  <h1 style={{color: 'white'}}>最後まで見てくれてありがとう</h1>
);

export const SequencedStory: React.FC = () => {
  return (
    <div
      style={{
        flex: 1,
        backgroundColor: '#0f172a',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        fontFamily: 'system-ui',
      }}
    >
      <Sequence from={0} durationInFrames={90}>
        <Intro />
      </Sequence>
      <Sequence from={90} durationInFrames={90}>
        <Middle />
      </Sequence>
      <Sequence from={180} durationInFrames={90}>
        <Outro />
      </Sequence>
    </div>
  );
};

第8章 画像と音声を取り込む

RemotionではstaticFileヘルパーを使って、プロジェクト内の画像や音声ファイルを参照し、<Img><Audio>コンポーネントで簡単に利用できます。
これにより、既存のロゴやBGM、効果音をReactコードの中から直感的に読み込み、タイミングや音量をプログラムで制御できます。

// src/MediaIntro.tsx
import {Audio, staticFile} from 'remotion';

export const MediaIntro: React.FC = () => {
  const bgm = staticFile('audio/bgm.mp3');
  const logo = staticFile('images/logo.png');

  return (
    <div
      style={{
        flex: 1,
        backgroundColor: '#020617',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        position: 'relative',
      }}
    >
      <img src={logo} alt="Logo" style={{width: 300}} />
      <Audio src={bgm} />
    </div>
  );
};

第9章 テキストアニメーションとタイポグラフィ

テキストアニメーションでは、文字ごとにmapで要素を分解し、useCurrentFrameによって表示タイミングや位置をずらすことで、タイプライター風や1文字ずつ浮かび上がる演出が実現できます。
フォントサイズや行間、色を工夫することで、プレゼン動画やサービス紹介動画の読みやすさと印象を大きく変えられます。

// src/TypingText.tsx
import {useCurrentFrame} from 'remotion';

const message = 'Remotionで文字が躍る';

export const TypingText: React.FC = () => {
  const frame = useCurrentFrame();
  const chars = Array.from(message);

  return (
    <div
      style={{
        flex: 1,
        backgroundColor: '#020617',
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        fontSize: 64,
        color: 'white',
        fontFamily: 'monospace',
      }}
    >
      {chars.map((ch, index) => {
        const visible = frame > index * 5;
        return (
          <span
            key={index}
            style={{
              opacity: visible ? 1 : 0,
              transform: visible ? 'translateY(0px)' : 'translateY(20px)',
              transition: 'all 0.2s ease-out',
            }}
          >
            {ch}
          </span>
        );
      })}
    </div>
  );
};

第10章 外部データとAPIを使った動的動画

Remotionのコンポーネントは通常のReactコンポーネントなので、APIから取得したJSONやフォーム入力を props として受け取り、テキストや色、表示有無を変化させることでパーソナライズ動画を作れます。
例えばユーザー名やスコア、売上データなどを埋め込んだレポート動画を自動生成し、毎日バッチ処理でレンダリングするような運用も構築できます。

// src/ScoreCard.tsx
type ScoreCardProps = {
  userName: string;
  score: number;
};

export const ScoreCard: React.FC<ScoreCardProps> = ({userName, score}) => {
  const color = score > 80 ? '#22c55e' : '#e11d48';

  return (
    <div
      style={{
        flex: 1,
        backgroundColor: '#020617',
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        color: 'white',
        fontSize: 48,
      }}
    >
      <div>{userName} さんのスコア</div>
      <div style={{fontSize: 96, color}}>{score}</div>
    </div>
  );
};

第11章 動画のレンダリングと書き出し

Remotion Studioでプレビューした後は、コマンドラインからNodeベースのレンダラーを起動し、指定したコンポジションIDの動画をMP4やWebMとして出力できます。
レンダリング時には、ビットレートやコーデック、同時並列数などを設定して品質と速度のバランスを調整し、大量生成にも対応可能です。

# コンポジションID MyFirstVideo をレンダリング
npx remotion render MyFirstVideo out/my-first-video.mp4
// scripts/render.ts
import {renderMedia} from '@remotion/renderer';

const main = async () => {
  await renderMedia({
    compositionId: 'MyFirstVideo',
    inputProps: {},
    codec: 'h264',
    serveUrl: 'http://localhost:3000',
    outputLocation: 'out/my-first-video.mp4',
  });
};

main();

第12章 Reactのエコシステムを活用する

RemotionはReactベースのため、既存のUIライブラリやチャートライブラリ、Three.jsやCanvasラッパーなどをそのまま組み込んで、リッチなグラフィックを動画内に描画できます。
例えば営業資料でよく使うグラフも、Liveチャートコンポーネントを流用して動きのあるインフォグラフィックに変えることができ、コピペ中心で素早く開発できます。

// src/ChartVideo.tsx
import {Line} from 'react-chartjs-2';

const data = {
  labels: ['Jan', 'Feb', 'Mar', 'Apr'],
  datasets: [
    {
      label: 'Sales',
      data: [120, 150, 180, 230],
      borderColor: '#38bdf8',
    },
  ],
};

export const ChartVideo: React.FC = () => {
  return (
    <div
      style={{
        flex: 1,
        backgroundColor: 'white',
        display: 'flex',
        flexDirection: 'column',
        padding: 40,
      }}
    >
      <h1>売上の推移</h1>
      <Line data={data} />
    </div>
  );
};

第13章 Remotion PlayerでWebアプリに埋め込む

@remotion/playerパッケージを使うと、Webアプリに動画プレイヤーを組み込み、Reactのpropsを通じてその場で内容が変わるインタラクティブな動画体験を提供できます。
フォーム入力で名前や色を変えてプレビューし、その後バックエンドから本番レンダリングを依頼するといったSaaS的なサービス構築も可能です。

// web-app/Preview.tsx
import {Player} from '@remotion/player';
import {ScoreCard} from '../src/ScoreCard';

export const Preview: React.FC = () => {
  return (
    <Player
      component={ScoreCard}
      inputProps={{userName: '山田', score: 92}}
      durationInFrames={150}
      fps={30}
      compositionWidth={1280}
      compositionHeight={720}
      controls
    />
  );
};

第14章 日本語コミュニティと学習リソース

日本語でRemotionを解説した記事や作例も徐々に増えており、Reactで作った解説動画やゆっくり動画風のテンプレートなどが公開されています。
これらのコードを読みながら公式ドキュメントを参照すると、アニメーションのベストプラクティスや構成の工夫を自然に学べるため、最初は既存プロジェクトの改造から始めると理解が進みます。

// 既存サンプルを少しアレンジする例(抜粋)
import {useCurrentFrame, useVideoConfig} from 'remotion';

export const SampleRemix: React.FC = () => {
  const frame = useCurrentFrame();
  const {width, height} = useVideoConfig();
  const rotate = frame * 0.5;

  return (
    <div
      style={{
        width,
        height,
        background: 'linear-gradient(135deg,#0f172a,#22d3ee)',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
      }}
    >
      <div
        style={{
          padding: 40,
          borderRadius: 24,
          backgroundColor: 'rgba(15,23,42,0.85)',
          color: 'white',
          fontSize: 48,
          transform: `rotate(${rotate}deg)`,
        }}
      >
        サンプルをリミックス
      </div>
    </div>
  );
};

第15章 次のステップと応用アイデア

Remotionを使いこなすと、コードだけでテンプレート化された動画を自動生成できるため、YouTubeの定期企画、ニュースダイジェスト、売上レポートなどの定形コンテンツを省力化できます。
さらにAWS LambdaやCIと連携し、Gitにプッシュしたら自動で新しい動画がレンダリングされるパイプラインを構築すれば、開発チーム全体で効率的に動画プロダクトを運用できます。

// src/AutoGeneratedEpisode.tsx
import {Sequence, useCurrentFrame} from 'remotion';

type EpisodeProps = {
  title: string;
  date: string;
  topics: string[];
};

export const AutoGeneratedEpisode: React.FC<EpisodeProps> = ({
  title,
  date,
  topics,
}) => {
  const frame = useCurrentFrame();
  const bgShift = Math.sin(frame / 20) * 20;

  return (
    <div
      style={{
        flex: 1,
        background: `linear-gradient(135deg,#0f172a,#1d4ed8 ${50 + bgShift}%)`,
        color: 'white',
        fontFamily: 'system-ui',
        padding: 60,
      }}
    >
      <Sequence from={0} durationInFrames={90}>
        <h1 style={{fontSize: 64}}>{title}</h1>
        <p style={{fontSize: 28}}>配信日: {date}</p>
      </Sequence>
      <Sequence from={90} durationInFrames={210}>
        <h2 style={{fontSize: 40}}>今日のトピック</h2>
        <ul style={{fontSize: 28}}>
          {topics.map((t, i) => (
            <li key={i}>{t}</li>
          ))}
        </ul>
      </Sequence>
    </div>
  );
};
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?