💻️

ターミナルセッションを録画するツールVHSでのtips

2025/03/28に公開
8

はじめに

こんにちは、AWSでデベロッパーアドボケイトをしているものです。一昨日、Expert Onlineという企画で久々にターミナル上で行うデモをする必要があったのですが、時間がかかるデモだったので事前収録することにしました。しかし、長い時間がかかるのと、たまにターミナルに戻ってきて操作しなければならず、放ったらかしに出来ないのは時間の無駄だったので、なにかいいツールがないかと探したらVHSに行き着きました。

これが非常に便利だったので、その紹介と、デモに使う(特にプレゼンテーションスライドに埋め込む)場合のtipsを共有します。

VHSとはなにか

ターミナルセッションを録画するためのツールで、有名なものにはasciinemaがあります。多くの開発者ツールはGitHubのREADMEや公式ドキュメントにその動作をアニメーションGIFでデモを録画して埋め込んでいたりします。数秒〜数十秒程度のデモであればasciinemaで良かったのですが、先日のデモは数十分に及ぶため、アニメーションGIFでは難しく、どうしても動画ファイルで録画する必要がありました。そこで調べたところVHSに行き着いたというわけです。

VHSの特徴は次のとおりです。

  • 録画ファイルはアニメーションGIF、WebP、MP4 (H.264)のいずれかで選択可能
  • フォントやそのサイズ、画面サイズの設定が可能
  • カラーテーマの設定が可能
  • 入力待ちやスリープが可能
  • リッチな仮想的なターミナルウィンドウが設定可能
  • SSH経由でリモートのターミナルも録画可能

使い方

インストール

macOSであればHomebrewのcoreに入ってるのですぐにインストール可能です。

$ brew info vhs
==> vhs: stable 0.9.0 (bottled), HEAD
Your CLI home video recorder
https://github.com/charmbracelet/vhs
Installed
/opt/homebrew/Cellar/vhs/0.9.0 (10 files, 21.7MB) *
  Poured from bottle using the formulae.brew.sh API on 2025-03-25 at 00:02:42
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/v/vhs.rb
License: MIT
==> Dependencies
Build: go ✔
Required: ffmpeg ✔, ttyd ✔
==> Options
--HEAD
        Install HEAD version
==> Caveats
zsh completions have been installed to:
  /opt/homebrew/share/zsh/site-functions
==> Analytics
install: 250 (30 days), 1,051 (90 days), 3,939 (365 days)
install-on-request: 250 (30 days), 1,051 (90 days), 3,939 (365 days)
build-error: 0 (30 days)

$ brew install vhs

VHSはGo製なのでGoが入った環境であれば go install で入れるのも楽です。ただし動作させるのにはttydとffmpegが必要。

$ go install github.com/charmbracelet/vhs@latest

ほかにもLinuxであればdebやrpmのフォーマットで配布されていたり、Windowsだとscoopで入れることもできるようです。

操作方法

VHSという名前はある年齢以上の人であればピンとくるわけですが、家庭用ビデオテープの規格名ですね。というわけで、録画したい操作を .tape という拡張子の中に書いておくというのが慣例になっているようです。

操作の記述は専用DSLを使うわけですが、非常に単純なのでプログラムが書けない人でも問題なく記述できます。たとえば、macOS上で次のように sample.tape 書いて

Output sample1.webp
Set Shell zsh
Set FontSize 12
Set Width 600
Set Height 450
Set Framerate 60
Set Padding 10

Type "sw_vers"
Enter
Wait
Sleep 4s

Type "system_profiler SPHardwareDataType"
Enter
Sleep 3s

これを実行すると録画が開始されてどの操作をしているかが表示されていき、最後に録画ファイルを作るところまでが目視できます[1]

実行の様子

で上のスクリプトで生成された動画ファイルはこうなります。

実行の様子

DSLの一覧はプロジェクトのREADMEに記載されています。実際のタイピングと同様にバックスペースやタブ、Ctrl-Rなんかも動作します。もちろん矢印キーも動作します。これは下を5回、右を4回、上を3回、左を2回押したのと同様の動きをします。

