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 演示的录制工具。
本文来自博客园,作者:suntl,转载请注明原文链接:https://www.cnblogs.com/stlong/p/21583747

https://img2024.cnblogs.com/blog/389185/202607/389185-20260717145610555-1195747630.png
浙公网安备 33010602011771号