大昔に一度使った覚えはあるが再度入門した
ターミナル上に表示されるテキストデータを記録して専用のplayerで動画として再生可能にするためのツール
よくブログとかであるような「このコマンドを実行して結果はこうなりました」というのを共有するための用途としてはよさそう
専用playerの動画もテキストがコピーできるので便利
こんな感じ
とりあえず試してみる
apt,brewなどもあったがとりあえず使ってみたかったという感じなのでpipでインストールして使ってみた
pip install asciinema asciinema rec demo.cast # なにかしらの操作 asciinema play demo.cast
recで別シェルが立ち上がり、シェルを抜けると実行されたコマンドが記録される(demo.cast)
記録されたファイルをplayで指定し再現する
特定コマンドのレコード
特定コマンドのレコードも可能
-cオプションで指定する
asciinema rec -c htop demo.cast
htopを起動する、終了したらレコードも終了する
入力キーのキャプチャ
rec --stdin で入力文字の記録ができる
サービスにアップしたら動画の画面右下にそのタイミングで押下したキーを表示してくれる(Ctrl+j)など
ただ、入力した瞬間しか表示されないので正直これを見て「なるほどね」となるかというと怪しいかな…という印象だった
あと、Alt+bとか物によっては表示されないものもあるようでちょっとデフォルトの機能だけに頼るのは厳しそうだなという感じだった
option(play)
asciinema play --help
usage: asciinema play [-h] [-i IDLE_TIME_LIMIT] [-s SPEED] [-l] [-m] [--out-fmt {raw,asciicast}] [--stream {o,i}] filename
positional arguments:
filename local path, http/ipfs URL or "-" (read from stdin)
optional arguments:
-h, --help show this help message and exit
-i IDLE_TIME_LIMIT, --idle-time-limit IDLE_TIME_LIMIT
limit idle time during playback to given number of seconds
-s SPEED, --speed SPEED
set playback speed (can be fractional)
-l, --loop loop loop loop loop
-m, --pause-on-markers
automatically pause on markers
--out-fmt {raw,asciicast}
select output format
--stream {o,i} select stream to play
詳しくはhelpを読めばよいがよく使いそうなものをピック
-s 1.7
1.7倍で再生する
-i 2
アイドルタイム(何もアクションが無い時間)を短縮できる(2秒アクションが無い時間をアイドルタイムとして短縮して再生する)
player
会員登録してログインすればそこに上げてHTML上で埋め込み再生が可能
登録せずローカルで環境を用意し再生する方法もある
docker composeを利用するか、単純なHTMLだけ用意して再生する
今回は再生だけ試せればOKなので単純なHTMLを用意して再生してみる
最小でのプレイならmin.jsなどがrelease pageに用意されているのでそれを落としてHTMLをserveすれば見れる
npmパッケージもあるからReactなどと合わせて好みにカスタマイズさせることも可能そう
ドキュメントは今辺見れば良さそう
最小のHTMLを作成して再生
執筆時の最新バージョンのファイルを落としてきて
curl -LO https://github.com/asciinema/asciinema-player/releases/download/v3.8.1/asciinema-player.css curl -LO https://github.com/asciinema/asciinema-player/releases/download/v3.8.1/asciinema-player.min.js
HTMLファイルを作って
- index.html
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="/asciinema-player.css" /> </head> <body> <div id="demo"></div> <script src="/asciinema-player.min.js"></script> <script> const player = AsciinemaPlayer.create('/readme_exec.cast', document.getElementById('demo'), { theme: 'solarized-dark', terminalFontFamily: "'JetBrainsMono Nerd Font', monospace", idleTimeLimit: 1, markers: [ [9.0, "ls with icon"], [11.0, "Ctrl+g , m"] ] }); player.addEventListener('input', ({ data }) => { console.log('input!', JSON.stringify(data)); }) </script> </body> </html>
python -m http.server 8080
でlocalhost:8080/index.htmlを見に行くと無事閲覧できた
以下playerオプションとか操作からピックアップする
スタート、ストップ
再生中、スペースキーでpause resumeが可能
font
player側の設定もNerdFontなどが必要な場合は対応しているフォントを指定する必要がある
terminalFontFamily: "'JetBrainsMono Nerd Font', monospace",
marker
このタイミングでInstallした、このタイミングで実行した!みたいなマーカーを付けられる
AsciinemaPlayer.create時のオプションで指定する
{ markers: [ [1.0, "なにかした!"] ] }
1.0秒時点でなにかした!
castファイルとは別の情報なのでHTMLにベタ書きしている
そして、スピードやアイドルタイムなどのオプションによって秒数が変わってしまうのでこれはなかなか厳しい…となった
ただ共有する側からしたら便利ではある

