AIGC标识 Terminalizer 介绍与使用:从安装到 MP4 终端录屏

Terminalizer 介绍与使用:从安装到 MP4 终端录屏

Terminalizer 是一个用 Node.js 编写的命令行录屏工具。它记录的不是整块桌面,而是终端里的输入、输出和时间间隔,最后可以回放或渲染成 GIF。

我最近在 myvideo-tools 里加了一组验证脚本,顺手把从安装到交付 MP4 的过程跑了一遍。这篇文章就按使用顺序记录下来。

Terminalizer 适合做什么

Terminalizer 适合录制这些内容:

  • 命令行工具的安装和初始化;
  • Git 分支、构建、测试等操作;
  • CLI 工具的使用教程;
  • 技术文章里的终端演示片段。

它的工作方式比较直接:先把终端会话保存成 YAML,再用这个文件回放或渲染。

record → play → render

环境准备

本文使用的环境如下:

Node.js:v22.23.1
npm:10.9.8
Terminalizer:0.12.0
FFmpeg:6.1.1
平台:WSL2 / Linux

先确认 Node.js 和 npm:

node --version
npm --version

版本号不是必须和本文完全一致,只要满足 Terminalizer 当前版本的运行要求即可。发布文章时,最好重新执行一次这两个命令,不要照抄本机版本。

安装 Terminalizer

最直接的安装方式是 npm 全局安装:

npm install --global terminalizer

我在录屏时使用了下面这个版本,主要是减少 npm 输出对画面的干扰:

npm install --global terminalizer --no-fund --no-audit --progress=false

这些参数不是 Terminalizer 的要求:

  • --global:安装成全局 CLI;
  • --no-fund:隐藏 funding 提示;
  • --no-audit:跳过本次 audit;
  • --progress=false:关闭 npm 的 spinner,避免录屏中出现一串控制字符。

安装完成后检查版本和路径:

terminalizer --version
which terminalizer

我的输出是:

0.12.0
/home/stl/.nvm/versions/node/v22.23.1/bin/terminalizer

路径会随系统和 Node.js 管理方式变化。使用 NVM 的用户通常会看到 NVM 目录;使用系统 Node.js 的用户可能会看到 /usr/local/bin/terminalizer 或其他路径。

全局安装会修改当前 Node.js 版本对应的 npm 全局环境。如果只是个人使用,这种方式最省事。如果要在团队或 CI 中固定版本,再考虑项目级 package.json 和 lock 文件。

第一个录制

Terminalizer 的基本命令是:

terminalizer record demo

执行后,Terminalizer 会打开一个交互式终端。接下来在里面输入命令,例如:

echo "hello terminalizer"
pwd

完成后按 Ctrl+D 结束录制。默认会得到:

demo.yml

也可以直接使用 .yml 后缀,具体以当前版本 CLI 的提示为准。

回放录制文件:

terminalizer play demo.yml

渲染 GIF:

terminalizer render demo.yml -o demo.gif

到这里,最小流程就跑通了。

为什么自动录制时会遇到 TTY 错误

我第一次在自动化 Shell 里测试 terminalizer record 时遇到了:

TypeError: process.stdin.setRawMode is not a function

这个错误的意思不是 Terminalizer 没装好,而是当前标准输入不是交互式 TTY。Terminalizer 需要把输入切换成原始模式来读取按键,普通管道没有这个能力。

Linux 下可以用 script 创建一个伪终端:

script -q -E never -e -c "terminalizer record demo --skip-sharing" /dev/null

几个参数的作用:

  • -c:指定要运行的命令;
  • -q:减少 script 自身输出;
  • -E never:关闭额外输入回显;
  • -e:让 script 返回子进程的退出码;
  • /dev/null:不保存额外的 typescript 文件。

如果要自动给终端输入内容,可以把输入通过管道送进 script

{
  sleep 1
  printf '%s\n' 'echo Terminalizer smoke test'
  sleep 1
  printf '\004'
} | script -q -E never -e -c "terminalizer record demo --skip-sharing" /dev/null

这段命令的关键是:Terminalizer 仍然运行在伪终端里,而不是直接从普通管道读取。

回放和渲染

录制文件本身是 YAML 文本,可以打开查看。里面保存了录制配置和终端事件。

常用命令:

# 回放
terminalizer play demo.yml

# 渲染 GIF
terminalizer render demo.yml -o demo.gif

渲染时如果在 WSL 或无桌面 Linux 环境下看到类似下面的提示:

Failed to call method: org.freedesktop.portal.Settings.Read
Exiting GPU process due to errors during initialization

先看命令最后是否显示 Successfully Rendered,再检查输出文件。如果 GIF 能生成,通常说明这些是 Electron/桌面环境的警告,不影响本次渲染。

用 FFmpeg 转成 MP4

Terminalizer 原生更偏向 GIF 输出。GIF 便于快速预览,但 MP4 更适合上传、剪辑和网页播放。我采用了下面的转换方式:

ffmpeg \
  -y \
  -i demo.gif \
  -an \
  -vf 'fps=30,scale=trunc(iw/2)*2:trunc(ih/2)*2,format=yuv420p' \
  -c:v libx264 \
  -crf 23 \
  -preset medium \
  -movflags +faststart \
  demo.mp4

