Скринкасты терминала. Запись действий в консоли Linux

Kate

Administrator
Команда форума
Скринкаст консольной сессии в маленьком анимированном gif — самый простой и быстрый способ продемонстрировать свои действия в консоли. Такую анимацию легко запостить в чате или опубликовать на веб-страничке, она весит совсем мало. Но это неоптимальный вариант.

Существуют специализированные инструменты именно для консольных скринкастов. Для этого они задействуют встроенный псевдотерминал Linux, то есть PTY. Самые продвинутые добавляют спецэффекты типа подсветки нажатий клавиш и, самое главное, позволяют выделить мышкой и скопировать текст прямо из «видео».

Записываем видео/анимацию​


Итак, начнём с классики. Когда хочется показать свои действия другому человеку, первая мысль — записать экран в видео mp4 / webm или анимацию gif. Казалось бы, логичный вариант.

Можно использовать ffmpeg, который пишет видео и автоматически конвертирует его в mp4 или webm. Например, так:

ffmpeg -f x11grab -r 25 -s 800x600 -i :0.0 ~/vid_tst1.mp4

Полученное видео тоже можно сконвертировать в GIF тем же ffmpeg.

Теоретически gif-анимацию можно сгенерировать вручную bash-скриптом. Команда magick import -window сохраняет скриншоты, а convert склеивает из них анимацию:

convert -delay 20 -loop 0 *.jpg scr_cst1.gif

Но этот конвейер добавляет лаги во время записи. А однажды ImageMagick вообще закрашился на этапе конвертации. Наверное, картинки не влезли в память. В этот момент стало понятно, что нужен какой-то специализированный инструмент, более заточенный под нашу задачу.

В принципе, подойдёт любая программа для захвата видео с экрана, типа навороченной OBS Studio или более простой SimpleScreenRecorder (SSR). Любопытно, что популярный медиаплеер VLC тоже умеет записывать видео с экрана.

7yr8qfgm1x2lqyssxpvmdj6vgt0.png

SimpleScreenRecorder используют для записи не только видео, но и разговоров в мессенджерах. Например, запись рабочей планёрки можно прослушать позже в удобное для себя время и на удобной скорости

Минималистичный вариант для маленьких скринкастов — Peek.

v-ffm-6bu0jd1on-ugk3wbzpm-g.gif

Peek

Можно вспомнить ещё Gifine. Да, такой софт отлично справляется с записью красивых скринкастов под Linux. Но это не самый оптимальный вариант именно для консоли, потому что такие программы не оптимизированы для записи конкретно текста. Они записывают полноценное видео. Файлы получаются большими по размеру, а процесс записи/конвертирования иногда нагружает CPU не меньше, чем наш допотопный скрипт с ImageMagick.

Так что для консоли лучше взять специальный инструмент.

Запись псевдотерминала​


Пользователи Linux наверняка знакомы с командами screen, script и ttyrec. Они обе используют одну и ту же функцию Unix: псевдотерминал (PTY) для записи и последующего воспроизведения сессий.

Псевдотерминал — это пара псевдоустройств (slave и master). Первое эмулирует консоль, а второе предоставляет средства управления. Псевдотерминалы дают программам возможность действовать в качестве посредника между пользователем, дисплеем и оболочкой. Это позволяет прозрачно перехватывать ввод пользователя (клавиатура) и вывод в терминал (дисплей). Команда screen использует её для перехвата специальных комбинаций клавиш, таких как Ctrl-A, и изменения вывода для отображения оконных id и других сообщений.

cpufqqtpfoml7mdruwzfxxjo4wq.png

Использование псевдотерминала командой script

Поэтому для записи консольных сессий под Linux было бы логично использовать PTY как нативную функцию этой операционной системы, что и делают программы такого типа. Среди них устаревшая ttyrec и ряд инструментов на её основе — это Ttyrec2gif, Seq2gif, Recterm и другие. Но их вряд ли стоит использовать на современных системах по причине некоторых ограничений легаси. Например, поддержка терминалов только 80×24.