Down 5
Right 4
Up 3
Left 2

操作を記録する

自分でゼロから .tape ファイルを記述するのが大変という場合には、下書きとして自分が入力したコマンドを記録してもらう record というモードがあります。次のコマンドは一旦自分の操作を demo.tape というファイルに保存して、それをあらためてVHSで録画しています。

vhs record > demo.tape
vhs demo.tape

これを使うことで冪等な操作であればそのままありのままを記録することも可能になります。

tips

好みの設定を固めておく

VHSではtapeファイルの中で他のtapeファイルを呼び出すことができます。

Output demo.mp4
Set WaitTimeout 10m

Source settings.tape

Type "echo $PATH"
Enter

ここで settings.tape は次のような設定を書いておきます。

Set Shell zsh
Set FontSize 20
Set Width 1600
Set Height 900
Set WindowBar Colorful
Set BorderRadius 10
Set Framerate 60
Set Theme "nord"
Set TypingSpeed 80ms

それぞれの設定は次のとおりです

  • Shell: 起動するシェルの種類を指定します
  • FontSize: デモ用なのでサイズを大きめに設定
  • Width, Height: スクリーンのサイズです。16:9で設定しておくとスライドに貼りやすい。
  • WindowBar: なんかぱっとみmacOSのターミナルで動作してるように見える。好み。
  • BorderRadius: 角丸のほうがかわいい
  • Framerate: 60FPSで十分だと思いますが、120や240がいい人はお好みで
  • Theme: 自分はターミナルもVS CodeもNordを使っているので合わせています
  • TypingSpeed: デフォルトのタイピングスピードは50msなのでちょっと速いと思うので遅くしています。

タイムアウト時間に注意

AIコーディングエージェントとかを使ってると、ざらに10分動きっぱなしになったりすることがあります。
そうするとプロンプトが帰ってこなくなるので、デフォルトだとタイムアウトしてしまいます。
自分はタイムアウトの設定値を伸ばして、コマンド実行中に終了してしまわないように変更してます。

Set WaitTimeout 10m

秘匿事項を入力しないといけない場合はHide

パスワードを入力しなければいけないような場合、HideとShowを使うことでそれを隠すことができます。さらにそれを別のtapeファイルに入れておけば使い回しも出来そうですね。たとえば login.tape というファイルを用意します。

Type "foo command log in..."
Hide
Ctrl+A
Ctrl+K
Type "foo login --password deadbeef && clear"
Enter
Show

これで foo コマンドのログイン動作中のパスワード入力などは録画されずにすみます。( login.tape でパスワードが丸見えなのはまた後で考えることにする)

作業をファイルで分割しておく

長い作業のデモを録りたい場合はtapeファイルを分割しておくのも良いと思います。

Output all.mp4
Set WaitTimeout 10m

Source step1.tape
Source step2.tape
Source step3.tape

step1.tapestep2.tapestep3.tape の作業に依存性がなければ別々に実行しても問題ないし、時間がないときは個々に録画しておくこともできます。

Output step1.mp4
Source step1.tape

動画ファイルはすべて同じコーデックで同じビットレートで作成されていて、VHSの動作条件としてffmpegが入ってる前提があるので、個々に実行してから最後に連結しても良いでしょう。

ここからはffmpegの話になってしまうけど、たとえば次のようなテキストファイル inputs.txt を作成しておきます。

file './step1.mp4'
file './step2.mp4'
file './step3.mp4'

このファイルを使って次のコマンドでファイルを無劣化で連結できます。

$ ffmpeg -f concat -safe 0 -i inputs.txt -c copy all.mp4

おわりに

まだVHSを使い始めたばかりなので、もっと便利な使い方があればぜひ知りたいです。

脚注
  1. これは vhs コマンドを実行するスクリプトを vhs コマンドに流すというおしゃれなことをしています。 ↩︎

8

Discussion