Remotion LabRemotion Lab
資源影片編輯器起始模板

影片編輯器起始模板

使用 Remotion 的 Editor Starter Kit 快速建立功能完整的線上影片編輯器,內含時間軸、屬性面板和即時預覽。

影片編輯器起始模板

Editor Starter Kit 是 Remotion 官方提供的完整起始模板,讓你可以快速建立一個功能齊全的線上影片編輯器,而不必從零開始實作時間軸、預覽播放器和渲染流程。

模板包含什麼

  • 即時預覽播放器:使用 @remotion/player 提供流暢的即時預覽
  • 時間軸介面:可拖曳調整片段順序與時長
  • 屬性編輯面板:點選元素即可修改文字、顏色、位置等屬性
  • 素材庫:管理圖片、影片、音訊等媒體資源
  • 渲染觸發:整合渲染 API,一鍵輸出最終影片
  • 響應式版面:適合整合進 SaaS 產品或獨立部署

快速開始

npx create-video@latest --template editor
cd my-editor
npm install
npm run dev

或直接從 GitHub 複製範本:

git clone https://github.com/remotion-dev/editor-starter
cd editor-starter
npm install
npm run dev

專案結構

editor-starter/
├── app/                    # Next.js App Router
│   ├── page.tsx            # 編輯器主頁面
│   └── api/
│       └── render/         # 渲染 API 路由
│           └── route.ts
├── remotion/               # Remotion Composition 定義
│   ├── Root.tsx
│   └── scenes/
│       ├── TextScene.tsx
│       ├── ImageScene.tsx
│       └── VideoScene.tsx
├── components/             # 編輯器 UI 元件
│   ├── Timeline.tsx        # 時間軸元件
│   ├── Preview.tsx         # 預覽播放器
│   ├── PropertiesPanel.tsx # 屬性面板
│   └── AssetLibrary.tsx    # 素材庫
└── store/                  # 全域狀態管理(Zustand)
    └── editorStore.ts

核心架構設計

狀態管理

模板使用 Zustand 管理編輯器狀態,所有場景資料、時間軸配置和選取狀態都集中在一個 store 中:

// store/editorStore.ts
import { create } from "zustand";
 
interface Scene {
  id: string;
  type: "text" | "image" | "video";
  from: number;
  durationInFrames: number;
  props: Record<string, unknown>;
}
 
interface EditorStore {
  scenes: Scene[];
  selectedSceneId: string | null;
  currentFrame: number;
  addScene: (scene: Scene) => void;
  updateScene: (id: string, props: Partial<Scene>) => void;
  removeScene: (id: string) => void;
  selectScene: (id: string | null) => void;
}
 
export const useEditorStore = create<EditorStore>((set) => ({
  scenes: [],
  selectedSceneId: null,
  currentFrame: 0,
  addScene: (scene) => set((state) => ({ scenes: [...state.scenes, scene] })),
  updateScene: (id, props) =>
    set((state) => ({
      scenes: state.scenes.map((s) => (s.id === id ? { ...s, ...props } : s)),
    })),
  removeScene: (id) =>
    set((state) => ({ scenes: state.scenes.filter((s) => s.id !== id) })),
  selectScene: (id) => set({ selectedSceneId: id }),
}));

動態 Composition

編輯器的 Composition 根據 store 中的場景資料動態渲染:

// remotion/DynamicVideo.tsx
import { AbsoluteFill, Sequence } from "remotion";
import { useEditorStore } from "../store/editorStore";
import { TextScene } from "./scenes/TextScene";
import { ImageScene } from "./scenes/ImageScene";
 
export const DynamicVideo: React.FC = () => {
  const { scenes } = useEditorStore();
 
  return (
    <AbsoluteFill>
      {scenes.map((scene) => (
        <Sequence
          key={scene.id}
          from={scene.from}
          durationInFrames={scene.durationInFrames}
        >
          {scene.type === "text" && <TextScene {...scene.props} />}
          {scene.type === "image" && <ImageScene {...scene.props} />}
        </Sequence>
      ))}
    </AbsoluteFill>
  );
};

渲染整合

模板內建渲染 API,可透過 Remotion Lambda 或本地 CLI 觸發渲染:

// app/api/render/route.ts
import { renderMediaOnLambda } from "@remotion/lambda/client";
import { NextResponse } from "next/server";
 
export async function POST(request: Request) {
  const { scenes } = await request.json();
 
  const { renderId } = await renderMediaOnLambda({
    region: "ap-northeast-1",
    functionName: process.env.REMOTION_LAMBDA_FUNCTION_NAME!,
    composition: "DynamicVideo",
    inputProps: { scenes },
    codec: "h264",
    imageFormat: "jpeg",
  });
 
  return NextResponse.json({ renderId });
}

客製化方向

基於此模板,常見的客製化需求包括:

  • 新增場景類型:在 remotion/scenes/ 中新增元件,並在 store 和屬性面板中加入對應設定
  • 整合素材上傳:串接 AWS S3、Cloudflare R2 或其他物件儲存服務
  • 使用者認證:加入 Clerk、NextAuth 等認證系統,支援多使用者協作
  • 專案儲存:將編輯狀態存至資料庫(PostgreSQL、PlanetScale 等),支援儲存草稿和歷史版本

延伸閱讀