看到“Claude Opus 5.5 生成视频”这种说法,我第一反应是版本更新又往多模态靠了一步。点进去仔细一瞧,发现大家其实把概念喊岔了:Claude Opus 5.5 根本不生成视频,它生成的是视频的代码。最终那个能播放的动画文件,是代码在浏览器或渲染引擎里一帧一帧跑出来的。这篇想把这个过程彻底拆开——一条“代码视频五步流水线”,从一句模糊需求到一部成片,每个环节做什么、为什么这么做、踩过什么坑,都捋清楚。适合谁看?想用AI辅助做科普动画、产品演示、数据可视化动效、字幕卡的人,以及所有被“AI直接出片”这句话误导过的同学。
1. 先把概念掰正:说“生成视频”其实是偷懒的说法
1.1 Claude到底在做什么:文字生成、像素生成、代码生成是三条路
先说清楚底层逻辑。大语言模型干的事情,本质上是预测文本序列中的下一个token。你把问题丢进去,它吐出来的是一串token,拼起来是自然语言或者代码。Claude Opus 5.5确实能把复杂需求翻译成结构完整的程序,但它并没有直接输出视频流的能力,也不会在内部偷偷“渲染”几帧画面再塞给你。它输出的是文本字符,仅此而已。
真正能直接生成视频的路线,走的是另一套机制,叫扩散模型或者说像素生成模型。这种模型内部处理的是图像张量,通过在噪声和清晰图像之间做预测,一步步还原出视频帧。你可以把Claude这种语言模型理解成一个编剧,它产出的是剧本;而文生视频模型是摄影师加后期,直接产出画面。编剧写“雨夜,主角撑着黑伞穿过霓虹灯街区”,不等于观众真的看到了雨夜,要让观众看到,还得有人去拍摄、布光、剪辑。放到这里,执行的“摄制组”就是浏览器、Canvas渲染器、ffmpeg这些程序。
所以严格来说,“Claude生成视频”是一个传播中的简化说法,准确的表述是“Claude生成了能渲染成视频的代码”。代码写得好不好、渲染出来效果怎么样,取决于两件事:一是模型的代码能力,二是你给的约束够不够清晰。这就是为什么同一套流程,有人能做出像样的成片,有人只能得到一张黑屏。工具没有变,变化的是一开始那个Prompt和流水线环节的完成度。
1.2 “代码视频”的边界与优势
所谓的“代码视频”,是用编程语言描述每一帧的图形、坐标、颜色和动效,再通过渲染引擎逐帧绘制出来的视频。和传统视频制作、文生视频模型相比,它有几个非常明显的优势,也有很多不擅长的地方。
优势方面:
- 像素级可控。画面里每一个粒子的位置、每一条字幕出现的秒数、背景色的色值,全部由代码显式定义。想要第5秒开始变红,就是一行if语句的事,不会出现“大概在第5秒左右”这种含糊。
- 参数化迭代。视频里所有元素都可以抽成变量,改一个数字重新跑一遍,就是一个新版本。对比文生视频模型,改关键词重新生成往往连构图都变了,代码方案天然适合企业LOGO片头、产品参数展示这类需要精确输出的场景。
- 产物可嵌入。代码视频的源文件本质是HTML、JavaScript、CSS或者Python脚本,体积通常只有几十KB,可以直接嵌入网页、桌面应用或演示文稿,生成MP4只是其中一种导出方式。
- 格式不依赖模型侧限制。分辨率、帧率、时长、导出编码全由自己控制,不会被平台预设的规格卡住。
边界也很明显。代码视频不适合做真实感内容,比如“一只猫从草丛里走出来”这种场景,你没法用几段Canvas代码去模拟猫毛的物理细节和光影变化。它同样不适合复杂的流体、爆炸、布料模拟,这类效果需要专业物理引擎和大量计算资源,强行用前端动画只会卡成PPT。代码视频的强项是抽象化、符号化、数据化的视觉表达——图标的运动、数字变化、地图路径动画、信息图表的转场,这些才是它能发挥最大效率的地方。
搞清楚边界之后,你再回头看那些“用Claude做的视频”,就会发现真正跑得通的案例,无一例外都落在几何动画、文字动效、数据可视化这个范围内。这不是限制,而是路线本身的特性。
2. 五步流水线整体设计:从一句话到成片
2.1 为什么需要一条流水线而不是一步到位
很多人第一次试的时候,直接敲一句“帮我生成一个科技感片头视频”,然后期待Claude吐出一个MP4。结果当然是失望。一次让模型输出完整成品,问题出在哪?
第一个问题是上下文长度。一个15秒的1080P动画,代码量可能接近上千行。模型一次性生成的代码,要同时包含背景绘制、粒子系统、文字排版、时长控制、动画缓动逻辑,任何一处细节写得含糊,成品就会崩。第二个问题是缺乏中间检查点。视频是强时序产物,你没法像看静态图一样一次性审查全部细节,中途任何一步出问题都会累积到最终结果里。第三个问题是代码本身的调试属性,再强的模型也会写出语法错误或者API误用,必须通过执行反馈来修正。
流水线的价值在于把“生成一件成品”拆成“生成五个中间产物”,每个中间产物都有明确的验收标准。出了问题,能精确定位到某个环节,修复成本远低于重新生成整段。用软件工程的话讲,就是把黑盒变成白盒。我实测下来,分环节推进的效率比一次性生成的效率高一倍不止,原因很简单:每步模型的输出任务变简单了,你的审查目标也变清晰了。
2.2 五步分工与交付物速览
废话不多说,先上整体框架,后面每个小节再逐一展开。
| 步骤 | 输入 | 输出交付物 | 验收标准 |
|---|---|---|---|
| 目标拆解 | 一句原始需求 | 场景清单、参数表 | 时长、分辨率、画幅、风格、文案、动效节奏全部明确 |
| 指令设计 | 参数表 | 一段结构化的Prompt文本 | Claude能准确理解角色、任务、约束,不产生歧义 |
| 代码生成 | Prompt文本 | 可运行的HTML/JS或Python脚本 | 打开本地页面无报错,画面元素完整出现 |
| 渲染执行 | 脚本代码 | 动画帧序列或实时播放画面 | 动效节奏正确,帧率达标,无掉帧花屏 |
| 导出封装 | 帧序列、音频素材 | 目标格式成片 | 编码正确,音画同步,清晰度符合要求 |
这五步不是一次性的线性流程,它们是叠代环。实际做片的时候,从第四步或者第五步发现问题,经常要跳回第二步改Prompt再重新生成,跑三五轮才出成品是很正常的事情。
2.3 为什么坚持“代码驱动”而不是“像素生成”
从前面的边界分析已经能看出答案,但我还是想说得再直白一点。像素级生成模型更适合创意探索,你心里只有一个模糊的画面,想看模型能不能给出让人惊喜的构图。但如果目标明确、要素固定,比如“金色文字在黑色背景上从粒子聚合成型”,像素生成模型往往很难精确控住每一帧的内容,容易出现文字变形、笔画错乱、节奏不可控。
代码驱动的核心价值在于“一切皆可推导”。画面的每一个状态都不是随手画的,而是函数计算的输出。这句看着轻描淡写,实际意义非常大:它能让你把动画的每个细节都换算成数学关系。比如粒子聚合速度是缓动函数决定的,文字出场时间是由帧数换算的,运动模糊的程度由随机种子控制。想要某种精确效果就写相应的逻辑,而不是反复抽卡。
另外还有一层现实考量:代码驱动方案的算力成本几乎是零。你自己电脑上的浏览器就能渲染1080P画面,渲染完用ffmpeg压缩成MP4,全程不依赖云端生成服务,也不消耗额外的API配额。对于那些每天要出十几个版本给需求方确认的工作流来说,这点非常关键。
3. 五步流水线实操拆解:每一步都有交付物
3.1 第一步:目标拆解与场景约束
任何视频项目的起点都不是“我想做一个动画”,而是“谁会看、在哪看、看多久”。我习惯用一个框架来整理需求:谁在什么时候看到什么。
“谁”决定风格调性,给老板看的汇报片头要稳重,给学生看的科普动效可以活泼;“在什么时候看到什么”决定信息密度,片头只有3秒就写不了太多字,短视频前5秒要抓住注意力就必须有高对比度的视觉变化。
实际操作中我会先写一句话需求,再扩展成参数表。举个例子,一句话需求是“做一个15秒的竖屏科技视频封面”,参数表至少要有这些项:
- 时长:精确到秒,最好标出分段,比如0-12秒聚合动画、12-15秒定格。
- 分辨率与画幅:1080×1920竖屏还是1920×1080横屏。
- 文案内容:所有要出现的文字,包括字号层级。
- 配色方案:给出具体色值,避免“科技感”这种模糊词,直接说“底色#000000、文字金色#FFD700、辅助线条#00FFFF”。
- 动效意向:聚合、扩散、呼吸、扫光、位移,每个元素对应一种。
- 字体要求:明确使用什么字体、能否联网加载、回退字体是什么。
- 导出方式:需要MP4还是GIF,帧率多少。
这一步的关键是别偷懒。模型很依赖约束的完备性,你少写一项,它就在默认值或者瞎猜中选一个,结果大概率不符合预期。
3.2 第二步:指令设计(Prompt工程的三个层次)
拿到参数表之后,写Prompt就有章法了。我的经验是Prompt分三个层次来写:角色与任务、约束与格式、示例与检查点。
角色与任务定义模型要扮演什么角色、承担什么目标。比如“你是一个资深前端动效工程师,负责用HTML+CSS+JavaScript Canvas实现短视频动画”。这一句看似简单,但能把回答风格拉向工程实现,而不是泛泛而谈。
约束与格式是Prompt的主体,把参数表里的每一项都翻译成对模型的硬性要求。下面是实际用过效果很稳的模板:
你是一个资深前端动效工程师,请用HTML+CSS+JavaScript实现一个短视频动画,要求如下: - 视频时长:15秒,播放一遍后停止,不要循环 - 分辨率与画幅:1080x1920,竖屏,Canvas铺满全屏 - 配色:背景#000000,主文字#FFD700,粒子#FFD700 - 文案:第0-8秒显示主标题"DESIGN IN CODE",第8-15秒显示副标题"让代码成为画面" - 动效:前8秒粒子从全屏随机位置聚合为主标题文字,聚合完成后主标题轻微呼吸闪烁;第8秒副标题从下往上位移渐显 - 技术限制:不使用任何外部库与CDN资源,纯原生Web实现,字体使用系统无衬线字体 - 代码要求:单个HTML文件即可运行,包含必要的注释,关键逻辑写到单独函数中 - 动画性能:粒子数量不超过3000,使用requestAnimationFrame驱动,避免每帧重复计算目标位置第三层的示例与检查点,是在Prompt末尾附加期望的代码结构,比如“请先实现粒子系统类,再实现文字目标坐标提取,最后在主循环中完成聚合效果”。这能引导模型按清晰的结构输出代码,不会把所有逻辑糊成一团。写完Prompt别急着执行,先把它当作面试题一样审视一遍:如果自己是个工程师,这份需求够不够开工?
3.3 第三步:代码生成与工程脚手架搭建
Prompt准备好之后,就可以让Claude生成代码了。这里我强烈建议选单文件方案:一个index.html包干所有事情。原因很简单,本地双击就能运行,不依赖npm安装、不依赖构建工具,最适合快速验证。
如果涉及大量数据处理,或者要生成多个片段再后期合成,再考虑Python路线。Python方案通常用moviepy、Pillow这类库做逐帧绘制,然后把帧序列合成视频。它适合批量生成、服务器端渲染,但本地调试成本比HTML方案高,首推还是网页方案。
生成代码时建议分阶段索取,而不是要求一次给全。比如第一次只要粒子系统的类结构,第二次要求添加文字坐标提取,第三次才要求主循环与完整动画。分阶段的好处是每段代码都可以独立审查,哪里不满足预期可以直接指出,让模型局部修改,而不是推倒重来。这一步如果检查发现Canvas宽度设定有问题,直接让它改一行就行,完整重新生成反而浪费时间。
拿到代码之后的基本验收项目包括:打开页面控制台没有红色报错;Canvas尺寸和CSS尺寸一致,没有被拉伸变形;页面上出现了预期的初始画面,哪怕还没有动效。
3.4 第四步:渲染执行与逐帧验证
代码能跑起来只是开始,真正的制作环节从这里才算进入正轨。本地调试时我建议起一个本地HTTP服务运行页面,直接用python -m http.server在项目根目录起服务,然后浏览器访问。为什么要这么麻烦?因为直接用file协议打开,浏览器会有很多安全限制,字体加载、JavaScript模块引用、音频解析都可能静默失败,排查起来非常头疼。
接着打开浏览器的Performance面板,录制一小段时间的动画,查看帧率是否稳定。如果帧率掉到明显低于目标值的水平,说明代码有性能瓶颈,需要优化而不是硬扛。录制的时候顺手观察每一帧的绘制耗时,哪里耗时高就重点检查哪里。
逐帧验证是容易被忽略的一步。做得粗糙的话,你只会看到动画“挺顺畅”,但每一帧是否符合设计意图说不清楚。我的做法是在页面里加一个调试面板,显示当前帧号、当前时间(秒)、动画进度(0到1),配合慢速播放,逐个时间点检查动画状态。比如设定第4秒应该是粒子开始向文字聚拢,那就暂停在第4秒,确认粒子的分布确实呈现了趋势性的移动。这一步能提前抓住大量节奏问题,效果远好过导成MP4后再发现错位。
3.5 第五步:导出封装与人工修正
动画在浏览器里跑满意了,接下来要导出成真正的视频文件。两条路线,按需选择。
路线一是屏幕录制。用OBS之类的录屏工具,把浏览器窗口录下来。适合快速交付预览版,但有个致命问题:屏幕录制的帧间隔不均匀,容易造成画面掉帧感,而且音频录制容易不同步。如果只是发给同事看效果,完全可以;如果要用于正式发布,建议走路线二。
路线二是帧序列导出再合成。让动画代码调用Canvas的toDataURL()或者toBlob(),在每一帧绘制完成后把当前画面保存成PNG图片,然后批量导出,再用ffmpeg合成。这里给一段常用的ffmpeg命令:
ffmpeg -r 30 -i frame_%04d.png -c:v libx264 -pix_fmt yuv420p -crf 18 output.mp4参数解释:-r 30指定输入帧率是30fps,-c:v libx264选H.264编码,-pix_fmt yuv420p保证播放器兼容性,-crf 18是视觉无损质量档位。这一步常见的问题是导出后发现画面变成绿色或者播放器不认,绝大多数时候就是忘了加-pix_fmt yuv420p。
导出的成片先自己看两遍。第一遍看整体节奏,第二遍逐秒校对文案与画面。发现结构性缺陷,比如粒子的聚合逻辑不对,回到第二步修改Prompt重新生成;如果只是调一个颜色色值、移动几个像素,直接改代码效率更高。这个判断标准,熟练之后可以形成肌肉记忆。
4. 一个可以照着抄的实例:15秒粒子聚合成标题动画
4.1 目标与参数约束
纸上谈兵不如跑一个完整案例。这里我选“粒子聚合成标题”这个经典动效作为示范,原因是它足够典型,能覆盖流水线的所有环节,又不涉及复杂的外部素材。
需求拆解之后参数锁定如下:
- 时长:15秒,播放一遍后停止
- 分辨率与画幅:1080×1920,竖屏
- 背景:#000000
- 主文字与粒子颜色:#FFD700
- 文案:主标题“DESIGN IN CODE”
- 动效:粒子从全屏随机位置聚合为主标题文字,聚合完成之后主标题整体轻微呼吸闪烁
- 粒子数量:3000到5000之间,控制得好看且不卡顿
- 字体:系统无衬线字体,不加载外部字体
4.2 让Claude生成核心渲染代码
按照3.2的Prompt模板,把参数带进去让Claude生成代码。它会给你一个单HTML文件,里面通常包含两个关键模块:目标坐标提取和粒子动画。
目标坐标提取的思路是这样的:先把文字画到一个离屏Canvas上,调用getImageData读取像素数据,把所有不透明像素的坐标记录下来,作为粒子的最终聚合目标。这样不管文字是什么形状,代码都能自动算出每一个粒子该去哪,完全不需要人工标注坐标。
粒子动画则简单得多。每个粒子从随机初始位置出发,根据当前帧与总动画时长的比例,用缓动函数计算当前位置在“初始位置”和“目标位置”之间的插值距离。核心逻辑大致长这样:
const canvas = document.getElementById('c'); const ctx = canvas.getContext('2d'); canvas.width = 1080; canvas.height = 1920; // 步骤一:离屏绘制文字,提取像素坐标 const offscreen = document.createElement('canvas'); offscreen.width = 1080; offscreen.height = 1920; const offCtx = offscreen.getContext('2d'); offCtx.fillStyle = '#000'; offCtx.fillRect(0, 0, 1080, 1920); offCtx.fillStyle = '#FFD700'; offCtx.font = 'bold 160px "Helvetica Neue", Arial, sans-serif'; offCtx.textAlign = 'center'; offCtx.textBaseline = 'middle'; offCtx.fillText('DESIGN IN CODE', 540, 800); const imageData = offCtx.getImageData(0, 0, 1080, 1920); const targets = []; const gap = 6; // 每隔6个像素采样一次,控制粒子数量 for (let y = 0; y < 1920; y += gap) { for (let x = 0; x < 1080; x += gap) { const alpha = imageData.data[(y * 1080 + x) * 4 + 3]; if (alpha > 128) { targets.push({ x, y }); } } } // 步骤二:建立粒子系统 const particles = targets.map((target, i) => ({ target, x: Math.random() * 1080, y: Math.random() * 1920, disturbX: Math.random() * 20 - 10, disturbY: Math.random() * 20 - 10 })); // 步骤三:主循环,按时间插值聚合 function easeInOut(t) { return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2; } function draw(t) { const seconds = t / 1000; const progress = Math.min(seconds / 8, 1); // 前8秒完成聚合 const eased = easeInOut(progress); ctx.fillStyle = '#000'; ctx.fillRect(0, 0, 1080, 1920); particles.forEach((p) => { const tx = p.target.x + p.disturbX; const ty = p.target.y + p.disturbY; p.x = p.x + (tx - p.x) * 0.12; // 用平滑追踪替代线性插值 p.y = p.y + (ty - p.y) * 0.12; ctx.fillStyle = `rgba(255, 215, 0, ${0.6 + Math.sin(seconds * 3 + p.x) * 0.4})`; ctx.fillRect(p.x, p.y, 3, 3); }); if (seconds < 15) { requestAnimationFrame(draw); } } requestAnimationFrame(draw);这段代码刻意写得收敛,没有引入复杂依赖。这里有一个容易被模型忽略、也容易被你忽略的细节:粒子速度不是线性变化的,我用了“当前位置 + (目标 − 当前) × 0.12”这个平滑追踪算法,效果上比线性插值更自然——粒子会在接近目标时自动减速,形成聚合感而不是直线撞过去。你要是觉得聚合太慢,把0.12调成0.18即可。
4.3 渲染与导出
这段代码在浏览器里跑起来会持续15秒,然后自动停止。你可以直接录屏做预览,但正式交付还是用帧序列导出方案。
具体做法:在draw(t)函数末尾加一段逻辑,当当前是第N帧时,调用canvas.toDataURL('image/png'),把DataURL通过页面上的隐藏控件或者直接靠浏览器批量下载。更省事的做法是使用一段辅助脚本定时抓取Canvas内容,这里就不展开完整实现,只提关键思路:抓帧时间要和对帧的渲染时间严格对齐,不要在浏览器UI线程忙的时候抓,会漏帧。
我习惯用帧序列导出。先在代码里加入导出标记,确保一下命令可以生成30帧/秒的PNG帧,再用4.1节提到的ffmpeg命令合成MP4。注意-r 30放在输入文件前面,这样才能覆盖输入的帧率设置,很多人在这个问题上栽过跟头:参数顺序不对,合成的视频速度忽快忽慢。
4.4 产物检查清单
成片导出后,我习惯按这个清单过一遍:
- 画面尺寸是不是1080×1920,有没有因为Canvas缩放导致模糊。
- 前8秒粒子是否在视觉上完成了从发散到聚合的过渡,有没有粒子还在“流浪”。
- 聚合完成后的呼吸闪烁是否均匀,会不会有一部分粒子亮度过低看不清。
- 第8到15秒画面是否静止,副标题可替换成项目真实信息。
- 整体播放有没有跳帧感,字体是否清晰没有毛边。
这套检查流程看起来繁琐,但实际跑下来只需要几分钟,却能避免把带着低级问题的片子发出去,省掉之后“返工+解释”的额外沟通成本。
5. 常见问题与排查技巧实录
5.1 渲染空白、黑屏,八成是脚本执行时机问题
最常遇到的情况是打开页面黑屏,控制台报错“Cannot read properties of null”或者类似错误。原因基本是JavaScript在DOM元素还没加载完成时就尝试获取Canvas节点。解决办法是在HTML结构里把<script>标签放到body的最后面,或者给脚本加defer属性。另外检查一下Canvas的CSS尺寸和attribute尺寸是否一致,ctx.fillRect有值但画面没显示,多半是Canvas被CSS拉伸到0了。
还有一种黑屏原因是代码里用了document.addEventListener('DOMContentLoaded'),但脚本本身放在body末尾,事件不会再触发。这种问题在浏览器里表现得很隐蔽,不是每次都报错,需要冷静排查。
5.2 粒子动效掉帧,先查这三个地方
动效卡顿是制作过程中的高频问题。三个检查重点:
- 粒子数量。5000个粒子在1080×1920分辨率下对Canvas绘制压力不小,尤其每个粒子用了
fillRect绘制。降粒子数、加大采样间隔,是立竿见影的办法。 - 每帧重复计算目标点阵。把
getImageData放到了主循环里执行,会导致每帧都重新读取像素数据,性能直接崩溃。正确的做法是只在初始化时计算一次,后续循环只访问缓存好的坐标数组。 - 用了
setInterval驱动动画而不是requestAnimationFrame。setInterval的间隔不可靠,标签页失去焦点时会被系统大幅降频,而且它会在主线程忙碌时排队积压,导致动画不连续。换成requestAnimationFrame之后,浏览器会按屏幕刷新率回调函数,掉帧问题基本能缓解大半。
5.3 文字发糊、字体闪跳,高分屏适配没做
在MacBook的Retina屏或者Windows的200%缩放下,很多人发现导出的视频文字边缘发虚。原因是Canvas绘制时没有考虑devicePixelRatio。系统以为你的Canvas只有540像素宽,但物理屏幕上实际是1080像素,于是浏览器强行拉伸,画面就糊了。解决方法是把Canvas的物理像素设为宽高乘以devicePixelRatio,再用ctx.scale(dpr, dpr)让绘制坐标保持逻辑像素不变。
字体闪跳则通常是字体加载时机的问题。如果页面使用网络字体,字体文件尚未加载完成时Canvas会先用回退字体绘制,等字体加载后再重绘,动画开始的一瞬间就能看到文字“跳”了一下。解决办法是等document.fonts.ready再开始动画,或者在初始化时先预加载字体。
5.4 导出视频画面撕裂、音画不同步,后期参数背锅
镜头画面撕裂大多来自录屏方案,帧率不恒定造成。前面说的帧序列方案可以根治这类问题,因为每一帧的画面内容本身就由代码保证是离散且完整的,不会出现录制过程中的半帧。音画不同步则集中在音频轨道上。如果成片需要配音,配音导入时间轴之后要检查声画偏移量,建议在动画里做一个“第3秒闪白”之类的隐式标记,导出后用闪白帧对齐音频波形,能大幅减少手动对齐的误差。
另外视频导出后花屏,呈现绿色或者粉色条纹,几乎是色彩空间转换的问题。ffmpeg默认的色彩格式导出到部分播放器会异常,需要用-pix_fmt yuv420p显式指定。这是我在第一版导出经常遇到的问题,加了这个参数就没再出现过。
5.5 常见问题速查表
| 症状 | 常见原因 | 处理方法 |
|---|---|---|
| 页面空白 | JavaScript执行时机不当、Canvas尺寸为0 | 脚本放body末尾、检查Canvas宽高 |
| 粒子卡顿 | 粒子数过多、每帧重复取像素、用setInterval | 降低粒子数、目标点阵缓存、改用requestAnimationFrame |
| 文字发糊 | 未适配devicePixelRatio | Canvas物理像素乘dpr,用ctx.scale |
| 字体闪跳 | 字体未预加载 | 等待document.fonts.ready后再启动动画 |
| 导出花屏绿屏 | 缺少色彩格式参数 | ffmpeg加-pix_fmt yuv420p |
| 动画结束直接黑掉 | 主循环停止条件过早 | 检查seconds<总时长的比较逻辑 |
| 粒子聚合出现乱串 | 目标坐标参考了CSS尺寸而非物理尺寸 | 确保off-screen canvas与主canvas尺寸一致 |
这套流水线我陆陆续续用了大半年,最大的体会是:把“想video”拆成“想code”,看起来绕了远路,实际上反而更快。视频制作本来就是一个反复修改的过程,像素生成模型把“修改”这件事变成了重新抽卡,而代码流水线把“修改”变成了改参数、重渲染,前者靠运气,后者靠控制。哪怕以后模型真的能直接输出高质量视频,这种“用代码精确控制每一帧”的思路,也依然是做片头、做数据动效、做产品demo时最稳的一条路径。