LIBTTYREC(3)
πΈ NAME πΈ
libttyrec β a whole entire library for handling ttyrec files π no cap
β¨ SYNOPSIS β¨
#include <ttyrec.h>
Link with -ltty. that's it. that's the whole vibe check π«Ά
π DESCRIPTION π
okay so bestie, this is the libttyrec(3) page from the termrec manual, and it's lowkey a whole tour of everything you can do with ttyrec files. grab a snack, we're going section by section π
π¦ Helper stream function π¦
int open_stream(int fd, const char* url, int mode, const char **error);β this one opens a stream for theurlyou hand it. and here's the cute part: if thaturlends in.gz,.xz,.bz2or.zst, the stream is assumed to be compressed and gets passed through the appropriate[un]packer. iconic. now, iffdis not-1, that's the descriptor you already opened; if it is-1, the file gets opened for you. and themodecan be:SM_READSM_WRITESM_REPREADSM_APPEND
on error, -1 comes back. if you want the actual message, pass a non-null pointer as error and it'll be filled in for you π
π₯ Format encoders π₯
const char* ttyrec_w_find_format(const char *format, const char *filename, const char *fallback);β this function searches for a format that would fit thefilenameyou gave it β like,abc.ttyrec.gzreturns"ttyrec". if no known extension turns up, it just returns whatever you gave asfallback. and if you wanna force a format yourself? go off β but then it's only validated, and if it's invalid,0is returned regardless of the other two arguments. periodt.recorder ttyrec_w_open(int fd, const char *format, const char *filename, const struct timeval *ts);β arecordergets opened, writing to the filefd. iffdisn't given (=-1), the function callsopen_stream(). recording happens in the givenformat, and if you didn't provide one, it's guessed from thefilename. if you pass a timestampts, that becomes the date of the recording π°οΈint ttyrec_w_write(recorder r, const struct timeval *tm, const char *data, int len);β a chunk of data of lengthlengets written to recorderr, with timestamptm. returns1if some sort of write error happened. (so1= bad news bestie π)int ttyrec_w_close(recorder r);β all pending data is flushed, the recorder is closed and its memory is freed. returns1if there's some kind of failure.const char* ttyrec_w_get_format_name(int i);β use this to enumerate known write formats by calling it withibeing subsequent numbers starting at0. an invalidireturns a null pointer.const char* ttyrec_w_get_format_ext(const char *format);β if the given write format is associated with a file extension, that extension is returned.
π§ Format decoders π§
const char* ttyrec_r_find_format(const char *format, const char *filename, const char *fallback);β literally see the_w_function, except that read formats are searched instead.const char* ttyrec_r_get_format_name(int i);β ditto.const char* ttyrec_r_get_format_ext(const char *format);β ditto.int ttyrec_r_play(int fd, const char *format, const char *filename, void (*synch_init_wait)(const struct timeval *ts, void *arg), void (*synch_wait)(const struct timeval *delay, void *arg), void (*synch_print)(const char *data, int len, void *arg), void *arg);β this one decodes the filefd(openingfilenameiffd=-1). if its contents contain the date of the recording, you'll receive it through the callbacksynch_init_wait. between frames, the delay is passed throughsynch_wait. and the actual frame data goes throughsynch_print. heads up tho: in some formats, two or more consecutive delays, or two consecutive frames, can happen one after another. if you provide an arbitraryarg, it gets passed to all the callbacks.
the function doesn't return until the end of input data. returns 1 on success, 0 on failure.
π The following functions deal with in-memory ttyrecs π
ttyrec ttyrec_init(tty vt);β an empty one is allocated. if avtis provided, it becomes the screen that the ttyrec is internally played on; otherwise, a blank80x25one is allocated. also β thevtis consumed. gone. absorbed. main character behavior fr.ttyrec ttyrec_load(int fd, const char *format, const char *filename, tty vt);β this loads a ttyrec from the file designated withfd. if it's not open yet (fd=-1), it gets opened withopen_stream. the ttyrec is played on thevtyou provide β or on a new80x25one.void ttyrec_free(ttyrec tr);β destroys the in-memory ttyrec, freeing its memory. bye babe π«Ά
you can read the ttyrec's data while it's being read β and yes, all functions are thread-safe with regard to reading. slay. the frames are stored in structures like this:
typedef struct {
struct timeval t;
int len;
char *data; } *ttyrec_frame;
ttyrec_frame ttyrec_seek(ttyrec tr, const struct timeval *t, tty *vt);β finds the frame that should be shown at time*t, or the first frame iftis null. ifvtis not-null, it will receive a terminal containing the screen at that frame.ttyrec_frame ttyrec_next_frame(ttyrec tr, ttyrec_frame tfv);β returns the next frame after frametfv, or null iftfvwas the last.void ttyrec_add_frame(ttyrec tr, const struct timeval *delay, const char *data, int len);β creates a new frame and appends it to ttyrectr.int ttyrec_save(ttyrec tr, int fd, const char *format, const char *filename, const struct timeval *selstart, const struct timeval *selend);β exports the ttyrec to a new file. ifselstartand/orselendare given, they designate the part that should be exported β and if not, the whole thing is. no cuts, full director's cut π
π struct timeval arithmetics π
a handful of macros for operating on timeval values:
tadd(t, d)βt+=d;tsub(t, d)βt-=d;tmul1000(t, m)βt*=m/1000;tdiv1000(t, m)βt/=m/1000;tcmp(t1, t2)β ift1<t2,-1. ift1>t2,+1.0otherwise.
π SEE ALSO π
and that's the whole page bestie, you ate that π this was libttyrec(3) from the termrec manual, version 0.19, dated 2024-04-01 β go forth and handle those ttyrec files like the icon you are πβ¨π
π¦ where this page comes from
- ubuntu noble: libtty-dev 0.19-2.1build2 Β· LGPL-2+noAffero
- ubuntu questing: libtty-dev 0.19-2.1build2
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms