news 2026/9/19 18:32:19

使用 VHS 编写 `.tape` 脚本:为 gws(Google Workspace CLI)制作终端演示 GIF/MP4 的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 VHS 编写 `.tape` 脚本:为 gws(Google Workspace CLI)制作终端演示 GIF/MP4 的完整指南

使用 VHS 编写.tape脚本:为 gws(Google Workspace CLI)制作终端演示 GIF/MP4 的完整指南

【免费下载链接】cliGoogle Workspace CLI — one command-line tool for Drive, Gmail, Calendar, Sheets, Docs, Chat, Admin, and more. Dynamically built from Google Discovery Service. Includes AI agent skills.项目地址: https://gitcode.com/gh_mirrors/cli413/cli

VHS 是 Charmbracelet 出品的终端录屏工具,它通过读取.tape脚本文件把终端会话录制为 GIF、MP4 或 WebM。本指南以 gws(Google Workspace CLI)仓库的演示录制实践为核心,讲解.tape文件的语法规则、引号陷阱、录制参数与常见命令,并结合 docs/demo.tape 这一真实工程示例,让读者既能学会编写可复现的终端演示脚本,也能掌握本仓库"场景化 + 隐藏 setup"的录屏编排方法论。

为什么用脚本录制终端演示

终端演示(Demo)是开源项目 README、发布公告和功能宣传中最直观的表达方式,但手工录屏存在几个痛点:手速不稳定、容易打错字、难以重录、无法版本化。VHS 用.tape文本脚本解决了这些问题——录制内容是一份可提交进 Git 仓库的普通文本文件,任何改动都能走 code review,任何机器都能重放。

在 gws 仓库中,演示录制是开发流程的一等公民:

  • AGENTS.md 明确说明"Demo recordings are generated with VHS (.tapefiles)",并给出运行命令vhs docs/demo.tape
  • 仓库根目录存放着最终产物 demo.gif,由 docs/demo.tape 生成;
  • 仓库提供 npm 包(@googleworkspace/cli),发布流程与录制脚本相互独立,docs/demo.tape只负责展示 CLI 能力,不参与构建。

基本使用方式只需一条命令:

vhs docs/demo.tape

VHS 会按脚本从上到下逐条执行指令,最终在Output指定的路径产出录屏文件。

关键语法规则:指令分隔与引号闭合

.tape脚本最容易出错的地方不是命令本身,而是"一行里同时出现多个指令"时的解析规则。

Type、Sleep、Enter 是同一行上的独立指令

TypeSleepEnter同一行内用空格分隔的独立指令Type字符串的右引号是它们之间的分界符。最常见的 bug 是忘记闭合Type字符串,导致Sleep/Enter被当成字面文本敲进终端:

# ✅ CORRECT — closing " before Sleep Type "echo hello" Sleep 300ms Enter # ❌ WRONG — Sleep and Enter are typed as literal text Type "echo hello Sleep 300ms Enter

检查每一条Type行时,务必确认:只要该行后面还跟着SleepEnter,字符串必须先闭合引号。

Type@<time>覆盖单条命令的打字速度

TypingSpeed设置的是全局打字速度,但有时需要在某一条命令上放慢(例如 JSON 参数想让观众看清)或加快。VHS 支持在Type后紧跟@加时间,中间不能有空格

Type@80ms '{"pageSize": 2}' Sleep 100ms

这条指令以每字符 80ms 的速度敲入{"pageSize": 2}。仓库的 docs/demo.tape 中就有实战用例——在演示自动分页时,用Type@30ms慢速敲入 JSON 参数,制造"观众能看清关键载荷"的节奏:

Type "gws drive files list" Type " --params '" Sleep 50ms Type@30ms '{"pageSize":2,"fields":"nextPageToken,files(id)"}' Sleep 50ms Type "'" Type " --page-all" Type " | jq -r '.files[]?.id'" Enter Sleep 6s