Рекордеры консоли нового поколения используют более современный стек: например, Ttystudio, ShowTerm, TermRecord, Terminal-Recorder и Asciinema.

Asciinema​


Asciinema сохраняет вывод PTY в памяти вместе с метками времени, включая весь текст и невидимые escape/control последовательности в исходном виде. По окончании записи сохраняется файл в формате asciicast. Он же по умолчанию публикуется в открытом доступе на сайте asciinema.org. Там скринкасты доступны по стандартному URL типа asciinema.org/a/20055. Конечно, дефолтные настройки можно изменить.

Для просмотра используется интегрированный плеер asciinema-player. Во время просмотра такой скринкаст можно поставить на паузу, скопипастить текст, а затем запустить дальше.

Установка и использование Asciinema максимально просты. Установка:

brew install asciinema

Если планируете отправлять скринкасты на сервер, нужно пройти аутентификацию:

asciinema auth
Open the following URL in a browser to register your API token and assign any recorded asciicasts to your profile:

Старт записи:

asciinema rec --stdin

После этого записываются все наши действия в консоли, а также дополнительно все нажатия клавиш на клавиатуре (опция --stdin). По окончании записи набираем exit или жмём Ctrl-D.

По умолчанию скринкаст заливается на сервер, прописанный в настройках (например, asciinema.org). Чтобы этого избежать, нужно запускать запись с указанием файла:

asciinema rec [filename]

Впоследствии запись можно залить на сервер вручную:

asciinema upload asciicast.json

Недостаток собственного формата в том, что его не выложишь в открытый доступ, как гифку, а для просмотра требуется отдельный плеер.

Но зато плеер очень маленький, так что asciinema player легко интегрировать в любое приложение как модуль из пакета npm. Ну или интегрировать на сайт, как это сделано на бесплатном хостинге скринкастов asciinema.org.

Просто берём плеер asciinema-player.min.js и загружаем в него записанный скринкаст. В нашем случае это 20055.json:

<head>
<link rel="stylesheet" type="text/css" href="asciinema-player.css" />
</head>
<body>
<div id="player"></div>
<script src="asciinema-player.min.js"></script>
<script>
AsciinemaPlayer.create(
'20055.json',
document.getElementById('player'),
{ cols: 80, rows: 24 }
);
</script>

С точки зрения посетителя, интегрированный плеер выглядит так:

n8jhmz-jprtdefusgfeepiabobw.gif


Вот этот конкретный 38,907319-секундный скринкаст 20055.json с псевдографикой Python весит 2,091 МБ. Для сравнения, гифка с его записью получилась на 2,665 МБ.

Но текстовый JSON при желании можно сжать ещё в несколько раз без потери информации, а гифку — уже нельзя (по сути, вся текстовая информация из терминала была утеряна при переводе в графический формат).

И самое главное, что из скринкаста легко скопировать любой текст, в том числе вводимые команды и результат их выполнения. Скажем, вот скринкаст 139514.json с брутфорсом газетной головоломки про рельсы. Останавливаем его на 00:11 — и просто копируем консоль в текстовом виде:

