Is it possible to "script" asciinema?

So something I’ve always wanted is the ability to “script” a video, so that all i have to do is edit the script file then regenerate the video.

I think I could hack this together by using shell-mode in emacs and then writing elisp to send commands to it. But, has anyone else done something like this?

An example, I have a project GitHub - joelmccracken/reddup: Helping you keep your workstation nice and tidy , and i get a lot of people who don’t quite “get” why the project would be useful. So I thought having a screencast would be a great way to “demo”. Basically, if I could script it, what I would do is something like:

cd to some directory
run a bunch of git and touch commands to set up a repo in a certain way.
start asciinema
run my project (and script the way it should interact)
stop asciinema.

I hope that is clear. The big value would be in having a repeatable “setup” and it would be a lot easier to add and remove demo features.

Thanks!

5 Likes

Well yes, pretty easy. Maybe even easier than you think!

The --command= option allows to specify the program you run, it’s $SHELL by default. Just set it to whatever program you can script in which will literally output the “movie” to its stdout! Then you get the scriptability from the program (oh I guess it’ll be rich in sleep() calls), as well as the preserved recording from asciinema. That’s Unix-style program composition!

Too bad you can’t really edit the recordings… Or can you? However there’s also asciinema rec --stdin mode, which’ll record your manual timed input into the replayable file.

I hope, some combination of these would become useful!

3 Likes

Thank you! and sorry for the belated reply. I think I’m going to start working on this soon. WOuld you be interested in hearing what I come up with?

2 Likes

not sure if it is still a topic but I created a small golang based tool which allows to script the sequence by defining a couple of parameters such as character typing speed:

1 Like

there is an opensource tool called asciinema-edit. Take a look at it to see if its what you want.

Check this out: Automating terminal demos

1 Like

In case it could be useful, I have made a small python package to automate recordings. It uses pexpect, so it is similar to what is used in the blog post @ku1ik pointed out in his answer in some sense.

1 Like

Check out:

This is done by building a version of the original script that surfaces all the comments and commands by also echoing them to the screen.

Then passing that augmented script to asciinema’s rec --command command.

BTW if someone wants to help me package this up into its own container in GitHub’s Container Registry and create a GitHub Action from it to regenerate screencasts from a set of shell scripts in a screencasts directory.
ie. after every merge to main in any repo using it in a github action

I’m sure it would be super popular. :wink:

(I tried but couldn’t get it working.)

1 Like

Getting back to @joelmccracken 's original question…
Here’s how you’d use asciinema-rec_script to turn a simple bash script into a useful screencast…

Nb. I didn’t attempt making a screen recording of creating a screen recording - hence the screenshot.

But here’s a link to the resulting screencast:

For anyone looking into this in the future: check out the list of integrations: Integrations - asciinema docs

Some of them help with scripting and/or generating recordings automatically.

1 Like

You might like what I just released: Docker container for producing GIF files of shell sessions

1 Like

In the topic of scripting the recording, I’m thinking of implementing an RPC mechanism for asciinema rec, which would allow controlling the recording session (including the input) programmatically. It could be controlled for example via a UNIX socket or via STDIN (when recording in headless mode).

Does that sound useful?

I guess I forgot to reply to all of your helpful suggestions, my apologies. I haven’t revisited this sub-task since I posted. I’m not sure which/any of these will work for me, but they all sound interesting. I’m probably going to want to try it for a project that i’m working on now (tho not the one I posted on ages back)

the ideal solution to me would be a sort of text based “script” that drives interaction, it would just take stdin/stdout from a process, and then generate a “fake” terminal session with it. And then, most ideally, it could be updated automatically via CI.

I think this would likely be achievable with something like expect, tho its painful, but some kind of automatic solution for like user-like typing speeds, some pausing between command results and next command, etc.

Sending commands via RPC would be perfect as an implementation mechanism, I think.

In dorothy we automate inputs in our tests like so:

	{
		sleep "$delay"
		__print_string "$down" # down to second preference
		sleep "$delay"
		__print_string "$enter" # select second preference
		sleep "$delay"
		__print_string "$escape" # cancel the confirmation of second preference
		sleep "$delay"
		__print_string "$enter" # change mind, do select second preference
		sleep "$delay"
		__print_string "$enter" # confirm second preference
	} | eval-tester --name='select second preference then cancel that, select second preference then confirm that' --stdout='c' \
		-- choose 'q' 'd' --confirm --required --default=b --default=c --default=d -- a b c d

I’m considering redoing our echo-style command to support input characters, such that that would become:


	export ECHO_STYLE__DEFAULT_SLEEP="$delay"
	echo-style --sleep+down --sleep+enter --sleep+escape --sleep+enter --sleep+enter | \
	eval-tester --name='select second preference then cancel that, select second preference then confirm that' --stdout='c' \
		-- choose 'q' 'd' --confirm --required --default=b --default=c --default=d -- a b c d

For sending inputs to asciinema, this could become:

echo-style --sleep+down --sleep+enter --sleep+escape --sleep+enter --sleep+enter | \
asciinema rec --stdin

# or even something like this
export ECHO_STYLE__PRINT_DELAY="$delay"
echo-style --down --enter --escape --enter --enter | \
asciinema rec --stdin 

Let me know if that would be of interest.

However, I think that my suggestion of a asciinema replay <cast> would be a suitable alternative to this need though.

1 Like

ooo, TIL about dorothy. It seems quite in spirit with the thing i’ve been working on for a while. Looks cool, I’ll probably use it with the thing I’m working on.

(Oh and thank you for that, it will be easier to adapt working code for sure)

Edit: I’ve been considering working on a way to write a kind of expect in bash, which would have to end up using coproc. Which seems quite similar.

(a while back I tried learning TCL for expect usage and struggled to make sense of things, so I don’t want to use that directly)

1 Like

Hi @joelmccracken I have just announced “asciinwriter” (Yet another tool to generate input - #3 by russoz) that serves exactly that purpose. I wanted to script the term demo of my project.

It consumes an input like:

  SEND(git clone --quiet --depth 1 https://github.com/ansible-collections/community.general.git)
 ENTER()
EXPECT($ )

  SEND(cd community.general)
 ENTER()
EXPECT($ )
  SEND(ls)
 ENTER()
EXPECT($ )

  SEND(andebox test -R -- integration --docker default --python 3.13 pipx_info)
 ENTER()
EXPECT($ )

In fact, since you mentioned expect, this one is based on expect (or more precisely pexpect, the Python implementation of if).

Stackoverflow also has a list of tools BTW.

I once also stumbled upon Autocast – fix this and all folowing link when I have enough permissions-- and it also has a YAML playbook which you can run to automate it away.

Another alternative approach being [used here is asciinema for recording] (hxxps://github.com/borgbackup/borg/pull/6197) is [TCL/TCL Expect] (hxxps://core.tcl-lang.org/expect/index) and (optionally, I guess isolating this via docker or Vagrant.

[Reference to where I proposed this.] (hxxps://github.com/borgbackup/borg/issues/8040)