- 开发工具
【免费下载链接】vhs
Your CLI home video recorder 📼
本篇文章以开源仓库中的 examples/glow/README.md 为骨架,完整拆解用 VHS("Write terminal GIFs as code")为 Charm 出品的终端 Markdown 渲染器 Glow 录制演示 GIF 的两种典型方案:Glow Simple 与 Glow Full。读完你将掌握 Tape 脚本的完整语法(Output、Set、Type、Sleep、Hide/Show、方向键与组合键),理解逐字符输入速度(@time语法)、隐藏命令等进阶录制技巧,并能直接复用仓库内现成的 .tape 文件跑出自己的演示录像。
为什么用 VHS 录制 Glow:场景与价值
Glow 是一个在终端中渲染 Markdown 的命令行工具,常用于阅读.md文档、笔记与待办清单。它的交互界面包含目录导航、全文搜索(/前缀)、编辑模式(e/m/a)、滚动浏览与分页器等多个状态,是一个典型的 "TUI 演示对象"——光靠静态截图很难讲清楚它的交互节奏。
VHS 恰好提供了"以代码写终端录像"的能力:把每一次按键、每一段等待、每一个命令都声明式地写进.tape文件,再用虚拟终端(底层依赖ttyd)回放并用ffmpeg逐帧编码为 GIF/MP4/WebM 或纯文本 ASCII。仓库的 examples/glow 目录就是这一场景的官方样板:既有两套完整 Tape 脚本,也有对应的 GIF 与 ASCII 渲染产物,以及一组供 Glow 渲染的样例 Markdown 文件。
examples/glow/ ├── README.md # 本文依据的示例说明文档 ├── glow-simple.tape # 极简演示脚本(README 内嵌同款) ├── glow.tape # 完整进阶演示脚本(README 内嵌同款) ├── glow-edit.tape # 编辑模式专项演示脚本 ├── glow-simple.gif / vhs-glow.gif / glow-edit.gif ├── glow-simple.ascii / glow.ascii ├── NiHao.md / CarrotCake.md / StewedPeaches.md ├── notes/ (Currywurst.md / Kasewurst.md / Spatzle.md / Weibwurst.md) └── to-do/ (Okonomiyaki.md / Takoyaki.md)运行前准备:安装 VHS 与依赖
录制 Glow 演示前,机器上必须满足:
- VHS 本体:见 README.md 的安装章节,macOS/Linux 可用
brew install vhs,Arch 用pacman -S vhs,Nix 用nix-env -iA nixpkgs.vhs,Windows 可用scoop install vhs或winget install charmbracelet.vhs;也可以直接用 Docker(依赖内置):docker run --rm -v $PWD:/vhs ghcr.io/charmbracelet/vhs <cassette>.tape。 - 运行时依赖:VHS 要求
ttyd与ffmpeg已安装并在PATH中(README 中的 NOTE 明确说明)。 - Glow 本体:目标程序需能被虚拟终端调用。README 强调可以用
Require glow在 Tape 顶部声明依赖,缺失时提前失败。 - 样例 Markdown:仓库的 examples/glow 已备好
NiHao.md、CarrotCake.md、StewedPeaches.md以及notes/、to-do/目录下多篇笔记,正好作为 Glow 的渲染素材。
准备好后,进入该目录执行vhs glow-simple.tape即可按脚本输出文件(命令在仓库根目录执行时可写vhs examples/glow/glow-simple.tape)。
第一个脚本:Glow Simple 逐行解读
examples/glow/README.md 的 "Glow Simple" 小节给出了最简录制脚本,实际对应仓库文件 examples/glow/glow-simple.tape:
Output examples/glow/glow-simple.ascii Output examples/glow/glow-simple.gif Set Width 1000 Set Height 1050 Type "glow" Enter Sleep 1s Enter Sleep 1s Escape Sleep 1s Type "q" Sleep 1s逐条拆解:
| 命令 | 作用 | 说明 |
|---|---|---|
Output <path> | 声明渲染输出 | 可同时声明多个输出(这里是 ASCII + GIF),VHS 会渲染到各自位置;支持.gif/.mp4/.webm/.ascii以及目录(PNG 帧序列) |
Set Width 1000/Set Height 1050 | 设置虚拟终端尺寸(像素) | 需在文件顶部、任何非设置/非输出命令之前声明,否则被忽略 |
Type "glow" | 逐字符模拟输入命令 | 字符间隔默认由Set TypingSpeed决定 |
Enter | 按下回车执行命令 | 启动 Glow 并进入文件选择器 |
Sleep 1s | 暂停录像继续采集帧 | 支持100ms、1s、0.5等写法 |
Escape | 按 Esc 键 | 此处用于退出 Glow 的交互视图返回选择器 |
Type "q" | 输入 q | Glow 中按q退出应用 |
这个脚本呈现的完整节奏是:启动 Glow → 在文件选择器上停留 1 秒 → 进入默认文档视图停留 1 秒 → Esc 回退 → 按q退出。它演示了 Tape 脚本的三要素:声明输出与画布 → 用按键驱动交互 → 用 Sleep 控制镜头停留。
注意:README 中的两处Output路径(glow-simple.ascii、glow-simple.gif)是相对于示例运行目录的写法;在仓库根目录执行时,需要像上例一样以仓库根为基准补全为examples/glow/...,产物 glow-simple.ascii 与 glow-simple.gif 均已在仓库中留档。
双输出:GIF 与 ASCII golden file 并行渲染
Glow Simple 脚本最有价值的一点是同时声明了.ascii与.gif两个输出。ASCII 输出是把每一帧转成文本快照,这带来两个用途:
- 零依赖预览:任何人无需播放器即可查看终端的"关键帧"(仓库中的 glow-simple.ascii 正是如此,可以看到
> glow的输入提示行与分隔线)。 - 集成测试 golden file:README 的 "Continuous Integration" 章节指出,用
.txt/.ascii输出生成 golden 文件并入库,即可在 CI 中对比两次运行的差异,实现"终端交互的回归测试"——Glow 演示脚本因此不仅能做展示,还能当测试用例跑。
进阶脚本:Glow Full 完整拆解
README 的 "Glow Full" 小节才是重头戏,对应 examples/glow/glow.tape,它覆盖了 Glow 的搜索、目录切换、编辑、组合键与节奏控制等全部高频交互。完整脚本如下:
Output examples/glow/vhs-glow.gif Output examples/glow/glow.ascii Set Width 1600 Set Height 1040 Sleep 1s Type "glow" Sleep 100ms Enter Sleep 1s Hide Tab Type "/artichoke" Enter Down 2 Show Sleep 0.5s Down 20 Hide Escape Type "l" Down 5 Show Sleep 1s Up@400ms 5 Hide Type "/ulysses" Enter Show Sleep 0.5s Down@200ms 20 Hide Escape Type "/" Show Sleep 0.5s Type@500ms "todo" Sleep 1 Hide Escape Type "/ulysses" Enter Show Sleep 0.5s Type@750ms "????" Hide Escape Type "/artichoke" Enter Type "m" Ctrl+A Right 4 Show Sleep 1s Type@250ms "Tasty " Sleep 1s Hide Escape Down 5 Type "m" Ctrl+U Show Sleep 1s Type@150ms "Your new internet thing" Sleep 3s Hide Ctrl+C Show这段脚本暗含了多个值得复用的"录制套路":
套路一:Hide/Show隐藏中间步骤
Hide让 VHS 停止采集帧,Show恢复采集(源码中对应 command.go 的ExecuteHide与ExecuteShow,注释明确写着 "starts or stops the recording of the vhs")。在 Glow Full 里,Hide被用来隐藏按键动作本身、只展示结果:
Hide / Tab / Type "/artichoke" / Enter / Down 2 / Show:Tab 先切到搜索框,输入artichoke并回车完成搜索,再向下移动 2 行选择结果——整个过程观众看不到,只看到"搜索并定位到了文件"的落点。- 同样的模式还用于搜索
ulysses、输入/todo、以及最后的Ctrl+C退出。这种"先偷偷做动作、再亮出结果"的手法,是让演示 GIF 干净、不啰嗦的关键。
套路二:@time语法控制输入速度与滚动节奏
VHS 支持在命令后用@<时间>覆盖默认输入速度(README 的Set TypingSpeed章节:Set TypingSpeed 0.1表示每字符 100ms,可被Type@500ms这类写法临时覆盖;源码 command.go 的ExecuteSetTypingSpeed维护该默认值):
Up@400ms 5:每 400ms 按一次上箭头,共 5 次——慢速滚动营造"审阅"感。Down@200ms 20:每 200ms 按 20 次下箭头——快速翻页。Type@500ms "todo":以每字符 500ms 的速度输入搜索词。Type@750ms "????"、Type@250ms "Tasty "、Type@150ms "Your new internet thing":用递减的输入速度表现"郑重录入"的叙事节奏。
这是把"输入速度"当作剪辑语言的用法:慢打强调、快滚带过,整个演示因此有了时间维度的编排。
套路三:方向键、组合键与 Glow 编辑交互
Escape后Type "l":Glow 中l进入文件列表视图,随后Down 5定位文件。Type "m"+Ctrl+A+Right 4:m打开编辑视图,Ctrl+A跳到行首,Right 4把光标移到第 4 列(在标题前腾出插入位置),随后Type@250ms "Tasty "在文件名前补词。- 第二处编辑:
Down 5后Type "m"+Ctrl+U,Ctrl+U在 Glow 的编辑器中删除到行首,再输入Type@150ms "Your new internet thing"整段重写。
对比 examples/glow/glow-edit.tape 可以看到同主题的独立变体:它额外演示了Type "e"进入编辑、Type@100ms "jjjjjjjo"逐字符移动光标、Type " * Love"追加文本、Type@300ms ":wq"保存退出,以及Type "c"打开 Glow 的分页器。三份 Tape 合在一起,几乎覆盖了 Glow 全部编辑与浏览热键。
套路四:键位速查
Glow Full 用到的全部 VHS 键位命令在 README.md 的 "VHS Command Reference" 均有定义:
- 特殊键:
Enter、Tab、Escape(Esc 键本身)、Space、Backspace,均支持可选@time与重复次数,如Tab@500ms 2。 - 方向键:
Up/Down/Left/Right,同样支持Up@400ms 5形式。 - 组合键:
Ctrl+<char>(如Ctrl+A、Ctrl+U、Ctrl+C),也支持Ctrl+Alt+Shift+<char>。 - 节奏控制:
Sleep支持Sleep 1s、Sleep 100ms、Sleep 0.5;Hide/Show配对使用。
从源码理解录制机制
Tape 脚本之所以"所见即所得",是因为 VHS 的解析与执行分两层:词法/语法层(lexer/lexer.go、parser/parser.go、token/token.go)负责把命令文本解析为指令树;执行层(command.go 与 evaluator.go)把指令逐条喂给虚拟终端。其中:
- command.go 的
ExecuteHide直接切换录像开关(startOrStop),印证了"隐藏动作、保留画面"的机制是在帧采集层面生效,而不是"拍完再裁剪"; - command.go 附近在每次输入前读取
v.Options.TypingSpeed作为默认字符间隔,被@time显式覆盖——这就是Type@150ms能逐条变速的底层依据; - 输出端则由 record.go、ffmpeg.go 与 video.go 负责把捕获帧编码为 GIF/MP4/WebM,screenshot.go 支持任意时刻
Screenshot抓 PNG 帧。
仓库还自带 parser_test.go、lexer_test.go 与 command_test.go,把脚本语法与各命令行为都固化为可回归的单元测试——读代码时可以先看这些测试来确认某个命令的确切语义。
把脚本跑起来与进一步定制
在仓库根目录执行:
vhs examples/glow/glow-simple.tape # 生成 examples/glow/glow-simple.gif 与 .ascii vhs examples/glow/glow.tape # 生成 examples/glow/vhs-glow.gif 与 .ascii vhs examples/glow/glow-edit.tape # 生成 examples/glow/glow-edit.gif如需微调,可参考以下常用配置(均须放在 Tape 顶部,除TypingSpeed外,位于非设置/非输出命令之后都会被忽略):
Set FontSize 22 # 字号(glow-edit.tape 即用 22) Set FontFamily "Monoflow" # 字体族 Set Theme "Catppuccin Frappe" # 按名设置主题,或 Set Theme { "name": ... } 传完整 JSON Set Framerate 60 # 采集帧率(glow.tape 在仓库目录版使用 40) Set PlaybackSpeed 1.0 # 回放倍速 Set TypingSpeed 100ms # 全局输入速度 Require glow # 顶部声明依赖,缺失即快速失败若想让演示更像"真人操作",建议按 Glow Full 的做法:Sleep控制停顿、@time控制按键节奏、Hide把重复的目录切换与清理动作藏起来,只保留最终落点。
小结
examples/glow/README.md 用一简一繁两个脚本,浓缩了 VHS 录制 TUI 演示的完整方法论:Glow Simple讲清"输出声明 + 画布尺寸 + 按键 + Sleep"的最小骨架,并示范了 GIF 与 ASCII 双输出;Glow Full则展示了 Hide/Show、@time变速、方向键与Ctrl组合键、搜索与编辑热键的进阶编排。配合仓库中的 glow.tape、glow-simple.tape、glow-edit.tape 三份可运行脚本以及对应 GIF/ASCII 产物,任何人只要装上 VHS、ttyd、ffmpeg 与 glow,就能一键复刻并改造出属于自己的 Glow 演示录像——这套"按键即代码"的录制范式,同样适用于其他任何终端交互工具。
- 开发工具
【免费下载链接】vhs
Your CLI home video recorder 📼
相关推荐
Pwndbg 演示 GIF 制作指南:用 VHS Tape 录制可复现、可维护的终端演示视频
Pwndbg 演示 GIF 制作指南:用 VHS Tape 录制可复现、可维护的终端演示视频 本文是 Pwndbg 文档体系的配套创作指南:当你需要为某个命令或
编程语言编译器标准库语言运行时并发编程使用 VHS 编写 `.tape` 脚本:为 gws(Google Workspace CLI)制作终端演示 GIF/MP4 的完整指南
使用 VHS 编写 .tape 脚本:为 gws(Google Workspace CLI)制作终端演示 GIF/MP4 的完整指南 VHS 是 Charmbr
Glow入门指南:5分钟掌握终端Markdown阅读器的终极用法
Glow入门指南:5分钟掌握终端Markdown阅读器的终极用法 Glow是一个强大的 终端Markdown阅读器 ,专为命令行环境设计,让您在终端中优雅地阅读
CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考