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.
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!
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:
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.
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
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).
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
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)
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)