用 Remotion 批量生成多语言视频:一条脚本跑通 12 种语言的出片链路
2026/8/30 9:11:09 网站建设 项目流程

用 Remotion 批量生成多语言视频:一条脚本跑通 12 种语言的出片链路

【免费下载链接】remotion🎥 Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion

一条 40 秒的产品宣传片,要出英、西、中 3 个配音版本。手动路线是:在剪辑软件里逐版换旁白、对字幕、调画面时长,一版半小时,改一句文案就得全量重来。把这件事交给脚本,流程变成:改一份配置表,跑一次自动化渲染,半小时后三个 MP4 排好队躺在输出目录里。Remotion 是一个用 React 编写视频的开源框架,它的渲染器支持把同一套组件按不同参数批量生成多语言视频,这正是本链路的全部基础。

拆成三块看:组件即模板、配置表驱动、渲染管线

视频模板就是一个可传参的组件

它是什么:在 Remotion 里,一段视频对应一个 React 组件加一组inputProps,组件决定画面结构,props 决定具体内容。为什么这样设计:语言差异本来只存在于文案、配音文件、字体这三样东西上,把它们抽成 props,剩下的布局、动画、节奏对所有语言完全一致,一次改动同时生效。你在哪会碰到:写第一个视频组件的那天——从第一版开始就把语言相关的部分参数化,比事后重构便宜得多。

一份配置表驱动 N 个语言版本

它是什么:一张表,每行一个语言:语言代码、文案 key、TTS 音色 ID、字体名。为什么这样设计:多语言批量生成的失败点大多是"组件里写死了某一版的字符串",把文案和音色映射挪进配置表后,新增语言不再需要碰组件代码。你在哪会碰到:第 2 步准备配音和字幕时,表和文件目录的结构都由这张表决定。

渲染管线:同一入口,参数化出片

它是什么:Remotion 的渲染器提供renderMedia,输入 composition 名加inputProps,输出一个 MP4。为什么这样设计:批量生成不需要任何新机制,只是同一个调用传不同参数重复 N 次,再配合delayRender/continueRender控制并发。你在哪会碰到:第 4 步的批量脚本,整段不超过二十行。

动手链路:从一张配置表到 N 个 MP4

第 1 步:把语言清单落成一张配置表

从需求文档里抽出每一行的四样东西:语言代码、展示名、文案 key、TTS 音色 ID。文案统一放在一个字典里,按语言分组。示例结构:

export const languages = { en: { name: 'English', voice: 'en-US-Jenny', copy: 'copy/en' }, es: { name: 'Español', voice: 'es-ES-Elvira', copy: 'copy/es' }, zh: { name: '中文', voice: 'zh-CN-Xiaoxiao', copy: 'copy/zh' }, };

为什么:这张表是后面所有环节的唯一数据源,配音命名、字幕目录、渲染输出名全部由它推导,加语言只加一行。

第 2 步:跑 TTS 语音合成,产出带时间戳的音频

每条文案按语种各调一次 TTS,得到音频文件,同时保存返回的时长或词级时间戳。为什么:时长决定每段画面的长度,词级时间戳决定字幕逐词对齐;只留音频不留时间戳,第 5 节的字幕问题就会找上门。文件按"语言-段落名"命名,渲染时按名取用。

第 3 步:把语言接进组件

组件内用 props 选择文案与音色,音频用<Audio>引入,字幕用 TTS 的时间戳对齐:

import {NotoSansSC} from '@remotion/google-fonts/NotoSansSC'; import {Inter} from '@remotion/google-fonts/Inter'; export const MyVideo = ({lang}: {lang: 'en' | 'es' | 'zh'}) => { const font = lang === 'zh' ? NotoSansSC.loadFont() : Inter.loadFont(); const copy = COPIES[lang]; return ( <div style={{fontFamily: font}}> <Text>{copy.headline}</Text> <Audio src={staticFile(`audio/${lang}/headline.mp3`)} /> </div> ); };

为什么:字体必须显式加载,中文和西文的字体栈完全不同;在本地预览里逐个语言点一遍,能提前暴露布局问题。

第 4 步:批量渲染,自动化出片

一个脚本遍历配置表,每条调用一次renderMedia

import {renderMedia, selectComposition} from '@remotion/renderer'; for (const [code, cfg] of Object.entries(languages)) { const composition = await selectComposition({ env: {entryPoint: 'src/index.ts'}, id: 'MyVideo', inputProps: {lang: code}, }); await renderMedia({ composition, inputProps: {lang: code}, serveUrl, codec: 'h264', output: `out/${code}.mp4`, }); }

为什么:失败只记录日志不中断整批,跑完后统一检查产物数量和时长是否符合预期,比一边跑一边看输出可靠得多。

避坑与调优

字幕对不上口型?用 TTS 的词级时间戳驱动字幕

问题:按字数估算时间轴排字幕,不同语种的语速差异让中版本字幕提前、英版本拖后。后果:音画错位两三秒,直接毁掉整个版本的观感。处理思路:合成时开启词级时间戳,用现成工具把 transcript 转成字幕结构——仓库里的packages/elevenlabs/src/index.ts导出的elevenLabsTranscriptToCaptions就是干这个的,字幕完全跟着音频时间走。

文本溢出和断行?先固定容器,再按语种调字体

问题:德语短语比英语长 40%,中文没有词间空格,直接复用英文样式必然溢出或断行位置离谱。后果:标题被截断、换行把关键信息劈成三段。处理思路:文案容器宽度固定,按语种映射不同字体与字号——@remotion/google-fonts里 1800 多个字体按语种各挑一个(中文如NotoSansSC、西文如Inter),在本地预览里逐个语言过一遍再进批量渲染。

渲染排队太慢?并发 + 缓存两步走

问题:12 种语言串行渲染要 4 小时;无脑全并行,浏览器是共享资源,每个都变慢甚至内存溢出。后果:批量任务卡死在夜里,早上看输出目录一片空白。处理思路:并发数压在 2 到 3,配合delayRender/continueRender排队;TTS 音频按"语言-段落"做本地缓存,合成前先查文件是否已存在,命中就跳过,迭代文案时只有改过的条目重新付费重合成。

落地参考:多语言产品宣传片的完整配置

场景:品牌宣传片,结构是 logo 开场、三句卖点、产品截图、行动号召,文案与 TTS 音色放配置表,一次跑 12 条语言,每条输出out/<code>.mp4。验收只查三件事:音画是否同步、字幕是否溢出、总时长是否一致。可直接照抄的配置清单:

  • 文案 key:headline/points[3]/cta,每种语言各一份
  • TTS 音色:每语种一个 ID,写入配置表
  • 字体映射:中文NotoSansSC,西文Inter,其余语种按需
  • 音频缓存目录:audio/<lang>/<key>.mp3,先查后合成
  • 批量脚本:并发 2 到 3,单条失败记录后继续,跑完核对产物数

现在就能做三件事:把现有视频拆成"语言相关"和"语言无关"两部分,只参数化前者;挑 2 个最急的语言跑通配置表到 MP4 的完整链路;给 TTS 建一层按语言命名的本地缓存。剩下的语言,只是往表里加行的事。

【免费下载链接】remotion🎥 Make videos programmatically with React项目地址: https://gitcode.com/GitHub_Trending/re/remotion

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询