引号的三条规则

  1. 双引号"..."Type的标准分隔符;
  2. 单引号'...'同样可用,当敲入的内容本身含双引号(如 JSON)时优先使用单引号,避免转义地狱;
  3. 反引号用于在双引号字符串内部转义引号:Type `VAR="value"`

AGENTS.md 补充了一个重要限制:VHS 不支持双引号Type字符串内的\"转义,强行使用会直接导致解析错误。因此当要敲入含双引号的 JSON 时,正确姿势是整行改用反引号:

Type `gws drive files list --params '{"pageSize":5}'` Enter

嵌套引号:把一条命令拆成多行 Type

当构建包含多层嵌套引号的 shell 命令(例如gws--params要传 JSON、JSON 里又要写含双引号的fields表达式)时,不要试图一行写完,而是拆成多段Type,每段之间用Sleep制造打字节奏:

Type "gws drive files list --params '" Sleep 100ms Type@80ms '{"pageSize": 2, "fields": "nextPageToken,files(id)"}' Sleep 100ms Type "' --page-all" Sleep 300ms Enter

Pitfall 总结:凡是一行Type后面还跟着SleepEnter,必须先把字符串闭合。逐行审计是编辑.tape文件的基本功。

Settings:文件顶部的录制参数

Settings指令只能出现在文件顶部——任何非设置指令(Output除外)出现之前。唯一的例外是TypingSpeed,它是唯一允许在脚本中途改动的设置。

仓库 docs/demo.tape 顶部的实际配置如下:

Output docs/demo.mp4 Output docs/demo.gif Set Shell "bash" Set FontSize 18 Set Width 800 Set Height 500 Set TypingSpeed 1ms Set Padding 30 Set LineHeight 1.3

与技能文档中的标准配置对比,可以观察到两个值得注意的点:

设置项技能文档示例demo.tape 实际值说明
Shellbashbash录制使用的 shell
FontSize1418字号越大,终端行数越少,适合竖屏展示
Width/Height1200/1200800/500横屏宽高比,接近视频封面比例
TypingSpeed40ms1msdemo 里几乎瞬间敲完,靠Sleep控制节奏
Padding2030画面内边距
WindowBar/ThemeColorful/Catppuccin Mocha未设置(默认)主题与窗口栏样式可选配置

注意 docs/demo.tape 使用了两条Output指令同时产出 MP4 和 GIF——这是"一次录制、多格式分发"的实用技巧,可适配 README 内嵌与视频平台两种场景。

一个完整的标准设置块长这样:

Output demo.gif Set Shell "bash" Set FontSize 14 Set Width 1200 Set Height 1200 Set Theme "Catppuccin Mocha" Set WindowBar Colorful Set WindowBarSize 40 Set TypingSpeed 40ms Set Padding 20

常用命令速查

命令示例说明
OutputOutput demo.gif输出文件,支持.gif.mp4.webm,可多次指定
TypeType "ls -la"逐字符敲入文本
Type@<time>Type@80ms "slow"覆盖该条指令的打字速度
SleepSleep 2sSleep 300ms暂停录制(等待命令输出或控制节奏)
EnterEnter回车
Hide/ShowHide...Show隐藏/显示录制内容,常用于跳过 setup 命令
Ctrl+<key>Ctrl+C组合键
TabSpaceBackspaceTab 2可带重复次数
UpDownLeftRightUp 3方向键,可带次数
WaitWait /pattern/等待屏幕出现匹配正则的内容
ScreenshotScreenshot out.png截取当前帧为图片
EnvEnv FOO "bar"设置环境变量
SourceSource other.tape引入另一个 tape 文件
RequireRequire jq断言外部程序存在,不存在则报错

Hide/Show:把 setup 藏起来

录屏时,export PATH、创建测试数据、clear这类准备工作既冗长又不该出现在成片里。Hide之后的指令不进入画面,直到Show恢复录制。技能文档给出的标准模式:

