錄製器模板
使用 Remotion 的 Recorder 模板快速建立螢幕錄製加工具,結合程式碼高亮、自動字幕與品牌化輸出。
錄製器模板
Recorder Template 是 Remotion 為技術教學影片、產品展示和開發者內容創作設計的起始模板。它將螢幕錄影與 Remotion 的後製能力結合,讓你可以用程式碼控制的方式,快速為錄製影片加上字幕、品牌識別、程式碼高亮框和章節標記。
適用場景
- 技術教學影片:為程式碼教學自動加上語法高亮標注
- 產品 Demo:在螢幕錄製上疊加說明文字和品牌元素
- 線上課程:自動生成字幕,降低後製門檻
- 開發者內容:用統一風格批次製作技術短影音
模板功能
- 螢幕錄製整合:匯入 mp4 錄製檔,自動對齊時間軸
- 自動字幕:整合 Whisper 轉錄,逐字同步顯示
- 程式碼高亮框:在特定時間點疊加語法高亮的程式碼片段
- 章節標記:自動在影片底部顯示目前章節標題
- 品牌化背景:客製化背景、Logo 和色彩主題
- 一鍵渲染:輸出適合 YouTube、Twitter、LinkedIn 的影片規格
快速開始
npx create-video@latest --template recorder
cd my-recorder-video
npm install設定環境變數:
# .env.local
OPENAI_API_KEY=your-openai-api-key工作流程
- 將你的螢幕錄製影片放到
public/目錄 - 執行轉錄腳本生成字幕
- 在
src/config.ts中設定章節和程式碼高亮 - 用 Remotion Studio 預覽效果
- 渲染最終影片
# 1. 轉錄字幕
npm run transcribe -- --input public/my-recording.mp4
# 2. 預覽
npm run dev
# 3. 渲染
npx remotion render RecorderVideo out/final.mp4設定檔
整個影片的結構在 src/config.ts 中定義:
// src/config.ts
import { RecorderConfig } from "./types";
export const config: RecorderConfig = {
// 錄製影片來源
videoSrc: "my-recording.mp4",
// 影片基本設定
fps: 30,
width: 1920,
height: 1080,
// 品牌設定
brand: {
name: "我的頻道",
logo: "logo.png",
primaryColor: "#6366f1",
backgroundColor: "#0f0f1a",
},
// 章節定義
chapters: [
{ startMs: 0, title: "簡介" },
{ startMs: 15000, title: "安裝與設定" },
{ startMs: 45000, title: "核心概念" },
{ startMs: 90000, title: "實作範例" },
{ startMs: 150000, title: "總結" },
],
// 程式碼高亮區段
codeHighlights: [
{
startMs: 47000,
endMs: 62000,
code: `npm install remotion\nnpx create-video@latest`,
language: "bash",
title: "安裝指令",
},
{
startMs: 95000,
endMs: 120000,
code: `export const MyComp: React.FC = () => {
const frame = useCurrentFrame();
return <div style={{ opacity: frame / 30 }}>Hello</div>;
};`,
language: "tsx",
title: "基本元件",
},
],
};核心 Composition 結構
// remotion/RecorderVideo.tsx
import { AbsoluteFill, OffthreadVideo, staticFile, useCurrentFrame } from "remotion";
import { config } from "../src/config";
import { Captions } from "./components/Captions";
import { ChapterTitle } from "./components/ChapterTitle";
import { CodeHighlight } from "./components/CodeHighlight";
import { BrandOverlay } from "./components/BrandOverlay";
import captions from "../src/captions.json";
export const RecorderVideo: React.FC = () => {
const frame = useCurrentFrame();
const currentMs = (frame / config.fps) * 1000;
// 找出目前啟用的程式碼高亮
const activeHighlight = config.codeHighlights.find(
(h) => currentMs >= h.startMs && currentMs <= h.endMs
);
// 找出目前章節
const currentChapter = [...config.chapters]
.reverse()
.find((c) => currentMs >= c.startMs);
return (
<AbsoluteFill style={{ backgroundColor: config.brand.backgroundColor }}>
{/* 背景:螢幕錄製影片 */}
<OffthreadVideo
src={staticFile(config.videoSrc)}
style={{ width: "100%", height: "100%" }}
/>
{/* 品牌 Logo 和頻道名稱 */}
<BrandOverlay brand={config.brand} />
{/* 章節標題 */}
{currentChapter && (
<ChapterTitle title={currentChapter.title} />
)}
{/* 程式碼高亮框(出現時疊加在影片上) */}
{activeHighlight && (
<CodeHighlight
code={activeHighlight.code}
language={activeHighlight.language}
title={activeHighlight.title}
/>
)}
{/* 自動字幕 */}
<Captions captions={captions} fps={config.fps} />
</AbsoluteFill>
);
};程式碼高亮元件
// remotion/components/CodeHighlight.tsx
import { interpolate, useCurrentFrame } from "remotion";
import { Highlight, themes } from "prism-react-renderer";
interface CodeHighlightProps {
code: string;
language: string;
title?: string;
}
export const CodeHighlight: React.FC<CodeHighlightProps> = ({
code,
language,
title,
}) => {
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 8], [0, 1], {
extrapolateRight: "clamp",
});
const translateY = interpolate(frame, [0, 8], [20, 0], {
extrapolateRight: "clamp",
});
return (
<div
style={{
position: "absolute",
bottom: 200,
left: 80,
right: 80,
opacity,
transform: `translateY(${translateY}px)`,
borderRadius: 16,
overflow: "hidden",
boxShadow: "0 20px 60px rgba(0,0,0,0.6)",
}}
>
{title && (
<div
style={{
backgroundColor: "#1e1e2e",
padding: "12px 24px",
color: "#cdd6f4",
fontSize: 28,
fontFamily: "monospace",
}}
>
{title}
</div>
)}
<Highlight theme={themes.nightOwl} code={code} language={language}>
{({ style, tokens, getLineProps, getTokenProps }) => (
<pre
style={{
...style,
margin: 0,
padding: "24px 32px",
fontSize: 32,
lineHeight: 1.6,
}}
>
{tokens.map((line, i) => (
<div key={i} {...getLineProps({ line })}>
{line.map((token, key) => (
<span key={key} {...getTokenProps({ token })} />
))}
</div>
))}
</pre>
)}
</Highlight>
</div>
);
};輸出格式選項
針對不同平台,可渲染不同規格:
# YouTube(16:9 Full HD)
npx remotion render RecorderVideo out/youtube.mp4 \
--width=1920 --height=1080
# Twitter/X 短影音(1:1 方形)
npx remotion render RecorderVideoSquare out/twitter.mp4 \
--width=1080 --height=1080
# Instagram Reels / TikTok(9:16 垂直)
npx remotion render RecorderVideoVertical out/reels.mp4 \
--width=1080 --height=1920