キー入力イベントのロギング
playerのイベントとして入力キーを受け取ることができるよう
player.addEventListener('input', ({ data }) => { console.log('input!', JSON.stringify(data)); })

入力したキーが記録されているので、入力したタイミングでイベントを受け取れる
cmdは\u0015かな
この辺をよしなにしてローカルのplayerを作り込めばKeyCast的な見た目もできるかな? と思ったが
tmuxのコピーコマンドは何もキャプチャされてなかった(Ctrl+[)おそらく空文字…
押下されたキーすべてを記録したい場合はやはりKeyCastとかを使ったほうが確実かな…という気になった
ということでいったん諦めた、時間を見つけて再挑戦したい
キャプチャの対象範囲
そりゃそうかって話でもあるんだけど、tmuxの機能を使って範囲選択→コピーは反映されてなかった
また、iTerm上の文字列も手動で選択→コピーしたときも反転などはされなかった
あくまでasciinemaでシェル起動したその中での世界の範囲のテキストデータがキャプチャ対象
まぁそうだよねと納得した
castファイルの中身を見たらansiエスケープカラーコードが出力されていたので表示側で解釈してねという感じのよう
なのでカスタムのカラーテーマを使っている場合なども設定の色どおりに出力されない可能性がある
逆に同じcastファイルでもテーマ変えることができる(サンプルはSolarized Darkを設定した)
gif化
動画で見れるようになりました、便利です!
そうはいってもやはりGif画像でなんとかしたいパターンはある…ということで
agg - asciinema gif generator - asciinema docs
これ使えばOKらしい
同じ組織が作っているよう、asciinemaで生成したcastファイルをInputにしてアニメーションGifを生成するコマンド
agg demo.cast demo.gif
これだけでdemo.gifが生成される
専用のPlayerを用意できない、画像ファイルしか使えないなどの場合はこの方法でGif化すればほぼ動画と同様のみためとなる
とりあえず記録しておいてあとでcastファイルを編集してGif化するとかもできるのでまぁ色々活用はできる
Font指定
NerdFontのアイコンなど、フォントが必要な場合、Gif生成時にもフォント指定する必要がある
agg --font-family "JetBrainsMono Nerd Font" readme_exec.cast readme.gif
当然だが実行環境に対象フォントがインストールされている必要がある
WSLを使っている場合、普段はホスト側にインストールするだけでOKだがこのコマンドを実行するのはWSLの環境上なのでWSLで動いているマシンにもフォントをインストールする必要がある

とりあえず今回のサンプルをアップロードしたのでplayerを埋め込んでおいた
<script src="https://asciinema.org/a/691810.js" id="asciicast-691810" async="true"></script>
所感
- テキストで結果が保存されている(ndjson)ため、比較的容易に編集可能
- 専用Playerが公開されているのでログインせずとも再生できる
- ログインしてアップロードすれば、共有用の埋め込みが簡単にできる
- Gif化コマンドも用意されているので活用の幅は広い
- とりあえず「あとで参照するかもな?」と感じたら起動して記録しておくのがよいかな
- とりえあずrecしておけばあとは操作に集中できる
- あとで動画見ながらコピーして…というのができるのでブログ記事書く際にも良さそう