资讯动态

DSH+V4.1F+Remotion:程序化视频批量生产实战指南

发布时间:2026/10/21 7:20:16 来源:尧图企业网站定制
1. 这套组合到底在解决什么问题第一次看到“DSH搭配V4.1FRemotion”这个组合的时候我正瘫坐在椅子上刷别人的作品展示脑子里只有一个念头这玩意儿真的是用代码跑出来的不是某个后期团队熬了三个通宵剪出来的后来自己上手把这条链路完整跑了一遍才发现这套方案的核心价值根本不在于“炫技”而在于它把视频生产从手工劳动变成了可复用、可参数化、可批量化的工程流程。先把三个关键词拆开说清楚不然后面没法聊。DSH在这里指的是一套数据脚本处理层你可以把它理解成“把原始素材和业务数据翻译成视频能吃的结构化输入”的中间件V4.1F是一套版本化的视觉规范框架负责定义画面里的栅格、动效曲线、字体层级和色彩令牌Remotion则是把React组件渲染成视频帧的运行时。三者叠在一起形成了一条从“数据”到“规范”再到“渲染”的完整流水线。这套东西能做什么举几个我实际跑过的场景把一份结构化的数据报表自动生成带动态图表和转场的周报视频把一批商品信息批量渲染成统一风格的短视频素材把一段带时间戳的字幕数据变成带动画强调的解说视频。适合谁来参考如果你是会写React但没碰过视频渲染的前端或者你是做内容自动化但被传统剪辑软件卡住效率的运营再或者你是想把手里的数据直接变成可视化视频的数据从业者这套链路都值得花时间啃一遍。我一开始也怀疑用代码写视频是不是脱裤子放屁。但当我需要把同一个模板套到两百条数据上、每条都要保证动效节奏一致、字体不跑版、转场不突兀的时候手工剪辑的边际成本是线性增长的而这套方案的边际成本几乎为零。这就是它真正解决的问题把创意劳动和重复劳动分离让模板负责稳定让数据负责变化。2. 整体架构设计与选型逻辑拆解2.1 为什么是这三层而不是别的组合市面上做程序化视频的方案不少有基于时间轴的脚本方案有基于模板引擎的方案也有直接调底层渲染库的方案。我选DSHV4.1FRemotion这个组合是踩过几次坑之后的结果。最早我试过用纯模板引擎加图片序列的方式优点是简单缺点是动效基本靠预渲染的序列帧改一个缓动曲线就要重新导出几百张图迭代一次半小时起步。后来试过直接调底层渲染接口逐帧绘制灵活是灵活但每一帧的布局都要手算坐标写一个稍微复杂的图表动画代码量直接爆炸维护成本高得离谱。Remotion的好处在于它把“帧”变成了React组件的props你可以用写网页的方式写视频布局用flex动效用插值状态用组件树管理。这意味着前端那套工程化能力——组件复用、类型检查、热更新——全部可以平移到视频生产上。但Remotion本身只解决了“怎么渲染”没解决“渲染成什么样才规范”和“数据怎么进来”的问题。V4.1F补的就是规范这一层。它把画面拆成了一套设计令牌间距用8的倍数栅格字号用模块化比例动效曲线统一用几组预设的贝塞尔参数颜色用语义化的令牌而不是硬编码色值。这样做的好处是当你要调整整体风格时改的是令牌而不是几百个组件里的散落数值。我实测下来把主色从蓝改成橙只动了三个令牌文件全片所有元素同步更新没有一处漏改。DSH补的是数据这一层。原始数据往往是脏的、嵌套的、字段命名随意的直接喂给渲染层会导致组件里全是防御性判断。DSH的作用是在中间做一次清洗和映射把业务数据转成渲染层约定的schema同时做校验和默认值填充。这样渲染组件只需要关心“怎么画”不需要关心“数据长什么样”。2.2 三层之间的契约怎么定这三层能串起来关键是层与层之间的接口要稳定。我的做法是DSH输出一份符合JSON Schema的渲染描述文件V4.1F定义这份描述文件里每个字段对应的视觉语义Remotion负责消费这份描述并渲染。具体来说DSH输出的每个场景对象包含几个固定字段场景类型、持续时间、进入动效、退出动效、内容载荷。内容载荷里再按场景类型细分比如图表场景有数据系列和坐标轴配置文字场景有标题正文和强调词位置。V4.1F则规定所有场景的默认进入动效是淡入加上移持续时间是0.4秒缓动曲线用预设的easeOutCubic所有标题字号是基准字号的1.5倍行高是1.4。这样定契约的好处是当我要新增一种场景类型时只需要在DSH里加一个映射规则在V4.1F里加一组视觉令牌在Remotion里加一个组件三处改动互不干扰。我试过在一天之内加了四种新场景没有动到已有场景的任何代码这就是契约稳定的价值。注意契约一旦定下来就不要轻易改字段名改一次就要同步改三层很容易漏。我一般会在项目根目录放一份schema文件三层都引用它改的时候有类型检查兜底。2.3 这套方案的优势和它不适合的场景优势前面说了不少总结成三条迭代快因为动效和布局都是代码改完热更新直接看效果一致性强因为规范是集中定义的不会出现这个场景字体大一点那个场景小一点的情况可批量化因为数据驱动换一份数据就是一条新视频。但它不适合所有场景。如果你要做的是实拍剪辑、复杂调色、多机位切换这套方案帮不上忙那是传统非线性编辑工具的领域。如果你要做的是高度艺术化、每一帧都要手工微调的动画用代码写反而比手K关键帧更慢。这套方案最适合的是结构清晰、模板化程度高、需要批量生产的视频类型比如数据播报、产品展示、教学课件、社媒短视频模板。我个人的判断标准是如果这个视频的80%内容可以用“填空”的方式描述那它就适合这套方案如果80%的内容需要“即兴创作”那还是老老实实开剪辑软件。3. 核心细节解析与实操要点3.1 DSH层的数据清洗与映射规则DSH这一层最容易被低估很多人觉得不就是把数据转个格式吗有什么难的。但我实际做下来这一层花的时间占整个项目的一半以上因为原始数据的坑实在太多了。第一个坑是时间字段的格式不统一。有的数据源给的是毫秒时间戳有的是ISO字符串有的是“3分20秒”这种自然语言。我的做法是在DSH里统一转成帧号因为Remotion是按帧渲染的所有时间最终都要落到帧上。转换公式是帧号 秒数 × 帧率。这里有个细节帧率要和Remotion的配置保持一致我一般用30帧因为它在大多数场景下足够流畅渲染压力也比60帧小一半。第二个坑是数值字段的量纲不一致。比如同样是“销售额”有的数据源单位是元有的是万元有的是带货币符号的字符串。DSH里要做一次归一化统一转成基准单位同时记录原始量纲用于显示格式化。我一般会在schema里加一个displayFormat字段渲染层根据这个字段决定是显示“1.2万”还是“12000”。第三个坑是缺失值和异常值。数据里经常有null、空字符串、负数、超大值。我的处理策略是缺失值用同字段的中位数填充异常值用分位数截断同时在渲染描述里标记哪些点是填充的渲染层可以选择用虚线或浅色表示。这样既保证了图表不断裂又不会误导观众。// DSH层的一个简化映射示例 function normalizeTime(raw, fps) { if (typeof raw number) return Math.round(raw / 1000 * fps); if (typeof raw string raw.includes(:)) { const parts raw.split(:).map(Number); const seconds parts[0] * 60 parts[1]; return Math.round(seconds * fps); } return 0; } function normalizeValue(raw, unit) { const num parseFloat(String(raw).replace(/[^\d.-]/g, )); if (isNaN(num)) return null; const multipliers { 元: 1, 万元: 10000, 亿元: 100000000 }; return num * (multipliers[unit] || 1); }实操心得DSH层一定要写单元测试。我一开始偷懒没写结果有一次数据源改了一个字段名整条视频渲染出来全是空白排查了两个小时才发现是映射规则没更新。后来我给每个映射函数都写了测试用例改数据源的时候先跑测试五分钟就能定位问题。3.2 V4.1F的视觉规范怎么落地成代码V4.1F是一套视觉规范但规范如果只写在文档里执行的时候一定会走样。我的做法是把规范全部转成代码里的常量让规范成为唯一事实来源。具体来说我建了一个tokens目录里面分几个文件spacing定义间距阶梯typography定义字号和行高motion定义动效曲线和时长color定义语义色板。每个文件导出一个对象组件里只引用这些对象不写任何魔法数字。间距阶梯我用的是8的倍数4、8、16、24、32、48、64。为什么是8因为大多数屏幕尺寸和视频分辨率都能被8整除用8的倍数做间距元素对齐的时候不会出现半像素模糊。字号我用的是模块化比例基准16比例1.25得到16、20、25、31、39、49。这样标题和正文之间有明确的层级关系不会出现“标题只比正文大一点点”的尴尬。动效曲线我预设了四组easeOutCubic用于进入easeInCubic用于退出easeInOutQuad用于循环spring用于强调。每组曲线对应一组贝塞尔参数组件里通过名字引用。我试过用默认的linear出来的效果非常机械换成easeOutCubic之后整个视频的质感提升了一个档次。// tokens/motion.js export const motion { enter: [0.215, 0.61, 0.355, 1], exit: [0.55, 0.055, 0.675, 0.19], loop: [0.455, 0.03, 0.515, 0.955], spring: { damping: 12, stiffness: 180 } }; export const duration { fast: 0.2, normal: 0.4, slow: 0.8 };注意动效时长不要超过1秒除非是刻意的慢镜头效果。我见过很多新手把进入动效设成1.5秒结果视频节奏拖沓得让人想关掉。0.3到0.5秒是大多数场景的甜点区。3.3 Remotion组件的拆分粒度与复用策略Remotion组件拆得太粗复用性差拆得太细组合起来又很繁琐。我摸索出来的粒度是一个组件对应一个视觉语义单元。什么叫视觉语义单元比如“一个带标题的图表卡片”是一个单元“一个带图标的列表项”是一个单元“一个带背景的转场遮罩”是一个单元。这些单元在不同场景里会重复出现拆成组件之后就可以复用。我一般会分三层原子组件、分子组件、场景组件。原子组件是最基础的比如Text、Box、Icon只负责渲染不负责布局。分子组件是原子组件的组合比如ChartCard、ListItem、TransitionMask负责一个完整的视觉单元。场景组件是分子组件的组合比如BarChartScene、TextScene、ListScene负责一个完整的视频片段。这样拆的好处是当我要调整所有卡片的圆角时只改ChartCard一个组件当我要调整某个场景的布局时只改那个场景组件不会影响到其他场景。我实测下来一个中等复杂度的视频项目组件数量控制在30到50个之间比较合适太少会导致组件臃肿太多会导致组合复杂。// 分子组件示例带标题的图表卡片 const ChartCard ({ title, children, delay 0 }) { const frame useCurrentFrame(); const opacity interpolate(frame, [delay, delay 15], [0, 1], { extrapolateRight: clamp }); return ( AbsoluteFill style{{ opacity }} div style{{ padding: spacing.lg }} Text style{{ fontSize: typography.h3, marginBottom: spacing.md }} {title} /Text {children} /div /AbsoluteFill ); };3.4 帧率、分辨率与渲染性能的平衡这三个参数直接决定了渲染时间和成片质量需要根据实际场景权衡。帧率方面30帧适合大多数内容60帧适合有快速运动或需要慢放的场景。我做过对比测试同一个项目从30帧切到60帧渲染时间增加了约80%但肉眼观感提升在普通播放速度下并不明显。所以我的默认选择是30帧只有在有高速运动镜头时才切60帧。分辨率方面1080p是安全选择4K适合大屏展示但渲染时间翻四倍。我的做法是先用低分辨率预览确认动效和节奏没问题之后再切高分辨率正式渲染。Remotion支持通过配置切换分辨率不需要改代码。渲染性能方面最大的瓶颈通常是DOM节点数量和复杂CSS效果。我踩过的坑是在一个场景里放了200个DOM节点做粒子效果结果单帧渲染时间从50毫秒飙升到800毫秒。后来改用canvas绘制粒子单帧降到80毫秒。所以我的经验是超过50个动态元素就用canvas不要用DOM。参数推荐值适用场景渲染时间参考帧率30fps大多数内容基准帧率60fps高速运动、慢放约1.8倍分辨率1920x1080通用基准分辨率3840x2160大屏展示约4倍并发数CPU核心数-1批量渲染线性加速4. 完整实操流程与关键环节实现4.1 环境搭建与项目初始化先把基础环境搭起来。Node版本建议用18以上的LTS因为Remotion的一些依赖需要较新的运行时。包管理器我用的是pnpm因为它的硬链接机制在装大量依赖时比npm快不少磁盘占用也小。初始化项目的命令很简单但有几个配置项需要提前想清楚。第一个是视频的宽高比16:9适合横屏平台9:16适合竖屏1:1适合信息流。这个一旦定下来后面改起来很麻烦因为所有布局都是按比例算的。第二个是帧率前面说了默认30。第三个是输出格式Remotion支持mp4、webm、gif等我一般用mp4因为兼容性最好。# 初始化项目 pnpm create video my-video-project cd my-video-project # 安装核心依赖 pnpm add remotion remotion/cli remotion/bundler # 安装辅助工具 pnpm add -D typescript types/react初始化之后项目结构大概是这样的src目录放组件public目录放静态资源remotion.config.ts放全局配置。我一般会再加一个data目录放DSH层的映射脚本一个tokens目录放V4.1F的规范常量。实操心得把remotion.config.ts里的concurrency设成CPU核心数减一留一个核心给系统不然渲染的时候电脑会卡到没法干别的。我试过设成核心数结果渲染时鼠标都拖不动。4.2 DSH层的数据管道搭建数据管道我一般分四步读取、清洗、映射、校验。读取这一步数据源可能是CSV、JSON、数据库查询结果。我一般统一转成JSON数组再往下走因为JSON的结构最灵活嵌套和数组都能表达。清洗这一步处理前面说的时间格式、量纲、缺失值、异常值。我一般会写一个通用的清洗函数库每个项目复用。清洗完之后数据应该是一份“干净”的表格每行一条记录每列一个字段字段类型明确。映射这一步把清洗后的数据转成渲染描述。这一步是项目相关的每个项目的映射规则不一样。我一般会写一个mapToScenes函数输入是清洗后的数据输出是场景数组。校验这一步用JSON Schema验证输出是否符合契约。如果不符合抛出明确的错误信息指出哪个字段有问题。这一步能省掉大量调试时间因为问题在数据层就暴露了不会等到渲染出来才发现。// DSH层的完整管道示例 import { z } from zod; const SceneSchema z.object({ type: z.enum([bar, line, text, list]), duration: z.number().positive(), enter: z.string().default(fadeUp), exit: z.string().default(fadeOut), payload: z.record(z.any()) }); const VideoSchema z.object({ title: z.string(), scenes: z.array(SceneSchema).min(1) }); export function buildVideo(rawData, config) { const cleaned cleanData(rawData); const scenes mapToScenes(cleaned, config); const video { title: config.title, scenes }; return VideoSchema.parse(video); }4.3 V4.1F规范层的令牌注入令牌注入的方式我试过两种一种是直接用import引入常量对象另一种是通过React Context注入。前者简单直接后者灵活但多一层抽象。我最终选了直接import因为视频项目的令牌基本不会在运行时变化Context带来的灵活性用不上反而增加了组件的心智负担。直接import的话组件里写spacing.lg、typography.h2、motion.enter一眼就能看出用的是哪个令牌。令牌的命名我遵循语义化原则不用具体数值命名。比如spacing.lg而不是spacing.24typography.h2而不是typography.32。这样当数值调整时名字不用改引用处也不用改。我试过用数值命名结果把基准从16改成18之后所有名字都对不上了改了一下午。// tokens/index.js export const spacing { xs: 4, sm: 8, md: 16, lg: 24, xl: 32, xxl: 48 }; export const typography { h1: 49, h2: 39, h3: 31, body: 20, caption: 16 }; export const color { bg: #0a0a0a, surface: #1a1a1a, primary: #3b82f6, text: #f5f5f5, muted: #a3a3a3 };4.4 Remotion场景组件的实现与组合场景组件是最终被Remotion消费的组件。每个场景组件接收一个scene对象作为props根据scene.type决定渲染哪个分子组件。我一般会写一个SceneRenderer作为分发器根据type字段路由到具体的场景组件。这样在根组件里只需要遍历scenes数组每个场景交给SceneRenderer处理不需要写一堆条件判断。// SceneRenderer.jsx import { BarChartScene } from ./scenes/BarChartScene; import { TextScene } from ./scenes/TextScene; import { ListScene } from ./scenes/ListScene; const sceneMap { bar: BarChartScene, text: TextScene, list: ListScene }; export const SceneRenderer ({ scene }) { const Component sceneMap[scene.type]; if (!Component) { throw new Error(Unknown scene type: ${scene.type}); } return Component {...scene.payload} duration{scene.duration} /; };根组件里用Series组件把场景按顺序排列每个场景的时长由duration字段决定。Series会自动处理场景之间的衔接不需要手动算偏移量。// Root.jsx import { Composition, Series } from remotion; import { SceneRenderer } from ./SceneRenderer; import videoData from ../data/video.json; export const Video () { return ( Series {videoData.scenes.map((scene, i) ( Series.Sequence key{i} durationInFrames{scene.duration * 30} SceneRenderer scene{scene} / /Series.Sequence ))} /Series ); }; export const RemotionRoot () { return ( Composition idMainVideo component{Video} durationInFrames{videoData.scenes.reduce((sum, s) sum s.duration * 30, 0)} fps{30} width{1920} height{1080} / ); };4.5 渲染输出与批量生产单条视频的渲染命令很简单但批量生产需要额外处理。我的做法是写一个脚本遍历数据源为每条数据生成一份渲染描述然后调Remotion的渲染接口逐条输出。批量渲染的关键是并发控制。Remotion本身支持并发渲染多个composition但并发数太高会导致内存溢出。我一般设成2到4具体取决于机器配置和视频复杂度。我试过设成8结果16G内存的机器直接卡死。// batch-render.js import { bundle } from remotion/bundler; import { renderMedia, selectComposition } from remotion/renderer; import { buildVideo } from ./dsh/pipeline; import rawData from ./data/raw.json; const CONCURRENCY 2; async function renderOne(dataItem, index) { const videoData buildVideo(dataItem, { title: dataItem.title }); const composition await selectComposition({ serveUrl: bundleUrl, id: MainVideo, inputProps: { videoData } }); await renderMedia({ composition, serveUrl: bundleUrl, codec: h264, outputLocation: out/video-${index}.mp4, concurrency: CONCURRENCY }); } const bundleUrl await bundle({ entryPoint: ./src/index.ts }); for (let i 0; i rawData.length; i) { await renderOne(rawData[i], i); }注意批量渲染之前先用一条数据跑通全流程确认输出没问题再跑全量。我踩过的坑是直接跑全量结果渲染到第50条才发现字体加载失败前面49条全白跑了。5. 常见问题与排查技巧实录5.1 渲染出来字体不对怎么办这是最高频的问题。原因通常是字体文件没有正确加载。Remotion在渲染时会启动一个无头浏览器如果字体是通过网络加载的可能因为网络问题或跨域限制加载失败。我的解决方案是把字体文件下载到public目录用font-face在全局CSS里声明并且用font-display: block确保字体加载完成前不渲染文字。另外在Remotion的配置里加上delayRender等字体加载完成再开始渲染。// 字体加载等待 import { continueRender, delayRender } from remotion; const waitForFont delayRender(); const font new FontFace(CustomFont, url(/fonts/custom.woff2)); font.load().then(() { document.fonts.add(font); continueRender(waitForFont); });5.2 动效卡顿或不流畅怎么排查动效卡顿通常有三个原因帧率不够、插值曲线不对、渲染性能不足。先看帧率如果设的是30帧但动效变化很快肉眼会觉得卡。这时候要么提高帧率要么放慢动效。我一般先试放慢动效因为提高帧率的代价是渲染时间翻倍。再看插值曲线linear曲线在视觉上会显得机械换成easeOutCubic或spring会自然很多。但spring参数如果设得太硬会有过冲看起来像在抖。我一般用damping 12、stiffness 180这组参数实测下来比较稳。最后看渲染性能如果单帧渲染时间超过100毫秒播放时就会掉帧。这时候要检查DOM节点数量和CSS效果。阴影、模糊、渐变这些效果很吃性能能不用就不用。问题现象可能原因排查方法解决方案字体显示为默认字体字体未加载检查network面板本地化字体delayRender动效机械用了linear曲线检查interpolate配置换easeOutCubic动效抖动spring参数过硬检查damping值调高damping到12以上播放掉帧单帧渲染超100ms打时间戳测量减少DOM节点改用canvas颜色不一致硬编码色值全局搜索hex值统一用color令牌5.3 批量渲染时内存溢出怎么处理内存溢出通常是因为并发数太高或者单个composition的DOM节点太多没有释放。我的处理策略是把并发数降到2并且在每个视频渲染完成后手动触发垃圾回收。如果还是溢出就要检查是不是有全局状态没有清理。Remotion在渲染每个composition时会重新挂载组件树但如果组件里有全局变量或闭包引用可能会导致内存泄漏。我一般会在组件卸载时清理定时器和事件监听。实操心得批量渲染时加一个进度日志每渲染完一条就输出一条记录。这样即使中途崩了也知道渲染到哪了不用从头再来。我一般会把已完成的文件名写到一个临时文件里重启时跳过已完成的。5.4 数据更新后视频没变化怎么排查这个问题通常是缓存导致的。Remotion在开发模式下会缓存bundle数据更新后如果bundle没重新构建渲染出来的还是旧数据。我的做法是在数据管道的入口加一个版本号每次数据更新时版本号递增bundle的hash也会变缓存自动失效。另外在开发模式下用--watch参数数据文件变化时自动重新构建。还有一种可能是数据映射函数有bug把新数据映射成了旧结构。这时候要打印映射前后的数据对比看看是哪一步出了问题。我一般会在映射函数里加console.log确认输入输出符合预期。5.5 输出视频体积太大怎么压缩视频体积主要取决于码率和分辨率。Remotion默认的码率比较高输出文件会比较大。我一般会把码率设成8Mbps左右1080p下画质和体积比较平衡。如果还需要更小可以降低分辨率到720p或者用h265编码。h265比h264体积小约40%但兼容性稍差一些老设备可能不支持。我一般用h264因为兼容性优先。// 码率配置 await renderMedia({ composition, serveUrl: bundleUrl, codec: h264, crf: 23, // 质量因子18-28之间越大体积越小画质越差 outputLocation: out/video.mp4 });6. 我在这条链路上踩过的坑和总结的经验6.1 不要一开始就追求完美规范我刚开始做的时候花了一周时间设计V4.1F的规范把间距、字号、颜色、动效全部定义得清清楚楚结果真正开始写组件的时候发现很多规范在实际场景里根本用不上或者需要频繁调整。后来我改了策略先用最简规范跑通一个场景然后根据实际需要逐步补充规范。这样规范是长出来的不是设计出来的每一条都有实际场景支撑不会出现“定义了但没人用”的情况。6.2 数据校验要前置我踩过最大的坑是数据问题在渲染阶段才暴露。有一次数据源里有一个字段是nullDSH层没校验映射函数直接报错但错误信息很模糊排查了半天才发现是数据问题。后来我把校验全部前置到DSH层用zod做schema校验数据不符合契约就直接抛错错误信息明确指出哪个字段有问题。这样问题在数据层就解决了不会带到渲染层。6.3 组件复用要有度组件拆得太细会导致组合复杂拆得太粗会导致复用性差。我摸索出来的平衡点是一个组件如果会在三个以上场景里用到就拆成独立组件如果只用一两次就内联在场景组件里。另外组件的props不要太多超过7个就要考虑拆分了。我见过一个组件有15个props用的时候要对着文档一个个填非常痛苦。6.4 渲染时间要提前估算渲染时间跟视频时长、分辨率、帧率、复杂度都相关。我一般会先渲染10秒的样片测量单帧渲染时间然后乘以总帧数估算总时间。如果总时间超过可接受范围就要优化。优化的方向有三个降低分辨率、减少DOM节点、简化CSS效果。我一般先试减少DOM节点因为这是最有效的。把一些静态元素合并成一张图片或者用canvas绘制能大幅降低渲染时间。6.5 版本管理要严格这套方案涉及三层每层都有自己的版本。DSH的映射规则、V4.1F的规范令牌、Remotion的组件任何一层改动都可能影响最终输出。我一般会用monorepo管理三层放在同一个仓库里用changesets管理版本。每次改动都要记录变更日志说明改了什么、为什么改、影响范围是什么。这样当输出不符合预期时可以快速定位是哪次改动导致的。6.6 最后的个人体会这套方案最大的价值不是技术本身而是它改变了我的工作方式。以前做视频是“打开软件、拖素材、调参数、导出”现在是“写数据、跑脚本、等渲染”。前者是手工艺后者是工程化。手工艺的上限取决于个人技艺工程化的上限取决于系统设计。我现在的习惯是接到视频需求先问三个问题这个视频有多少内容是重复的数据来源是什么需要多久更新一次如果重复度高、数据驱动、需要频繁更新就用这套方案如果是一次性的创意视频还是老老实实开剪辑软件。最后分享一个小技巧在开发阶段用Remotion的预览功能实时看效果不要每次都渲染完整视频。预览是实时的改完代码立刻能看到变化效率比渲染高十倍。只有在确认效果没问题之后才跑完整渲染。这个习惯帮我省了大量等待时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