What's new in asciinema - part I: the player Published on 31 Aug 2023 by Marcin Kulik
There’s been a steady stream of asciinema releases over the last 12 months and I thought it would be nice to bring notable additions and improvements to the light. This is the first post in the “what’s new in asciinema” series, in which I’ll focus primarily on the player, highlighting changes I find most interesting. I will cover other parts of the asciinema stack in future posts.
First, a complete rewrite of the player resulted in 4x smaller, 50x faster version 3.0. This enabled a lot of possibilities and vastly improved integration of self-hosted player on websites.
Player v3.1 brought about improved terminal emulation, thanks to gradually evolving avt - asciinema virtual terminal. We also got rendering of faint graphic rendition - SGR 2, as well as the inclusion of Nord theme in the bundled CSS file.
Control bar display behaviour was improved in v3.2. The bar was moved below the
last terminal line. In previous versions it already automatically disappeared
when player detected lack of user interaction, however it still obscured the
last terminal line during such interaction. Later, in v3.4, new
controls option
was added which can be used to force control bar to be always visible (true
)
or always hidden (false
). You can see the “always-on” control bar in the
markers demo later in this post.
This same release introduced the concept of recording parsers, which allows playback of terminal sessions in formats other than player’s native asciicast format. Later, player v3.4 bundled parsers for ttyrec and typescript files (produced by script command). See my Blast from the past post for Star Wars asciimation parser example.
Also in v3.2 player got ability to step through a (paused) recording one frame
at a time by pressing .
(dot) key. This adds to a list of other useful key
bindings like space
(toggle play/pause), f
(toggle fullscreen), ]
(jump to
next marker, see below), and few
others. Feel free to test
these in the player below.
Then, with v3.3, the player became more friendly for Reveal.js slide embeds.
However, probably the highlight of the release is support for input
events
embedded in asciicast files when recording with input capture enabled
(asciinema rec --stdin demo.cast
).
For example, “the ’t’ key was pressed at 5 seconds” is saved in asciicast as the following event line:
[5.0, "i", "t"]
If you’re self-hosting the player you can subscribe to input events with
player.addEventListener
(doc). Say, you
want to play Cherry MX Brown (eeewww!) sound for each key press.
const player = AsciinemaPlayer.create({
url: '/typing.cast',
inputOffset: -0.125
}, document.getElementById('demo'));
player.addEventListener('input', e => {
playSound('/Cherry_MX_Brown.wav');
});
Below is the result (make sure your audio is not on mute):
It sounds mechanical and not very natural because I used a single sample, so
there’s no variation whatsoever. For more natural effect use multiple samples,
and have a special one for space key which often sounds different than the rest,
due to its size and the way it’s mounted. The event argument, passed to the
callback, has data
property, which corresponds to asciicast input event’s 3rd
field (“t” in the example earlier). This can be used to check which key was
pressed and what sample to play.
I used new inputOffset
option with a value of -0.125
(sec) to shift input
events in time. I did it because the key press sample I use has a bit of a slow
attack, so by firing the sound slightly earlier I got the audio in better sync
with the display.
Next, player v3.4 and markers. This feature was often requested, and one which was added to the whole stack (player, server, recorder). Let’s take a look at that next.
In the player below notice the dots on the timeline. Those are markers which, when hovered, show time and text labels. Markers mark chapters or other interesting points in the timeline of a recording.
As expected, clicking on a marker fast-forwards/rewinds the recording to
selected position. You can also navigate between markers by pressing the [
and ]
keys which respectively jump to previous and next marker. You can also
seek to a marker
programatically.
There are several ways to add markers to a recording. If you keep your recordings on asciinema.org or you self-host the server you can add markers on recording’s settings page. If you use the player on your own site you can pass markers via new markers option like this:
AsciinemaPlayer.create('/demo.cast', document.getElementById('demo'), {
markers: [
[5.0, "Installation"], // time in seconds + label
[25.0, "Configuration"],
[66.6, "Usage"],
[176.5, "Tips & Tricks"]
]
});
Finally, you can embed markers directly in asciicast files. Marker events look
similar to input events we saw earlier, but the event code is m
here:
[25.0, "m", "Configuration"]
Those can be added to a recording either during the recording session by
pressing a hotkey (see rec.add_marker_key
config
option) or after
recording by adding lines like the one above to the asciicast file.
There’s also new pauseOnMarkers option which tells the player to automatically pause the playback when reaching next marker. This is super useful for “live” demos as it lets you discuss terminal output at precise points.
This concludes player-related improvements. In the next post, we’ll take a look at what’s new in the recorder, aka CLI.
Until my next update, happy recording!