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!


Did you like it? Feel free to send me an email with your feedback to . You can also reach me on Mastodon at @ku1ik@hachyderm.io. Thanks!