参数不需要全部记住,重点是:

  • libx264:输出 H.264;
  • yuv420p:兼容大多数播放器;
  • fps=30:统一帧率;
  • scale=trunc(iw/2)*2:trunc(ih/2)*2:保证宽高是偶数;
  • +faststart:让网页播放更快开始。

转换完成后可以用 FFprobe 检查:

ffprobe -v error \
  -show_entries format=format_name,duration \
  -show_entries stream=codec_name,width,height,pix_fmt,avg_frame_rate,nb_frames \
  -of default=noprint_wrappers=1 \
  demo.mp4

让命令看起来像手工输入

自动化脚本通常会把整行命令一次性送进终端,最终画面像这样:

$ git switch -c ...

然后整行突然出现。这对验证没有影响,但作为教程视频观感比较生硬。

验证工程里的工作流脚本使用 Bash 的 DEBUG hook,在真正执行命令前按字符输出命令。当前设置大约每个字符间隔 25ms

myvideo-tools (master) $ git switch -c br_to_master_stlong309_terminalizer-beautify_20260717

这只是改变画面呈现方式。Git、npm 和冒烟测试仍然由真实 Shell 执行,输出也来自真实命令。

让终端像一个窗口

默认 Terminalizer 画面容易像一块黑色矩形。可以在配置文件中启用窗口式 frame:

frameBox:
  type: window
  title: "MYVIDEO-TOOLS  /  TERMINALIZER"

我使用的配色来自仓库已有的技术教程视觉规范:

背景:#0d0d0d
主文字:#f0f0f0
强调色:#D4501E
成功色:#7CFC00
字体:Space Mono / Ubuntu Mono / monospace

完整配置位于:

projects/terminalizer-verify/workflow-config.yml

如果不需要品牌化,可以直接使用 Terminalizer 默认配置。窗口标题、字体和配色属于交付层的选择,不影响 Terminalizer 本身的录制能力。

一个完整的验证案例

为了验证这套流程,我在 myvideo-tools 中创建了:

projects/terminalizer-verify/
├── README.md
├── smoke-test.sh
├── record-workflow.sh
├── workflow-config.yml
├── terminalizer-cnblogs-plan.md
├── terminalizer-cnblogs-article.md
├── work/
└── renders/

其中:

  • smoke-test.sh:验证 record、play、render 和 FFprobe;
  • record-workflow.sh:录制从安装到冒烟结束的完整工作流;
  • workflow-config.yml:窗口、字体、颜色和终端尺寸;
  • work/renders/:本地生成物,不提交到 Git。

完整工作流里还会创建一个一次性 Git 仓库,在其中执行:

node --version
npm --version
npm install --global terminalizer --no-fund --no-audit --progress=false
terminalizer --version
which terminalizer
git switch -c br_to_master_stlong309_terminalizer-beautify_20260717
git branch --show-current
bash projects/terminalizer-verify/smoke-test.sh
git status --short --branch
exit

一次性仓库只用于让录屏里的 Git 操作真实可重复,工作流结束后会清理。npm 全局安装则使用当前机器的真实 Node.js 环境,所以录制前需要确认全局安装的副作用是可以接受的。

还有一个实际限制:Terminalizer 不能在完全未安装自己的状态下启动录制。因此“从安装开始”的视频,需要由已经存在的外层 Terminalizer 负责录制,录屏内容再执行真实的 npm 安装。这是工具自录时无法绕开的启动条件。

最后状态和播放器进度条

录屏最后通常会执行:

git status --short --branch

状态输出如果贴近底部,可能被博客播放器或视频控件的进度条挡住。验证脚本在最后状态检查后补充了几行空白,再执行:

exit

这样终端最后的状态结果会留出一点底部空间。这个空白不是终端操作的一部分,只是为了让交付视频更容易观看。

常见问题

terminalizer: command not found

检查安装路径:

which terminalizer
npm list --global --depth=0 terminalizer

如果 Node.js 使用 NVM 或 Conda,先确认当前 Shell 使用的是期望的 Node 版本。

process.stdin.setRawMode is not a function

当前进程没有 TTY。使用 script 创建伪终端,或者在真实交互式终端中直接录制。

npm 提示 boolean@3.2.0 已弃用

这是 Terminalizer 的间接依赖提示,不影响本次安装和验证。它也提醒我们:Terminalizer 本身及其依赖并不是一个可以完全忽略维护状态的工具。用于教程录制没有问题,生产自动化则应固定版本并评估依赖风险。

WSL 中的 DBus/GPU 警告

只要渲染命令最终成功、输出文件存在,并且 FFprobe 能读出正确的视频信息,就可以先把这些警告视为环境提示。

总结

Terminalizer 的使用路径并不长:安装、录制、回放、渲染,再按需要转换成 MP4。真正花时间的是录制环境和交付细节:TTY 是否可用,命令是否像人手输入,窗口是否看起来像终端,最后的输出是否被播放器控件挡住。

把这些问题处理好,Terminalizer 就不只是一个生成 GIF 的命令,而是一套可以用于技术教程和 CLI 演示的录制工具。

posted @ 2026-07-20 17:06  suntl  阅读(3)  评论(0)    收藏  举报