Puzzle: 54-14343245-14134544-48EW.53NE
1 4 1 3 4 5 4 4 1 4 1 3 4 5 4 4
┌─┬─┬─┬─┬─┬─┬─┬─┐ ┌─┬─┬─┬─┬─┬─┬─┬─┐
8 │ │ │ │━│ │ │ │ │ 5 8 │ │┏│━│━│┓│ │ │ │ 5
├─┼─┼─┼─┼─┼─┼─┼─┤ ├─┼─┼─┼─┼─┼─┼─┼─┤
7 │ │ │ │ │ │ │ │ │ 4 7 │ │┃│ │ │┗│━│┓│ │ 4
├─┼─┼─┼─┼─┼─┼─┼─┤ ├─┼─┼─┼─┼─┼─┼─┼─┤
6 │ │ │ │ │ │ │ │ │ 2 6 │ │┃│ │ │ │ │┃│ │ 2
├─┼─┼─┼─┼─┼─┼─┼─┤ ├─┼─┼─┼─┼─┼─┼─┼─┤
A │━│ │ │ │ │ │ │ │ 3 A │━│┛│ │ │ │ │┃│ │ 3
├─┼─┼─┼─┼─┼─┼─┼─┤ ├─┼─┼─┼─┼─┼─┼─┼─┤
4 │ │ │ │ │ │ │ │ │ 4 4 │ │ │ │ │┏│━│┛│ │ 4
├─┼─┼─┼─┼─┼─┼─┼─┤ ├─┼─┼─┼─┼─┼─┼─┼─┤
3 │ │ │ │ │┗│ │ │ │ 3 3 │ │ │ │ │┗│ │ │ │ 3
├─┼─┼─┼─┼─┼─┼─┼─┤ ├─┼─┼─┼─┼─┼─┼─┼─┤
2 │ │ │ │ │ │ │ │ │ 4 2 │ │ │ │ │ │ │ │ │ 4
├─┼─┼─┼─┼─┼─┼─┼─┤ ├─┼─┼─┼─┼─┼─┼─┼─┤
1 │ │ │ │┃│ │ │ │ │ 1 1 │ │ │ │┃│ │ │ │ │ 1
└─┴─┴─┴─┴─┴─┴─┴─┘ └─┴─┴─┴─┴─┴─┴─┴─┘
1 2 3 B 5 6 7 8 1 2 3 B 5 6 7 8

Такого не может сделать ни одна программа для видеозаписи экрана.

Asciinema работает в Linux, macOS и *BSD.

Ускорение в 50 раз​


Разработкой программы с 2012 года занимается польский разработчик Мартин Кулик. Недавно он неожиданно переписал программу с нуля на JavaScript и Rust (компилируется в WASM), отказавшись от любимого ClojureScript. В результате размер бандла JS уменьшился вчетверо с 570 до 140 КБ, а интерпретатор виртуальной консоли стал работать в 50 раз (!) быстрее.

Сам Мартин приводит такие цифры (в Chrome 88): в старом плеере эмулятор терминала обрабатывал 0,3–0,8 мегабайта текста в секунду, а в новой версии обрабатывает 24–37 МБ, то есть налицо ускорение в 45–73 раза.

Речь идёт о парсинге текстового потока в виртуальной консоли, включая управляющие команды, а также управление виртуальным экранным буфером, который был узким местом в пропускной способности предыдущей версии плеера. Интерпретатор преобразует этот поток в графику на экране.

Дополнительное ускорение интерфейса получено за счёт перехода с React.js на SolidJS, одну из самых быстрых библиотек UI на сегодняшний день.

Если подвести итог, то по набору функций у Asciinema практически нет конкурентов среди всех программ для записи скринкастов из консоли. Это вообще уникальный инструмент, который позволяет сохранять скринкасты практически в текстовом виде, то есть в минимальном размере. Для воспроизведения используется собственный плеер с интерпретатором виртуального терминала, написанный на Rust.

Скринкасты под Windows​


Хотя мы рассматриваем в основном скринкасты под Linux, но у разработчиков под Windows тоже есть удобные инструменты для записи скринкастов gif. Таких программ немало. Можно вспомнить великолепную программу ShareX, а также GifCam, Gif Screen Recorder, ScreenToGif, LICEcap, InstaGiffer и другие.

5tsvj46j5ofhhuo7fwnzz7pmuzi.png


Но чтобы программа создавалась конкретно для записи текстовой консоли — такого под Windows, кажется, ещё не делали. Впрочем, в последних версиях Win11 уже можно пробовать запускать полноценное окружение Linux и все привычные инструменты, включая ту же Asciinema.

Если совсем не хочется ничего устанавливать, то можно записать маленький скринкаст прямо из браузера, в онлайн-редакторах вроде FlexClip или Online Screen Recorder.

kcdln_bggstl9yoqri7bufkiohk.png

FlexClip

Только нужен нормальный браузер с поддержкой некоторых стандартов HTML5.

 
Сверху