Tool for splicing asciinema clips together?

Hi Asciinema community —

I’m curious whether anyone has a tool or script that can splice asciinema clips together? I understand that I can use the rec --append option to extend an existing clip with a new recording. But for the movie I’m trying to make, such a tool would make it easier to create a number of short clips and then to splice them together in arbitrary orders, or to later replace an intermediate clip without having to re-record all the clips that follow it.

Thanks for any pointers,

For anyone curious about this question, I believe my team has now developed such a script. I’ll post once I get more experience with it and permission from the author to do so.


Well, please. We are al ears now that you spoke about it

Couldnt it be asimple as using the append with a play?

something like…

asciinema rec --append $(asciinema play something.cast)

1 Like

That’s interesting and clever, and perhaps it would work for me… I’d hoped to give a list of clips to a script and have it splice them all together, but one could probably create such a script using that pattern.

I got distracted from this effort temporarily, so haven’t had the chance to test the draft script as much as I’d like yet to have full confidence in it, but to avoid keeping you in suspense now that I know someone saw the original post, here’s the rough draft:

#!/usr/bin/env python                                                           

# Script for splicing asciinema clips together, removing final exits            
# from each.                                                                    
# Authored by Engin Kayraklioglu, October 2019                                  

import sys
import re

first_line = False
cur_time_off = 0.

in_format = re.compile('\[(\d+\.\d+), "(.*)", "(.*)"\]')
end_markers = ('\\u001b[0;94m$ \\u001b[1;35m',
               '\\u001b[0;94m> \\u001b[1;35m')
out_format = '[{}, "{}", "{}"]\n'.format

def get_triple_from_line(l):
    match = in_format.match(l)
    if match:
        return match.groups(0)
        print('Unmatched line ', l)

out_file_name = sys.argv[-1]
in_file_names = sys.argv[1:-1]

with open(out_file_name, 'w') as out_file:
    for in_file_name in in_file_names:
        last_script = in_file_name == in_file_names[-1]
        with open(in_file_name) as in_file:
            found_end_marker = False
            for l in in_file:
                if not first_line:
                    first_line = True
                elif l[0] == '{':

                f1, f2, f3 = get_triple_from_line(l)
                if not last_script:
                    if f3 in end_markers:
                    if found_end_marker and f3 != 'exit\\r\\n':
                    if f3 in end_markers:
                        found_end_marker = True

                read_time = float(f1)
                out_file.write(out_format(read_time+cur_time_off, f2, f3))

            cur_time_off = read_time

It’s a start.

The exit(s) are kept from all files it seems. Do you happen to have another version?

My intermediate exits get removed. I think the difference is due to differences in our prompts. I believe this line indicates the prompts that it’s looking for:

end_markers = ('\\u001b[0;94m$ \\u001b[1;35m',
               '\\u001b[0;94m> \\u001b[1;35m')

so you probably would need to update it to reflect your prompt format (?).

If anyone is still looking for a way to combine multiple casts together then the upcoming asciinema 3.0 has built-in support for that:

asciinema cat clip1.cast clip2.cast clip3.cast >final.cast

3.0 is not released yet but there’s release candidate build you can get from here if you want to play with it:

1 Like