A terminal-to-gif recorder minus the headaches.
Record your terminal and compile it to a GIF or APNG without any external dependencies, bash scripts, gif concatenation, etc.
Install with: $ npm install ttystudio
. (Add -g
for global install).
$ ttystudio output.gif --log
$ vim
hello world
:q!
$ ^Q # stop recording with ctrl-q
initializing writer
writing image
writing head
writing frame 0 - 132 left
writing frame 1 - 131 left
writing frame 2 - 130 left
...
writing frame 131 - 1 left
writing eof
wrote image to /home/chjj/output.gif
$ chromium output.gif
# or if you wrote to output.png (an APNG)
$ firefox output.png
ttystudio differs from other terminal recorders in that:
This project has ended up making use of years of work I've done writing terminal libraries (my personal obsession). Once all the pieces were there, this project became possible. It also sprang out of a need to find a terminal-to-gif recorder that actually worked.
(NOTE: The above .gif was recorded with ttystudio - nested ttystudio instances cause a slight glitch where the cursor is not visible. Not to matter in most cases).
$ ttystudio output.gif --log # record and compile
$ ttystudio frames.json --log # record
$ ttystudio frames.json output.gif --range=0-50 # compile
$ ttystudio --record frames.json --interval=100 # grab each frame on a 100ms interval
$ vim
hello world
:q!
$ ^Q # stop recording with ctrl-q
$ ttystudio --compile frames.json output.gif --log
parsing json
initializing writer
writing image
writing head
writing frame 0 - 132 left
writing frame 1 - 131 left
writing frame 2 - 130 left
...
writing frame 131 - 1 left
writing eof
wrote image to /home/chjj/output.gif
$ chromium output.gif
# or if you wrote to output.png (an APNG)
$ firefox output.png
$ ttystudio --record frames.json
:
blessed+term.js+pty.js will spawn a
pseudo-terminal to let you record until you press ^Q.$ ttystudio --compile frames.json output.gif
: ttystudio will parse each set of
frames into a bitmap, keeping in mind the foreground color and character in
each cell.It's that simple. No bash script to run. No gifs to concatenate. No external dependencies required (i.e. ffmpeg or imagemagick) - ttystudio does it all on its own, in 99% javascript (aside from pty.js which is a node c++ binding to spawn terminals).
Compiling to APNG:
$ ttystudio frames.json output.png --log
Accidentally recorded something you don't want in your image? The range
option can help:
# compile only frames 5 to 130
$ ttystudio frames.json output.gif --log --range=5-130
The delay
option sets the delay between frames in the final image:
# 100ms between output frames
$ ttystudio frames.json output.png --log --delay=100
The --no-palette/--rgba
option can be used to avoid use a global palette
(color type 3) when compiling APNGs (this is known to cause high memory usage
when building the palette since it has to parse every frame beforehand).
Instead, it will use color type 6 (RGBA). This will make the APNG larger, but
does not risk OOMing the process. OOMing the process is unlikely to happen, but
if it does, this option is here. Use pngcrush
afterwards to optimize.
$ ttystudio frames.json output.png --log --rgba
Piping:
$ ttystudio frames.json - | feh -
Replaying frames in the terminal:
$ ttystudio --play frames.json
Adding a border:
# explanation of arguments:
$ ttystudio output.gif --log --border=[width],[r],[g],[b],[a]
# add a red border:
$ ttystudio output.gif --log --border=10,255,0,0,255
# white border:
$ ttystudio output.gif --log --border=10,255
$ ttystudio output.gif --log --border=10,255,255,255
$ ttystudio output.gif --log --border=10
Start in screenshot mode. This allows you to take multiple screenshot whenever
C-p
is pressed. ttystudio will write them all to separate images.
$ ttystudio o.gif --screenshot --screenshot-key C-p
-l, --log
-q, --quiet
-f, --font [font-file]
-b, --font-bold [font-file]
-d, --delay [delay-ms]
-i, --interval [interval-ms]
-k, --key [quit-key]
-n, --num-plays [num-plays]
-r, --range [frame-range]
-x, --ratio [pixel-cell-ratio]
-t, --term [term-name]
--palette
--no-palette, --rgba, --lct
--border [width,r,g,b,a]
play, --play
record, --record
compile, --compile
screenshot, --screenshot
C-p
unless specified otherwise by --screenshot-key
.--screenshot-key
C-p
.--version
-h, --help
Since ttystudio does not record a GUI, it needs to know which font you want to use (it has no real idea of the font your terminal is using). ttystudio uses terminus (ter-u14n/b) by default, but you can change this.
Your font must be in BDF format. Once you have your font ready,
place it in the fonts/
directory in ttystudio and run $ make
.
ttystudio+pxxl.js will convert the .bdf
font to a glyph bitmap format in a
json file, which is what ttystudio uses.
$ cp ~/ter-u12n.bdf ~/ttystudio/fonts/
$ cp ~/ter-u12b.bdf ~/ttystudio/fonts/
$ cd ~/ttystudio/fonts
$ make
...
$ ttystudio output.gif --log \
--font ~/ttystudio/fonts/ter-u12n.json \
--font-bold ~/ttystudio/fonts/ter-u12b.json
pty.js seems to currently be causing sporadic input lag on OSX. This is being investigated.
A special thanks to the folks who developed pxxl.js - a BDF font parser. Without them, it would not have been possible to render a reasonable looking font to the output gif/png.
If you contribute code to this project, you are implicitly allowing your code
to be distributed under the MIT license. You are also implicitly verifying that
all code is your original work. </legalese>
Copyright (c) 2015, Christopher Jeffrey. (MIT License)
See LICENSE for more info.