Hide Type "export PATH=$PWD/target/release:$PATH" Enter Type "clear" Enter Sleep 2s Show

docs/demo.tape 把这个模式用到了极致:开头一大段隐藏的 setup 里,先 mock 一个gemini命令保证演示结果确定性,再设置 PATH,然后用真实的gws drive files create在 Google Drive 上创建一个gws-demo文件夹和三个演示文件,最后clearShow,观众看到的直接是干净的演示起点:

Hide # Mock gemini CLI for deterministic demo Type 'function gemini() { echo "Why do Java developers wear glasses? Because they don'"'"'t C#."; }' Enter Type "export -f gemini" Enter Type "export PATH=$PWD/target/release:$PWD/target/debug:$PATH" Enter Type "set -e" Enter Sleep 1s Type `DEMO=$(gws drive files create --json '{"name":"gws-demo","mimeType":"application/vnd.google-apps.folder"}' | jq -r '.id')` Enter Sleep 3s Type `gws drive files create --json "{\"name\":\"meeting-notes.md\",\"mimeType\":\"text/markdown\",\"parents\":[\"$DEMO\"]}" > /dev/null` Enter Sleep 2s ... Type "clear" Enter Sleep 1s Show

这段代码还示范了几个进阶技巧:

  • function gemini()mock 外部 AI 命令,让演示输出可预测("deterministic demo");
  • DEMO=$(...) | jq -r '.id'把 API 返回值存进 shell 变量,后续命令引用$DEMO
  • 每条真实 API 调用后都给了Sleep 2s~3s,而纯本地操作(clear)只给Sleep 1s甚至500ms——这与技能文档检查清单第 3 条"网络调用可能需要 8s+ 的等待"的原则一致。

场景化编排:ASCII 标题卡与章节节奏

一份好的 demo 不只是命令流水账,而是有起承转合的"剧本"。gws 仓库的做法是用 ASCII art 标题卡切分章节:art/ 目录下存放intro.txtscene1.txtscene9.txtoutro.txt等标题卡,scripts/show-art.sh负责"清屏 + 打印":

#!/bin/bash clear cat "$1"

每张标题卡都是一幅纯文本场景画,例如 art/scene1.txt:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 🤖 WHAT IS GWS? ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ A single CLI for ALL Google Workspace APIs. Perfect for: 🤖 AI agents 📜 Shell scripts ⚡ Power users 📊 Automation

在 docs/demo.tape 中,每个场景的编排套路是固定的:HideType "./scripts/show-art.sh art/sceneN.txt" EnterSleep 1sShowSleep 1s→ 敲入该场景要演示的真实命令 → 等待输出。例如 Scene 4 展示"按文件夹查询文件列表":

Type "gws drive files list" Type ` --params "{\"q\":\"$Q\",\"fields\":\"files(name,mimeType)\"}"` Enter Sleep 3s

Scene 6 展示 Gmail 发信(base64 编码 raw 消息 +jq美化输出),Scene 8 展示 Sheets 追加数据(--paramsspreadsheetId/range/valueInputOption--jsonvalues),Scene 9 展示自动分页(--page-all)。整个脚本从 intro 到 outro 共 9 个场景,最后隐藏执行清理(删除演示文件夹),形成完整闭环。

--page-all自动分页能力对应 gws 的--page-all全局参数,与 crates/google-workspace-cli/src 中的分页处理逻辑配套,录制脚本直接以真实 CLI 行为作为演示内容,保证了"所见即所得"。

编辑 Tape 文件的自检清单

技能文档给出的五条检查项,是每个.tape文件提交前的必备体检:

  1. 每条Type字符串必须闭合——在Sleep/Enter出现在同一行之前;
  2. 多行 Type 拼接的 shell 命令——确保最后一行闭合字符串且包含Enter
  3. Sleep 时长要够命令执行完——网络调用可能需要 8s+;
  4. Settings 放在顶部——只有TypingSpeed可以出现在后面;
  5. 提交前本地测试——运行vhs <file>.tape完整重放一遍。

