recorders
A Recorder is an abstract class.
abstract class Recorder<T = unknown, F = T[]> {
protected manager: RecordingManager;
protected player: Player;
/**
A recorder is intransigent if it cannot be started immediately (e.g. AudioRecorder).
*/
intransigent = false;
/** Begin recording */
beginRecording() {}
/** Pause recording */
pauseRecording() {}
/** Resume recording from paused state. */
resumeRecording() {}
endRecording(): Promise<[number, number]> | void {}
finalizeRecording(data: T[], startDelay = 0, stopDelay = 0): F {
return data as unknown as F;
}
push: (value: T) => void;
provide({push, manager, player}: {
push: (value: T) => void;
manager: RecordingManager;
player: Player;
}) {
this.push = push;
this.manager = manager;
this.player = player;
}
getUpdate(data: T[], lastDuration: number) {}
}
RecorderPlugin
interface RecorderPlugin {
enabled?: () => boolean;
icon: JSX.Element;
key: string;
name: string;
recorder: Recorder;
saveComponent: React.FC<{data: any}>;
title?: string;
}
ReplayDataRecorder
export class ReplayDataRecorder<T> extends Recorder<[number, T]> {
private duration: number;
private index: number;
constructor() {
super();
this.duration = 0;
this.index = -1;
}
beginRecording() {
this.duration = 0;
this.index = -1;
}
finalizeRecording(data: ReplayData<T>, startDelay = 0, stopDelay = 0) {
for (let sum = 0, i = 0; i < data.length && sum < startDelay; ++i) {
const dur = data[i][0];
if (dur === 0) {
continue;
}
if (sum + dur >= startDelay) {
data[i][0] -= startDelay - sum;
break;
}
sum += dur;
data.splice(i, 1);
--i;
}
return data;
}
capture(time: number, data: T) {
if (time - this.duration < 0) {
// console.error(time, this.duration, data);
}
this.push([time - this.duration, data]);
this.duration = time;
}
}
tip
filesize
/**
Limit number to 2 decimal places to reduce filesize.
*/
function formatNum(x: number): number {
return parseFloat(x.toFixed(2));
}