Recording Your Terminal to SVG
Tags: beginners, shell, opensource
Published: 2020-03-27 10:40:29


## Problem

This use case describes how we recorded the pos-cli introduction and saved it as an SVG to embed it on our marketing website.

There are a couple of ways for recording your screen to share it on the Internet.

1. Animated GIF - Pretty easy to do with tools like [Kap](https://getkap.co/), but it has heavy drawbacks. Maximum of 256 colors, balance between FPS and file size is very delicate, and gif files are usually big.
2. Video (mp4, webm) - Pretty easy with tools like [Kap](https://getkap.co/), but needs usage of the video tag, which is not always a possibility (markdown readme being a big one).
3. Animated PNG - We have never seen anyone use it, even though the browser support is there. This is a good candidate to experiment.
4. Finally, SVG — All of the above solutions can record everything, the whole screen with images, so they are more universal. What we need is to record only terminal, which is predominantly text. This means, recordings will be much smaller than the closest alternative - gif, and easier to embed in more places than videos.

So, which solution did we choose for showing the recording of our CLI as an image on our website? 

## Solution 

If you only need to share your terminal recording with someone, without embedding it on a website, we recommend the excellent [asciinema](https://asciinema.org/).

But if you want to show off your recording as an image on your website, then you need an image format that is natively understood by browsers.

### Enter: [termtosvg](https://github.com/nbedos/termtosvg)

Instead of talking about what it does, let's [look at some examples](https://nbedos.github.io/termtosvg/pages/examples.html).

Apart from recording what you see in your terminal, you can also [change the theme](https://nbedos.github.io/termtosvg/pages/templates.html), just in case your terminal is heavily customized and you want a simpler look and feel.

**Installation**

It is a Python 3 script, so you will need to have Python in your system.

```shell
pip3 install termtosvg
```

**Usage**

When you use termtosvg, it starts recording immediately.

```shell
pos-cli|master ⇒ termtosvg helloworld.svg
Recording started, enter "exit" command or Control-D to end
```

It is time do what you want to record.

```shell
pos-cli|master ⇒ echo "Hello world"
Hello world
```

When you are ready to end and save your recording, press Control-D.

```shell
pos-cli|master ⇒
Rendering ended, SVG animation is hello.svg
```

You can even nest recordings, so I recorded all those commands above into an SVG file:

<a href="https://uploads.prod01.oregon.platform-os.com/instances/1/assets/images/use-cases/recording-terminal/hello.svg" target="_blank">
<img src="https://uploads.prod01.oregon.platform-os.com/instances/1/assets/images/use-cases/recording-terminal/hello.svg" alt="Hello world animation">
</a>
(Click to preview)

### More options

If you need to do more complicated things, type `termtosvg -h` which will give you information about the options it provides.

```shell
pos-cli|master ⇒ termtosvg -h
usage: termtosvg [output_path] [-c COMMAND] [-D DELAY] [-g GEOMETRY]
                 [-m MIN_DURATION] [-M MAX_DURATION] [-s] [-t TEMPLATE] [-h]

Record a terminal session and render an SVG animation on the fly

positional arguments:
  output_path           optional filename of the SVG animation. If --still-
                        frame is specified, output_path should be the path of
                        the directory where still frames will be stored. If
                        missing, a random path will be automatically
                        generated.

optional arguments:
  -h, --help            show this help message and exit
  -c COMMAND, --command COMMAND
                        specify the program to record with optional arguments
                        (default: /bin/zsh)
  -D DELAY, --loop-delay DELAY
                        duration in milliseconds of the pause between two
                        consecutive loops of the animation (default: 1000ms)
  -g GEOMETRY, --screen-geometry GEOMETRY
                        geometry of the terminal screen used for rendering the
                        animation. The geometry must be given as the number of
                        columns and the number of rows on the screen separated
                        by the character "x". For example "82x19" for an 82
                        columns by 19 rows screen.
  -m MIN_DURATION, --min-frame-duration MIN_DURATION
                        minimum duration of a frame in milliseconds (default:
                        1ms)
  -M MAX_DURATION, --max-frame-duration MAX_DURATION
                        maximum duration of a frame in milliseconds (default:
                        No maximum value)
  -s, --still-frames    output still frames instead of an animation.
  -t TEMPLATE, --template TEMPLATE
                        set the SVG template used for rendering the SVG
                        animation. TEMPLATE may either be one of the default
                        templates (base16_default_dark, dracula, gjm8_play,
                        gjm8_single_loop, gjm8, powershell, progress_bar,
                        putty, solarized_dark, solarized_light, terminal_app,
                        ubuntu, window_frame_js, window_frame_powershell,
                        window_frame, xterm) or a path to a valid template.

See also 'termtosvg record --help' and 'termtosvg render --help'
```

### Results

Having the SVG ready, you can embed it anywhere you want, using your favorite image syntax.

<a href="https://uploads.prod01.oregon.platform-os.com/instances/1/assets/images/use-cases/recording-terminal/pos-cli.svg?updated=1585304029" target="_blank">
<img src="https://uploads.prod01.oregon.platform-os.com/instances/1/assets/images/use-cases/recording-terminal/pos-cli.svg?updated=1585304029" alt="pos-cli animation">
</a>

(Click to open in new tab)

This post was inspired by this [dev.to post](https://dev.to/brpaz/make-your-project-readme-file-stand-out-with-animated-gifs-svgs-4kpe) by Bruno Paz, where he showed how to use asciinema and a converter to achieve a similar result. You might also use that approach in your development workflow: Record and share an asciinema recording to get feedback from your team, and when it is good enough, convert it to SVG and ship.