Скринкаст терминала в mp4 весит сотни мегабайт, текст в нём не выделить, нужную команду не найти поиском, а паузы между шагами приходится перематывать вручную. Asciinema записывает сам поток вывода с метками времени: файл получается на порядки легче, текст остаётся текстом, воспроизведение ускоряется и останавливается там, где нужно. Для документации, баз знаний и обучающих курсов это меняет всё: запись можно читать как текст, копировать из неё команды и хранить в репозитории рядом с кодом. Инструмент существует с 2011 года, распространяется по GPLv3, а текущее поколение утилиты переписано на Rust. Ниже формат записи, приёмы съёмки, воспроизведение, публикация и правила гигиены, без которых обучающий материал легко превращается в утечку.
Чем текстовая запись отличается от видеофайла по весу и удобству
Программа не снимает экран как видео, а запоминает события вывода: что появилось на экране и когда. Отсюда три следствия. Размер: запись рабочей сессии занимает десятки килобайт и после сжатия оставляет в среднем около восьми процентов исходного объёма, а не гигабайты, как у видеофайла. Поиск: файл открывается текстовым редактором или прогоняется grep-ом, и конкретная команда находится мгновенно. Копирование: зритель выделяет любую строку прямо в плеере и вставляет себе в терминал, вместо того чтобы перепечатывать с картинки.
Второй плюс проявляется в поддержке и обучении: записанную сессию воспроизводят в терминале командой play, и она ведёт себя как живой терминал, а не как неподвижный кадр. Читателю доступна скорость, переходы по шагам и остановка на нужном моменте, чего видео в вики не умеет вовсе.
Отсюда и любимые сценарии. Баг-репорт с приложенной записью избавляет от длинных описаний: разработчик воспроизводит проблему на своей машине с нужной скоростью и видит ровно то, что видел автор, а ссылка на запись спокойно живёт в описании задачи рядом с шагами воспроизведения. Онбординг новичка строится на серии коротких записей с текстовым разбором рядом, и вместо вечернего видеочаса человек проходит материал в своём темпе. Записи оседают и в базах рунбуков: перед обновлением узла инженер открывает запись прошлого обновления и сверяет порядок действий. Публичная демонстрация утилиты на конференции тоже проще: вместо съёмки экрана ведущий пишет сессию в файл и позже отдаёт зрителям лёгкую ссылку с плеером.
Текстовая природа записи дружит и с системами контроля версий: обновление документации вместе с новой записью попадает в обычный коммит, а разница между версиями читается глазами. Статичные скриншоты такую работу не заменяют: кадр не покажет движение курсора, порядок вывода и то, что происходило между двумя моментами.
Формат asciicast и устройство файла cast
Запись сохраняется в формате asciicast актуальной третьей версии, а записи первой и второй версии читаются и конвертируются без потерь. Устройство предельно простое: первая строка это JSON-заголовок с шириной и высотой терминала, меткой времени, окружением и темой, дальше идут строки событий со временем, типом и текстом:
{"version": 3, "width": 120, "height": 35, "timestamp": 1767225600, "env": {"SHELL": "/bin/bash"}}
[0.412, "o", "dev@server:~$ uname -a\r\n"]
[0.981, "o", "Linux server 6.8.0-45-generic #45-Ubuntu ...\r\n"]
Из такой структуры следуют практические возможности. Скрипт за пару строк отрезает хвост записи, склеивает две сессии или вырезает паузу, потому что каждая строка независима:
{ head -n 1 demo.cast; sed -n '2,120p' demo.cast; } > demo-cut.cast
Поиск по записи работает без специальных инструментов: grep находит нужную команду в файле как в обычном тексте:
grep 'systemctl' demo.cast | head -n 5
Инструменты конвертации идут в комплекте: превращение в другую версию asciicast, в сырой вывод терминала или в плоский текст без таймингов, а склейка нескольких записей пересчитывает время автоматически. Вторая версия формата по-прежнему широко используется, и плееры читают обе. Метаданные сессии, размер окна, команда запуска, заголовок, тема терминала и переменные окружения вроде оболочки, тоже хранятся в файле и попадают в плеер, поэтому воспроизведение выглядит как в оригинале, а не как случайная раскраска. При записи с ключом --stdin в файл добавляются события ввода, и тогда видны и нажатия клавиш. Формат из построчного JSON удобен и для контроля версий: обновление записи видно в diff построчно.
Запись сессии, маркеры и управление захватом на ходу
Базовый запуск выглядит так:
asciinema rec demo.cast
Завершение по exit или ctrl+d. Ключ -c (--command) записывает конкретную команду вместо оболочки, ключ --overwrite перезаписывает существующий файл. Запись без оболочки экономит время: черновое блуждание по каталогам не попадает в материал, и готовый файл короче. Подключение захвата нажатий клавиш включает --stdin: по умолчанию ввод не пишется, и это важная настройка для безопасности, о которой ниже. Текущее поколение утилиты добавило управление на лету: захват приостанавливается и возобновляется по горячим клавишам, а маркеры расставляются как закладки на ключевых шагах, и плеер умеет останавливаться на них при воспроизведении. Так запись превращается в главы: маркер перед каждым крупным шагом работает как оглавление, и зритель переходит сразу к нужной части. Полноэкранные приложения вроде htop или vim записываются корректно: управляющие последовательности сохраняются в событиях, и плеер восстанавливает картинку со всеми цветами и рамками. Привязки клавиш настраиваются в конфигурационном файле, там же задаются значения по умолчанию для команды записи и параметров захвата. Для автоматизации предусмотрен headless-режим с записью без терминала и передачей кода возврата: прогон тестов в CI записывается и прикладывается к задаче в доказательство, причём статус сборки от этого не ломается.
Воспроизведение с ускорением и живой стриминг по сети
Воспроизведение командой play даёт управление скоростью с произвольным множителем, лимит времени простоя, пошаговый режим и циклический повтор: паузы между действиями сжимаются ключом --idle-time-limit, и минутное раздумье превращается в две секунды. Для снятия записи лучше сразу выбрать разумную ширину окна терминала, тогда строки в плеере не уедут за край у читателя. Терминал подстраивается под размер окна зрителя, поэтому запись, снятая на широком экране, не разваливается на чужом ноутбуке. Для витрин и стендов на мероприятиях выручает циклический повтор: демонстрация играет сама, без докладчика у клавиатуры. Команда cat выгружает текст записи без таймингов, что удобно для быстрой выкопки вывода или склейки с журналом в отчёте.
Отдельная возможность текущей версии это стриминг. Команда stream -l поднимает встроенный HTTP-сервер с веб-плеером: коллеги в локальной сети открывают страницу и смотрят сессию по мере выполнения, а stream -r ретранслирует её через сервер asciinema для удалённых зрителей. Режимы комбинируются в одном запуске: утилита умеет одновременно писать файл, стримить локально и в сеть, так что демонстрация и сохранение материала не требуют двух сеансов. Для живых разборов кода это готовая замена демонстрации экрана: зрители смотрят текст без потерь, а запись остаётся на диске.
Публикация записей и встраивание плеера в документацию
Готовую запись удобно выложить на официальный хостинг asciinema командой upload: страница с плеером и кодом встраивания появляется сразу, доступ можно ограничить по ссылке. Для внутренних баз знаний поднимается собственный сервер проекта, и записи не покидают инфраструктуру компании, что важно для команд с требованиями к размещению материалов: сервер разворачивается рядом с корпоративной вики, а записи получают внутренние адреса. В документацию и README плеер вставляется готовым скриптом-встраиванием, а рядом с ним обычно лежит текстовый разбор команд: плеер показывает действия, текст объясняет логику, и вместе они работают лучше любого из них по отдельности. На страницах, где внешние скрипты запрещены политикой, выручает GIF из следующего раздела. Доступ к записи ограничивается ссылкой, поэтому внутренние материалы не должны попадать в общий поиск. В README репозитория короткая запись работает как вступление: новичок за минуту видит рабочий сценарий ещё до чтения текста. Поскольку запись остаётся файлом, её же кладут в репозиторий документации и обновляют вместе с остальным текстом, без пересъёмки всей серии при правке одного шага.
GIF через утилиту agg для площадок без поддержки плеера
Там, где нельзя подключить внешние скрипты или нужен просто анимированный файл, выручает agg, генератор GIF от авторов asciinema. Он читает asciicast любой версии, в том числе с локального диска, из потока или по ссылке, и собирает GIF через кодировщик gifski с точными таймингами:
agg --theme dracula --speed 1.5 --font-size 14 demo.cast demo.gif
Темы dracula, monokai, nord, solarized-dark, gruvbox-dark и другие задают оформление, размер шрифта и межстрочный интервал настраиваются, скорость и ограничение кадров в секунду тоже, а запись сама подхватывает встроенную тему, если та указана в метаданных. Фрагмент вырезается по временным границам, маркерам или процентам длительности, поэтому GIF собирается сразу в финальном виде, без внешнего видеоредактора: отрезок между двумя маркерами становится готовой сценой. Зацикливание и длительность последнего кадра настраиваются отдельно, что пригождается для коротких демонстраций в README. Подписи поверх кадров agg не добавляет, поэтому текстовый разбор рядом с картинкой остаётся главным источником объяснений. Сама утилита ставится одной командой из экосистемы Rust, а собранный GIF весит куда меньше видеозаписи того же фрагмента. В автоматизированных документациях GIF собирают на этапе сборки прямо из тестовых записей CI, и иллюстрации обновляются вместе с кодом.
Гигиена записи и порядок выпуска обучающего материала
По умолчанию записывается только вывод, а не ввод: пароли, которые оболочка и sudo не печатают, в файл не попадут. Всё меняется с ключом --stdin: тогда пишется каждое нажатие, и включать его стоит осознанно. Опасность чаще прячется в выводе: экспорт переменных с токенами, файлы окружения, листинги конфигов с секретами, вывод истории команд. Классические промахи хорошо известны: печать файла учётных записей для облака, показ приватного ключа по невнимательности, случайный вывод журнала с адресами клиентов. Отдельная предосторожность для чувствительных систем: отдельный пользователь без доступа к продакшену, от имени которого идёт запись. Перед записью стоит почистить приглашение и историю, а во время записи на помощь приходят пауза захвата и маркеры, позволяющие вырезать черновую возню. После записи файл остаётся обычным текстом: его проверяют поиском по признакам токенов, и лишь затем публикуют, потому что выложенное в общий доступ отзывается плохо. Финальная проверка деловая: открыть запись в плеере на другой машине и посмотреть чужими глазами, что увидит читатель.
Чтобы обучающая запись вышла чистой с первого дубля, помогает такой порядок:
- Подготовить демо-среду и приглашение без секретов, спрятав ключи в переменные, которые не печатаются на экран;
- Записать сессию с маркерами на ключевых шагах и паузой захвата для черновых манипуляций;
- Задать лимит простоя при воспроизведении, чтобы длинные раздумья не усыпляли зрителя;
- Просмотреть файл как текст, прогнать поиск по признакам токенов и удалить случайные чувствительные строки;
- Выложить запись на хостинг или собрать GIF и встроить плеер в документацию рядом с текстовым разбором команд.
На выходе получается материал, который живёт дольше видеоролика: его ищут поиском, копируют из него команды, обновляют одной новой записью и без сожалений удаляют, когда шаги устарели. Для команды, где документация пишется руками, это самый дешёвый способ показать, как всё устроено, не снимая ни одного гигабайта видео. Достаточно одной привычки: любая отладка, которую жалко забыть, идёт под запись, и база знаний растёт сама собой, шаг за шагом.