用途:把“给这个 README 加一个演示 GIF”变成可复现的流水线——先判断项目适合哪种录制方式,再生成可重录的脚本,渲染、优化文件体积,最后把 GIF 正确嵌入 README。核心目标是不要手工录屏后往仓库里塞一个 40 MB 的文件;每一步都脚本化,工具变化后可重新生成。
第一步,判断演示类型。看仓库信号:有 bin/、CLI 入口、package.json 的 bin 字段、argparse/click/cobra 代码或运行命令的 Dockerfile,属 CLI 工具,用终端录制(vhs);使用 TUI 框架(bubbletea、ratatui、textual、blessed、ink)属 TUI,用终端录制(vhs),窗口更大;有前端框架、dev server 脚本、index.html 的属 Web 应用,用浏览器录制(Playwright + ffmpeg);无独立入口、README 只有 import 与用法片段的库,用 REPL 或短示例脚本录成终端会话。若有歧义,应询问要展示哪个界面,而不是猜测。
第二步,生成录制脚本。终端场景首选 VHS:把 .tape 纯文本脚本确定性地渲染为 GIF/MP4/WebM,同样输入总得到同样输出,因此优先于录屏软件。安装:macOS 用 brew install vhs;Windows 用 scoop install vhs 或 winget install charmbracelet.vhs;Debian/Ubuntu 需先加 Charm 仓库再 sudo apt install vhs ffmpeg,ttyd 从 GitHub releases 单独安装;有 Go 可 go install github.com/charmbracelet/vhs@latest;Docker 用 docker run --rm -v $PWD:/vhs ghcr.io/charmbracelet/vhs <file>.tape。tape 文件最小结构包含 Output、Set Shell/FontSize/Width/Height/Theme 以及 Type/Enter/Sleep。渲染命令为 vhs demo.tape。无法安装 vhs 的终端回退方案是 asciinema rec demo.cast 后用 agg demo.cast demo.gif --theme monokai --speed 1.5 --idle-time-limit 2 转换,但可复现性较差。Web 应用用 Playwright 的 recordVideo 上下文选项录制浏览器会话,脚本需在结束时 await context.close(),否则视频不生成;再把视频转成 GIF。
第三步,渲染。终端由 vhs demo.tape 直接产出;Web 先跑 Playwright 脚本再转 GIF。优化前先看原始输出,若文字太小、时长过长、有明显错误或首尾空白,应重录脚本而非事后裁剪。
第四步,优化。目标小于 8 MB(GitHub 约 10 MB 起截断显示,原始上传上限 25 MB)。视频源用 ffmpeg 两遍调色板:先 palettegen 生成 palette.png,再用 paletteuse=dither=sierra2_4a 输出;两遍优于单遍固定 256 色表。已是 GIF 则用 gifsicle -O3 --lossy=30 --colors 128 优化。帧率 10–15 fps、宽度约 800px、总时长 10–25 秒即可;仍过大就依次降帧率、降宽度、提高 lossy,最后才缩短时长。用 ls -la 确认体积。
第五步,嵌入 README。文件放 docs/demo.gif 或 .github/demo.gif 并提交进仓库,不要外链图床。普通 markdown 用 ,需控制宽度用 img 标签。明暗主题可用 URL 片段 #gh-dark-mode-only / #gh-light-mode-only 提交两版;首版可先选一种。位置放在标题与一句话简介之后、安装说明之前。
常见失败:vhs 输出全黑多为 ttyd 缺失(vhs validate 不检查 PATH 依赖);Playwright 视频为 0 字节是未关闭 context;GIF 出现色带是用了单遍编码或颜色数过低;报 invalid Set Theme 是主题名大小写敏感,可用 vhs themes 查询;gifsicle/agg 未安装时回退 mp4 往返未必更小,需实测比较。文中未提供的价格、平台支持范围等信息暂未给出。