RemotionでYouTubeのイントロ・アウトロ動画を作る方法
RemotionでYouTubeのイントロ・アウトロ動画を作る方法
チャンネルを訪れた視聴者が最初に目にするのはサムネイルでも概要欄でもなく、動画の冒頭数秒です。そこで流れるイントロがチャンネルのブランドを刻み込み、「また戻ってきたくなる場所」という印象を形成します。動画の末尾に配置するアウトロも同様に重要で、チャンネル登録や関連動画への誘導という実務的な役割を担っています。
多くのクリエイターはこれらのクリップを動画編集ソフトで一度作り、そのまま使い続けます。しかしチャンネルをリブランドしたり、新しいシリーズを立ち上げたりするたびに、ゼロからの作り直しを迫られます。Remotionを使えば、イントロ・アウトロをReactコンポーネントとして管理できるため、ブランドの変更をコードの修正と再レンダリングだけで完結させることが可能です。
なぜプログラムでイントロを作るのか
動画編集ソフトのテンプレートは優れていますが、本質的に静的な資産です。チャンネル名を1文字直すためにプロジェクトを開き、テキストレイヤーを探し、修正して再エクスポートする。この作業を複数チャンネルで繰り返すと、維持コストが見えないところで積み上がっていきます。
Remotionのアプローチは根本的に異なります。イントロはTypeScriptの関数です。チャンネル名、アクセントカラー、ロゴのパス、アニメーションのタイミング——これらすべてがプロパティ(props)として外部から注入されます。バリアントを作りたければpropsを変えて再レンダリングするだけ。タイムラインを触る必要はありません。
具体的なメリットを整理します。
Gitで管理できる。 イントロのソースコードはリポジトリに入ります。「旧ブランド」と「新ブランド」のブランチをdiffすれば、何がどう変わったかが一目瞭然です。
データ駆動のバッチ生成。 複数の番組やシリーズを運営している場合、設定をJSON配列で定義してループ処理するだけで、複数種類のイントロを1コマンドで出力できます。
決定論的な再現性。 Remotionはコードから一意に映像を生成します。同じソースからは常に同じ出力が得られるため、「マシンによって微妙に見た目が違う」という問題が発生しません。
YouTubeイントロの設計原則
コードを書く前に、効果的なYouTubeイントロの条件を確認しておきましょう。
長さは3〜5秒が基本。 視聴者の大半はイントロをスキップします。動画冒頭の視聴維持率グラフには必ずと言っていいほど落ち込みがあり、イントロが長いほど離脱が早まります。どうしても長くしたい場合でも8秒を上限と考えてください。
最初の1秒でブランドを示す。 イントロの唯一の仕事は「この動画はあなたが求めているチャンネルのものですよ」と確認させることです。ロゴやチャンネル名の提示を引っ張る演出は逆効果になりがちです。
チャンネルのトーンに合わせる。 技術解説系のチャンネルであれば、シャープなタイポグラフィと整ったモーションが映えます。旅行vlogなら躍動感のある色使いとカメラシェイクが合います。ジャンルのモーション言語を意識してください。
音も設計する。 Remotionは音声を標準でサポートしています。public/フォルダに置いた音楽ファイルは<Audio>コンポーネントで簡単に組み込めます。短いブランドスティングがあるだけで視聴者の記憶定着率が大きく変わります。
最終フレームのカットを意識する。 イントロの最後のフレームが本編の冒頭フレームに自然につながるよう、背景色やトーンを設計段階で揃えておきましょう。
Remotionでロゴイントロを作る
以下のコードは、npx create-video@latestでRemotionプロジェクトを初期化済みであることを前提としています。
コンポジションの登録
Root.tsxに1920×1080・30fps・5秒(150フレーム)のコンポジションを追加します。
import { Composition } from "remotion";
import { YoutubeIntro } from "./YoutubeIntro";
export const RemotionRoot: React.FC = () => {
return (
<>
<Composition
id="YoutubeIntro"
component={YoutubeIntro}
durationInFrames={150}
fps={30}
width={1920}
height={1080}
defaultProps={{
channelName: "マイチャンネル",
accentColor: "#FF4444",
}}
/>
</>
);
};
spring()でロゴをポップイン
spring()はRemotionが提供する物理ベースのアニメーション関数です。バネのように目標値に向かって収束するため、ロゴの出現に使うと自然な勢いが生まれます。
import {
AbsoluteFill,
useCurrentFrame,
useVideoConfig,
spring,
interpolate,
} from "remotion";
type Props = {
channelName: string;
accentColor: string;
};
export const YoutubeIntro: React.FC<Props> = ({ channelName, accentColor }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// ロゴを0→1にスケールアップ(バネの弾力あり)
const logoScale = spring({
frame,
fps,
config: {
damping: 12,
stiffness: 120,
mass: 1,
},
});
// 最初の10フレームでフェードイン
const opacity = interpolate(frame, [0, 10], [0, 1], {
extrapolateRight: "clamp",
});
return (
<AbsoluteFill
style={{
backgroundColor: "#0F0F0F",
justifyContent: "center",
alignItems: "center",
}}
>
<div
style={{
transform: `scale(${logoScale})`,
opacity,
fontSize: 96,
fontWeight: 800,
color: accentColor,
fontFamily:
'"Yu Gothic", "Hiragino Kaku Gothic ProN", "Noto Sans JP", sans-serif',
letterSpacing: "-2px",
}}
>
{/* 実際の制作では <Img> コンポーネントでロゴ画像を表示する */}
{channelName}
</div>
</AbsoluteFill>
);
};
useCurrentFrame()は現在のフレーム番号(0始まり)を返し、useVideoConfig()はfps・width・height・durationInFramesを提供します。spring()はframeとfpsを受け取って動作するため、フレームレートを変更してもアニメーションの物理的な感触は変わりません。
テキストリビールを追加する
ロゴが現れた後にチャンネル名やエピソードタイトルをスライドインさせるパターンは、視聴者に階層的な情報を伝える王道の手法です。Remotionの<Sequence>コンポーネントを使うと、子要素の開始タイミングをフレーム単位でずらすことができます。
import { Sequence } from "remotion";
// メインコンポーネントのreturn内:
<Sequence from={20}>
{/* このサブツリーはフレーム20から始まる */}
<ChannelNameReveal name={channelName} />
</Sequence>
<Sequence from={40}>
<EpisodeTitleReveal title="第12回" />
</Sequence>
個々のテキストリビールコンポーネントは「自分はフレーム0から始まる」として書けばよく、<Sequence from={20}>が親フレーム20を子フレーム0に変換してくれます。
const ChannelNameReveal: React.FC<{ name: string }> = ({ name }) => {
const frame = useCurrentFrame();
const translateY = interpolate(frame, [0, 20], [30, 0], {
extrapolateRight: "clamp",
});
const opacity = interpolate(frame, [0, 15], [0, 1], {
extrapolateRight: "clamp",
});
return (
<div
style={{
transform: `translateY(${translateY}px)`,
opacity,
color: "#FFFFFF",
fontSize: 48,
fontWeight: 600,
fontFamily:
'"Yu Gothic", "Hiragino Kaku Gothic ProN", "Noto Sans JP", sans-serif',
}}
>
{name}
</div>
);
};
この設計により、アニメーションコンポーネントを独立した単位として管理でき、タイミングの調整も<Sequence>のfrom値を変えるだけで済みます。
アウトロを作る:チャンネル登録CTAとエンドカード
YouTubeのアウトロは通常15〜20秒で、目的は明確です。視聴者をチャンネル登録者に変換するか、次の動画に誘導するかです。YouTubeのエンドカードUI(クリッカブルなオーバーレイ)は動画末尾20秒から自動表示されるので、アウトロのアニメーションはそれらと競合しないよう設計します。
レイアウトの考え方
効果的なアウトロは画面をゾーンに分けます。
- 中央または左上 — 「ご視聴ありがとうございました」などの締めの言葉
- 右上 — チャンネル登録ボタンのアニメーション
- 下部 — 関連動画のサムネイルプレースホルダー
チャンネル登録ボタンのアニメーション
const SubscribeButton: React.FC = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// 30フレーム(1秒)遅延してからspring起動
const pulse = spring({
frame: frame - 30,
fps,
config: { damping: 8, stiffness: 100, mass: 1.2 },
from: 0,
to: 1,
});
const scale = interpolate(pulse, [0, 1], [0.8, 1]);
return (
<div
style={{
transform: `scale(${scale})`,
backgroundColor: "#FF0000",
color: "#FFFFFF",
padding: "20px 48px",
borderRadius: 8,
fontSize: 36,
fontWeight: 700,
fontFamily:
'"Yu Gothic", "Hiragino Kaku Gothic ProN", "Noto Sans JP", sans-serif',
boxShadow: "0 8px 32px rgba(255,0,0,0.4)",
}}
>
チャンネル登録
</div>
);
};
spring()のfrom・toパラメーターを直接指定すると、単純なスケールアニメーションではinterpolate()を別途書かずに済みます。
ループするシマー効果
ベルアイコンを定期的に光らせるような繰り返しアニメーションは、モジュロ演算で実装できます。
// 30fpsで2秒ごとにリセット
const shimmerFrame = frame % 60;
const shimmerOpacity = interpolate(shimmerFrame, [0, 10, 50, 60], [0, 1, 1, 0]);
frame % サイクル長のパターンは、追加ライブラリなしにループ効果を作る最もシンプルな方法です。
YouTube向けの出力設定
YouTubeが推奨するHD動画の仕様は1920×1080・H.264・30fps・平均ビットレート8Mbps前後です。Remotionのレンダリングコマンドはこの仕様に直接対応しています。
npx remotion render src/index.ts YoutubeIntro out/intro.mp4 \
--codec=h264 \
--fps=30 \
--width=1920 \
--height=1080 \
--crf=18
補足事項:
--crf(Constant Rate Factor)は品質を制御するパラメーターです。値が低いほど高品質・大ファイルになります。YouTubeにアップロードするマスター素材であれば18前後を推奨します。YouTubeが再エンコードを行うため、多少大きなファイルで入稿する方が最終画質が安定します。- 透過が必要な場合(映像素材に重ねるアウトロなど)は
--codec=vp8または--codec=prores-4444を使い、背景を透明にします。 - 大量のバリアントを並列生成するにはRemotion Lambdaが有効です。AWS Lambda上でフレームを分散レンダリングするため、10秒の動画を30秒以内に出力できます。
RenderCompのイントロ・アウトロテンプレートを使う
ゼロから作ることで自由度は最大化されますが、TypeScriptの習熟と時間が必要です。RenderCompは、この記事で解説したような実装を組み込み済みの本番品質Remotionテンプレートを提供しており、ボイラープレートの記述を省略できます。
テンプレートが含むもの
RenderCompの各イントロ・アウトロテンプレートには以下が同梱されています。
- 型付きpropsスキーマ — チャンネル名、ロゴ、カラー、タイミングなどすべてのビジュアル変数が型安全なプロパティとして定義されています。一箇所を変更すればアニメーション全体に反映されます。
- イントロ・アウトロのペア — 同じデザイン言語で作られたペアが含まれるため、追加作業なしに動画の統一感が生まれます。
- YouTube対応の解像度 — デフォルトは1920×1080。4K(3840×2160)バリアントも選択可能です。
- 音楽スティング — ブランドに合わせた短い音楽素材が
<Audio>コンポーネントに組み込まれた状態で同梱されています。
ノーコードでのカスタマイズ
コードを書かずに使いたい場合のワークフローです。
- rendercomp.comでテンプレートをブラウズ。
- チャンネルのトーンに合うイントロ・アウトロペアを選択。
- チャンネル名・HEXカラー・ロゴ画像をフォームに入力。
- レンダリング済みのMP4をダウンロード。
ソースコードを持ちたい開発者向けのワークフロー:
- テンプレートパッケージを購入・ダウンロード。
- Remotionワークスペースの
src/templates/以下に配置。 Root.tsxでコンポジションをimport・登録。- propsを変更するか、コンポーネントを拡張して好みにカスタマイズ。
ブランドのリニューアル時も、ロゴとアクセントカラーを変更して再レンダリングするだけです。2分以内に新しいイントロ・アウトロファイルが出来上がります。
よくある質問
YouTubeイントロの理想的な長さはどのくらいですか?
3〜5秒が標準です。視聴維持率のデータは、イントロが長いほど動画冒頭の離脱が早まることを一貫して示しています。5秒でブランドが伝わらない場合、問題は長さではなくデザインにある可能性が高いです。
プログラミングができなくてもRemotionのテンプレートを使えますか?
はい。RenderCompのテンプレートはすべてのクリエイティブ変数をシンプルなフォームで入力できるように設計されています。TypeScriptのコンパイルとレンダリングはバックエンドで処理されるため、制作者はMP4をダウンロードするだけです。
日本語フォントのレンダリングは問題ありませんか?
Remotionはシステムにインストールされているフォントを使用します。font-familyに遊ゴシック・Hiragino Kaku Gothic ProN・Noto Sans JPを指定しておけば、macOSおよびLinux(Noto既インストール環境)で正しくレンダリングされます。Remotion Lambda上でレンダリングする場合は、Noto Sans JPをプロジェクトに同梱するか@remotion/google-fontsなどのユーティリティで読み込む設定が必要になります。
アウトロに背景動画を敷くことはできますか?
できます。public/フォルダに動画ファイルを置き、<Video>コンポーネントで参照します。<AbsoluteFill>でレイヤー管理を行い、動画の上にアニメーション要素を重ねる構成が一般的です。
spring()のバウンスが強すぎます。どうすれば抑えられますか?
spring()のconfigにあるdampingの値を大きくしてください。12前後だと弾力感があり、200程度にするとほぼイーズアウトに近い挙動になります。チャンネルのトーンに合わせて調整してください。
複数チャンネル向けにまとめてイントロを生成できますか?
できます。各チャンネルの設定をJSON配列として定義し、Node.jsスクリプトでrenderMedia()をループ呼び出しするだけです。Remotion Lambdaを使えばそれらを並列で処理することも可能です。
次のステップ
YouTubeイントロ・アウトロへの投資は、制作した後はすべての動画で自動的に機能し続ける、レバレッジ効率の高い取り組みです。Remotionを使えば、その資産をコードとして管理し、チャンネルの成長に合わせて素早く更新できます。
すぐに始めたい方は、RenderCompのテンプレートライブラリでイントロ・アウトロペアを探してみてください。数分でブランド入りのMP4が手に入ります。ソースを持ってカスタマイズしたい方には、すべてのテンプレートが完全なTypeScriptコンポジションとして提供されています。