比特之外

Remotion 教程 13:从模板到批量出片

当一个 Remotion 模板稳定后,下一步通常不是继续堆动画,而是把它接进产品流程:预览、提交任务、渲染、保存、下载。

最小链路是:

Web 表单 -> @remotion/player 预览 -> 生成任务 -> @remotion/renderer 渲染 -> 对象存储 -> 下载链接

前端负责让用户确认内容。后端负责稳定出片。

Player 负责预览

@remotion/player 可以把 Composition 放到网页里,让用户看到模板效果。它适合用在视频生成工具、内容编辑器和模板市场。

最小用法大概是:

import React from "react";
import { Player } from "@remotion/player";
import { TalkingVideo } from "./TalkingVideo";
 
export const Preview = () => {
  return (
    <Player
      component={TalkingVideo}
      durationInFrames={540}
      fps={30}
      compositionWidth={1080}
      compositionHeight={1920}
      controls
      inputProps={{
        title: "用 Remotion 生成可复现的视频",
        themeColor: "#38bdf8",
      }}
    />
  );
};

Player 适合预览,不适合承担最终出片任务。最终出片应该放到服务端或渲染环境。

Renderer 负责出片

@remotion/renderer 可以在 Node 环境中调用渲染流程。

典型流程是:

import { bundle } from "@remotion/bundler";
import { getCompositions, renderMedia } from "@remotion/renderer";
 
const serveUrl = await bundle({
  entryPoint: "src/index.ts",
});
 
const compositions = await getCompositions(serveUrl, {
  inputProps: {
    title: "用 Remotion 生成可复现的视频",
    themeColor: "#38bdf8",
  },
});
 
const composition = compositions.find((item) => item.id === "FinalTalkingVideo");
 
if (!composition) {
  throw new Error("找不到 FinalTalkingVideo");
}
 
await renderMedia({
  composition,
  serveUrl,
  codec: "h264",
  outputLocation: "out/final.mp4",
  inputProps: {
    title: "用 Remotion 生成可复现的视频",
    themeColor: "#38bdf8",
  },
});

这段代码说明了后端渲染的核心:先 bundle,再拿 Composition,再 renderMedia。

为什么需要队列

视频渲染比普通接口慢,也更消耗 CPU 和内存。不要让用户请求直接阻塞到渲染完成。

更稳的方式是把渲染放进队列:

用户提交表单
-> 创建 render job
-> job 进入队列
-> worker 拉取任务
-> renderMedia 出片
-> 上传对象存储
-> 更新任务状态

任务状态可以这样设计:

type RenderStatus =
  | "queued"
  | "rendering"
  | "completed"
  | "failed";
 
type RenderJob = {
  id: string;
  compositionId: string;
  inputProps: unknown;
  status: RenderStatus;
  outputUrl?: string;
  errorMessage?: string;
};

存储和下载

渲染完成后,不建议只把文件留在本地磁盘。通常会上传到对象存储,例如 S3、R2、OSS 或 GCS。

数据库里记录:

  • 任务 ID。
  • 输入参数。
  • 模板版本。
  • 渲染状态。
  • 输出文件地址。
  • 错误信息。

这样用户刷新页面后,也能看到任务状态和下载链接。

什么时候上云渲染

如果只是少量视频,本地服务器或容器就够了。

如果每天有大量任务,再考虑:

  • Remotion Lambda。
  • Cloud Run。
  • ECS / Docker worker。
  • 专门的渲染集群。

不要一开始就把架构做太重。先把单机渲染链路跑稳,再扩容。

示例项目位置

这篇文章对应示例项目里的:

Composition: LessonPlatformRendering
文件: src/lessons/PlatformRendering.tsx
最终模板: FinalTalkingVideo

LessonPlatformRendering 展示的是从预览到出片的核心链路。真正落地时,还需要补上表单、队列、数据库、对象存储和渲染 worker。

最后一篇集中整理工程踩坑:版本、浏览器、缓存和渲染稳定性。

本文标签