对照 docs/demo.tape 可以再加三条仓库级经验:

  • 单行命令更可靠:脚本开头注释写着 "Single line commands for reliability"——需要多行拼接时,尽量用Type分段 + 反引号包裹 JSON,而不是依赖 shell 续行符;
  • 注释即剧本:用# ╔═...╗这类分隔注释标注章节边界,让脚本本身可读、可评审;
  • 善用> /dev/null:setup 阶段的创建命令输出会干扰画面,重定向掉,只保留正式演示的输出。

何时使用、何时放弃

.tape脚本适合:README 功能演示、PR 行为验证、发布公告视频、需要"可评审 + 可重放"的录屏。但它也有适用边界:高度交互式的 TUI 操作(如 gws 的 setup_tui.rs 这类需要光标定位的界面)录制难度较高;画面比例需要按目标平台规划(横屏适合 README,竖屏适合短视频);录制依赖真实网络时(如本 demo 中的 Drive/Gmail/Calendar API 调用),需要提前准备好凭据与测试数据,并给足Sleep时间。

对于 gws 这样的命令行项目,vhs docs/demo.tape一行命令即可复现整条演示链路:从.tape脚本 → VHS 解析执行 →docs/demo.gifdocs/demo.mp4双格式产物。掌握本文的语法规则与场景编排方法后,你完全可以把这套"脚本化录屏"流程复制到自己的项目中。

【免费下载链接】cliGoogle Workspace CLI — one command-line tool for Drive, Gmail, Calendar, Sheets, Docs, Chat, Admin, and more. Dynamically built from Google Discovery Service. Includes AI agent skills.项目地址: https://gitcode.com/gh_mirrors/cli413/cli

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 18:30:49

安当RDM移动存储与外设管控实践:用文件级白名单堵住U盘泄密通道

一、为什么外设是勒索与泄密的"侧门" 很多安全建设把重心放在边界防火墙、邮件网关和内网检测上&#xff0c;却忽略了物理接口这一层。一台已经装好杀软的办公电脑&#xff0c;插上一块来历不明的U盘&#xff0c;勒索载荷就可能直接落盘&#xff1b;一份标注"机…

作者头像 李华
网站建设 2026/9/19 18:30:40

软件质量如何量化?从评价标准到测试验收与运维指标

简介&#xff1a;软件质量评价标准是衡量软件质量的重要参照。这份docx文档面向软件开发人员、质量管理人员及企业软件选购决策者&#xff0c;系统讲解了软件质量评价的核心框架与方法&#xff0c;填补了质量评价标准模糊、缺乏量化指标的实际缺口。文档依据B.W.Boehm和R.Brown…

作者头像 李华
网站建设 2026/9/19 18:30:26

DME测距原理与工程实践:从脉冲对到参数校准

简介&#xff1a;在航空无线电导航体系中&#xff0c;测距系统为飞行器提供关键的位置信息。DME&#xff08;地美依系统&#xff09;作为最常用的测距来源&#xff0c;其工作原理可概括为“一问一答”的脉冲对协议&#xff1a;机载询问器发射脉冲对&#xff0c;地面台经固定延迟…

作者头像 李华
网站建设 2026/9/19 18:24:32

从零打造高性能Markdown编辑器:实时预览、滚动同步与性能优化实践

用了六年 Markdown&#xff0c;我写长文、记笔记、写周报、存技术文档&#xff0c;几乎所有的文字产出都靠它。可越用越觉得不对劲&#xff1a;好看的编辑器通常功能单薄&#xff0c;功能扎实的又大多丑得让人提不起力气写东西。折腾了十几个工具之后&#xff0c;我决定自己动手…

作者头像 李华
网站建设 2026/9/19 18:23:45

WPF跨平台落地Ubuntu:LibreWPF.Sdk + WebGPU实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华