十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

tldraw PR Walkthrough 视频管线:manifest.json 幻灯片清单格式完整指南

tldraw PR Walkthrough 视频管线:manifest.json 幻灯片清单格式完整指南 tldraw PR Walkthrough 视频管线manifest.json 幻灯片清单格式完整指南【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. Worlds best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw导读本篇技术指南围绕 tldraw 仓库中 pr-walkthrough 技能Skill所定义的核心中间产物 ——manifest.json幻灯片清单展开。它是一个 JSON 文件逐条描述讲解视频中的每一张幻灯片充当旁白/音频阶段与超帧渲染器hyperframes renderer之间的桥梁被工作流的第 4 步引用见 SKILL.md 的 Step 4。读完本文你将掌握 manifest 的全部 8 种幻灯片类型及其必填字段、diff/code 内容的撰写规范、长内容动画滚动focus的配置方法以及它如何与durations.json、render.sh、build.mjs协作生成 1280×720/30fps 的 PR 讲解视频。一、Manifest 在整个 PR Walkthrough 管线中的位置在深入了解 manifest 格式之前先明确它在五步工作流中的位置。tldraw 的 PR walkthrough 视频生成管线定义在 skills/pr-walkthrough/SKILL.md完整流程为理解 PR通过gh pr view、git log main..HEAD、git diff main..HEAD --stat通读 PR 的提交、diff 与描述梳理叙事主线撰写旁白将讲解词写成连续文本并切分为逻辑段segment保存为tmp/pr-number/SCRIPT.md生成音频与时间戳编写narration.json运行 scripts/generate-audio.sh为每个 segment 生成一个 WAV 音频片段audio-00.wav、audio-01.wav……同时输出durations.json记录每个音频文件名对应的时长秒编写 manifest读取第 3 步生成的durations.json将每个音频片段的时长填入对应幻灯片与音频文件放在同一目录下写出manifest.json渲染视频运行 video/render.sh传入 manifest 与输出路径最终产出out/pr-number-walkthrough.mp4。Manifest 处于第 4 步是音频就绪与画面渲染之间的契约文件音频决定每张幻灯片播多久manifest 决定每张幻灯片画什么。它被render.sh解析用于收集音频/图片资源再由 video/build.mjs 读取并编译成 hyperframes 组合index.html。二、完整示例一份真实的 manifest.json以下是references/manifest.md中给出的完整示例。实际使用时将durations.json中的每个音频时长填入对应的durationInSeconds字段并跟随音频文件写入tmp/pr-number/目录{ pr: 7865, slides: [ { type: intro, title: Fix canvas-in-front z-index layering #7865, date: February 14, 2026, audio: audio-00.wav, durationInSeconds: 3.2 }, { type: diff, filename: packages/editor/editor.css, language: css, diff: -12,7 12,7 \n --tl-z-canvas: 100;\n- --tl-z-canvas-in-front: 600;\n --tl-z-canvas-in-front: 250;\n --tl-z-shapes: 300;, audio: audio-01.wav, durationInSeconds: 25.8 }, { type: code, filename: packages/editor/src/lib/Editor.ts, language: typescript, code: function getZIndex() {\n return 250\n}, audio: audio-02.wav, durationInSeconds: 13.5 }, { type: text, title: Summary, subtitle: Moved canvas-in-front from z-index 600 to 250., audio: audio-07.wav, durationInSeconds: 7.4 }, { type: list, title: Key changes, items: [Lowered z-index, Updated tests, Added migration], audio: audio-06.wav, durationInSeconds: 10.2 }, { type: outro, durationInSeconds: 3 } ] }关键结构说明顶层pr字段记录 PR 编号会被build.mjs用于 intro/outro 页眉如 tldraw / tldraw · #7865以及页脚水印PR #7865slides是按时间顺序排列的幻灯片数组每张幻灯片必须给出type与durationInSeconds带旁白的幻灯片还要引用audio文件名渲染器按数组顺序与durationInSeconds累加计算每张幻灯片的绝对起始时间——build.mjs中以游标cursor顺序累加得到每个 slide 的start与全局totalDuration见 video/build.mjs 中的 Cumulative timing 段因此幻灯片顺序即视频播放顺序时长必须与音频实际长度一致outro无音频固定 3 秒纯静音 Logo 结尾是 SKILL.md 强制要求的最后一张幻灯片。三、八种幻灯片类型速查表manifest 定义了 8 种幻灯片类型每种类型的必填字段与用途如下表内信息与 references/manifest.md 一致TypeRequired fieldsDescriptionintrotitle,date,audio,durationInSecondsLogo title datedifffilename,language,diff,audio,durationInSecondsSyntax-highlighted unified diffcodefilename,language,code,audio,durationInSecondsSyntax-highlighted source codetexttitle,audio,durationInSecondsTitle optionalsubtitlelisttitle,items,audio,durationInSecondsTitle numbered itemsimagesrc,audio,durationInSecondsPre-rendered image (fallback)segmenttitle,durationInSecondsSilent title card between segmentsoutrodurationInSecondsLogo only, no audio各类型的实际渲染行为可以从 video/build.mjs 的渲染器映射RENDERERS对象中印证intro/text居中大标题排版。intro会自动从title中摘取一个关键词默认倒数第二个词以品牌色高亮并展示日期text页眉固定为 Summary支持可选的subtitle副标题segment标题卡居中展示上下各有一条蓝色分隔线无音频、纯静音用于章节之间的视觉过渡diff/code顶部有文件栏file-bar从左到右依次为语言徽章lang-badge、文件名file-name与可选的段落标题slide-title主体是语法高亮的代码视口code-viewport上下带渐隐遮罩code-fadelist大号标题 蓝色数字编号的有序列表image以object-fit: contain全幅展示src指向的预渲染图片作为回退方案outro只展示 tldraw 字标wordmark与 PR Walkthrough · #NNNN 文案。从源码结构可以推断每种类型在build.mjs中都有独立的渲染函数renderIntro、renderSegment、renderCode、renderDiff、renderText、renderList、renderImage、renderOutro未知的type会在构建时直接抛出Unknown slide type错误因此字段缺失或拼写错误会在渲染阶段被尽早拦截。四、长内容动画滚动focus字段4.1 为什么需要 focus对于超过约 30 行的长 diff 或长代码如果保持 16px 可读字号内容无法在一屏内完整呈现。渲染器的解决方案是保持字号可读用一个动画视口在多个聚焦点之间滚动。为diff或code幻灯片添加focus数组即可{ type: diff, filename: packages/editor/src/lib/Editor.ts, language: typescript, diff: ... 60-line diff ..., focus: [ { line: 3, at: 0 }, { line: 25, at: 0.4 }, { line: 50, at: 0.8 } ], audio: audio-03.wav, durationInSeconds: 30 }4.2 字段语义line—— 要居中到屏幕上的行号该编号是从 0 开始、相对于解析后的 diff/code 行不含额外偏移at—— 到达该位置的时间点表示为幻灯片时长的比例0 开始1 结束。4.3 底层实现源码级佐证在 video/build.mjs 的 Timeline JS 段中focus 被翻译成 GSAP 时间轴的滚动动画每个聚焦点映射为绝对时间t start (f.at || 0) * duration与垂直位移y -max(0, f.line - 4) * lineHeightlineHeight 36即在目标行上方预留约 4 行首点通过tl.set立即定位相邻聚焦点之间用tl.to以power1.inOut缓动平滑滚动单段滚动时长下限为 0.5 秒视口在第一个聚焦点之前停留在初始位置最后一个聚焦点之后保持不动即tl.set首点、逐段tl.to的时序结构保证。4.4 何时使用、何时省略使用 focus任何超过约 30 行的 diff/code 幻灯片。不加 focus 时长内容默认从顶部开始并保持静止观众根本看不到底部的内容加上之后你能在旁白讲到哪一行时就把观众的视线引导到哪一行省略 focus短 diff≤30 行在 16px 字号下整屏即可容纳无需滚动。build.mjs对无focus的 code/diff 幻灯片会退化为[{ line: 0, at: 0 }]的默认值等价于静态展示。五、diff 与 code 字段的撰写规范5.1 diff 字段粘贴 unified diff对于diff幻灯片请粘贴相关 hunk 的unified diff。它就是git diff对该文件某段输出的原始结果——包括hunk 头以及/-/ 行前缀。渲染器正是解析这些前缀来施加绿/红背景与语法高亮。获取某个文件的 diffgit diff main..HEAD -- path/to/file.ts规范要点只包含相关 hunk不要整份文件 diff去掉diff --git与---/头行从hunk 头开始粘贴。build.mjs中的renderDiffLines对前缀的处理与文档描述完全一致行被标记为dl-hunk浅蓝背景的 hunk 头行首显示⋯行标记为dl-add绿色背景#dafbe1前缀符号显示-行标记为dl-del红色背景#ffebe9前缀符号显示−/---为淡化处理的元信息行其余为上下文行——每行的内容部分还会经过语法高亮highlightLineGitHub Light 配色覆盖注释、字符串、数字、关键字、类型与装饰器。5.2 code 字段粘贴源码对于code幻灯片直接粘贴相关源码一个函数、一个类、一个片段即可不需要任何 diff 前缀。5.3 文件名与语言的约定filename建议使用仓库内的真实路径示例中即为packages/editor/editor.css、packages/editor/src/lib/Editor.ts等它会显示在幻灯片顶部的文件栏中language决定语言徽章的文字与语法高亮的适用场景如css、typescriptbuild.mjs的语法高亮逻辑按通用正则匹配并非按语言切换规则集但徽章标签会按language原样展示。六、章节过渡segment标题卡6.1 使用规则在每个内容段之前插入一张segment幻灯片用于引入该段——但 intro 与 context/overview 段之前除外。这包括代码讲解段以及 summary/conclusion 段。每张 segment 卡是3 秒静音段标题居中显示{ type: segment, title: Zoom state machine, durationInSeconds: 3 }这些标题卡为不同章节提供清晰的视觉分隔给观众在每个新话题开始前一个定向orient的喘息时刻。6.2 与旁白叙事结构的关系从 SKILL.md 的 Script structure 可知标准叙事弧为intro1 段→ context0–1 段→ 代码讲解6–10 段→ summary1 段→ outro1 段静音目标是总共 8–12 个 segment且绝大多数画面展示代码。segment幻灯片正是为这些叙事段之间提供视觉断点让旁白段与画面段一一对应。七、段落标签code/diff 幻灯片上的title字段当一个段落跨越多张幻灯片时仅靠开头一张 segment 卡不足以让观众始终知道自己在讲哪一段。为此可以给code和diff幻灯片加一个title字段在左上角显示一个小的段落标签标识当前所处段落。该 title 应与此前那张segment幻灯片的标题保持一致{ type: diff, title: Zoom state machine, filename: packages/editor/src/lib/ZoomTool.ts, ... }从实现上看build.mjs的文件栏渲染file-bar在语言徽章与文件名之后、右侧对齐的位置渲染slide.titleCSS 类slide-titlemargin-left: auto即段落标签实际显示在文件栏的右端。而segment幻灯片则将title居中于全屏。两处使用同一标题即可在章节卡与章节内代码页之间建立视觉连续性。八、Manifest 如何被消费渲染管线与文件组织8.1 渲染命令manifest 写好后运行渲染脚本./video/render.sh \ tmp/pr-number/manifest.json \ out/pr-number-walkthrough.mp4注意SKILL.md 要求所有引用./scripts或./video的命令都从技能目录skills/pr-walkthrough/执行。8.2 render.sh 的五步流水线video/render.sh 对 manifest 的消费过程对应输出中的[1/5]–[5/5]日志收集资源用 Python 解析 manifest提取所有audio与src字段引用的文件名从 manifest 所在目录拷贝到video/assets/每次渲染前会清空该目录避免残留旧文件Whisper 转写对每个音频运行 whisper 转写幂等——仅当音频比已有转写新时才重新转写结果写入video/transcripts/audio-NN.json生成组合运行node build.mjs manifest生成video/index.html——一个 hyperframes 组合包含每张幻灯片的定时 clip、驱动转场与代码聚焦平移的 GSAP 时间轴以及基于 whisper 词级转写的、起止时间已知的黄底黑字字幕 clip渲染帧npx hyperframes lint检查组合警告不阻断随后以-q draft --crf 30渲染 1920×1080 帧draft 档控制中间文件体积最终体积由降采样主导降采样压缩ffmpeg 缩放到 1280×720/30fps 并以 CRF 26 AAC 96k 重压产出体积小且清晰的最终 MP4。8.3 字幕与进度的来源manifest 中的durationInSeconds也是字幕时间轴的基准build.mjs的makeCaptions将 whisper 词级转写按5–7 词一组分块遇到 450ms 的停顿句子边界提前断句并将每个字幕块的起始时间平移至所在音频的全局起点audioStart c.start。幻灯片切换使用 0.4 秒淡入/淡出画面右下角还有一个随播放进度填充的圆形进度指示器饼图总时长即 manifest 中所有durationInSeconds之和。8.4 文件组织根据 SKILL.md 的 File organizationmanifest 相关的完整目录约定如下pr-walkthrough/ ├── SKILL.md # 技能主文档 ├── scripts/ │ └── generate-audio.sh # narration.json → 每段 WAV durations.json ├── video/ │ ├── hyperframes.json # hyperframes 配置 │ ├── meta.json # 项目元信息 │ ├── build.mjs # manifest.json → index.html 组合 │ ├── render.sh # manifest.json → 720p MP4完整流水线 │ ├── assets/ # 渲染时自动填充gitignored │ ├── transcripts/ # Whisper 词级 JSONgitignored缓存 │ └── renders/ # 中间 1080p 渲染gitignored ├── out/ # 最终产物gitignored │ └── pr-XXXX-walkthrough.mp4 └── tmp/ # 中间文件gitignored └── pr-XXXX/ ├── SCRIPT.md # 旁白脚本 ├── narration.json # generate-audio.sh 的输入 ├── durations.json # 音频文件名 → 时长秒 ├── manifest.json # render.sh 的输入 └── audio-XX.wav # 每段音频片段值得注意durations.json与manifest.json同处tmp/pr-number/目录这正是 manifest 中audio字段以相对文件名如audio-01.wav而非绝对路径引用的原因——render.sh会基于 manifest 所在目录解析资源路径$MANIFEST_DIR/$FILE。所有中间产物都被 gitignore只有最终 MP4 进入out/。九、撰写 manifest 的实用清单结合本指南与 SKILL.md 的 Checklist一份可渲染的 manifest 应当满足已读取第 3 步的durations.json每张带音频的幻灯片都填入了对应的真实时长幻灯片按时间顺序排列type必须是八种类型之一未知类型会在build.mjs抛错每张带旁白的幻灯片都引用了与音频文件匹配的audio文件名diff幻灯片使用 unified diff含hunk 头与/-/ 前缀去掉了diff --git和---/头行只保留相关 hunk超过约 30 行的diff/code幻灯片配置了focus数组line从 0 开始编号at为 0–1 的比例值每个内容段除 intro 与 context 段前插入了title一致的segment幻灯片跨多张幻灯片的段落在其 code/diff 幻灯片上重复了相同的title字段最后一张幻灯片是type: outro、durationInSeconds: 3的静音 Logo 卡运行./video/render.sh manifest output.mp4后产出 1280×720 / 30fps、字幕同步、结尾含 outro 的最终视频。至此从 JSON 结构、八种幻灯片类型的字段约定到focus动画滚动、unified diff 粘贴规范、segment 章节卡再到render.sh与build.mjs的底层消费逻辑manifest 作为 tldraw PR 讲解视频音频—画面契约的完整面貌已经清晰。对照 references/manifest.md 与 video/build.mjs 阅读即可直接为任意 PR 编写可渲染的manifest.json。【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. Worlds best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表