Skip to content

Commit 4cf26ca

Browse files
various recap improvements
1 parent 6306155 commit 4cf26ca

File tree

3 files changed

+20
-28
lines changed

3 files changed

+20
-28
lines changed

src/client/graphics/recapCapture/GameRecapCapture.ts

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ export class GameRecapCapture {
3030
private stopped = false;
3131
private resolvedMimeType: string | null = null;
3232
private pendingFinalCapture = false;
33-
private disableOverridesAfterCapture = false;
3433
private memoryUsageLogged = false;
3534

3635
constructor(
@@ -47,21 +46,19 @@ export class GameRecapCapture {
4746
start() {
4847
this.stopped = false;
4948
this.resolvedMimeType = null;
49+
this.lastCaptureTick = null;
5050
this.frameStore.setLoopPauseMs(0);
5151
this.pendingFinalCapture = false;
52-
this.disableOverridesAfterCapture = false;
5352
this.memoryUsageLogged = false;
54-
this.setLayerCaptureOverrides(true);
5553
this.refreshViewportSize();
54+
this.frameStore.clear();
5655
}
5756

5857
dispose() {
5958
this.stopped = true;
6059
this.pendingFinalCapture = false;
6160
this.surface.dispose();
6261
this.frameStore.clear();
63-
this.setLayerCaptureOverrides(false);
64-
this.disableOverridesAfterCapture = false;
6562
this.memoryUsageLogged = false;
6663
}
6764

@@ -114,7 +111,6 @@ export class GameRecapCapture {
114111
}
115112
this.stopped = true;
116113
this.frameStore.setLoopPauseMs(this.config.loopTailHoldMs);
117-
this.disableOverridesAfterCapture = true;
118114
if (this.captureInProgress) {
119115
this.pendingFinalCapture = true;
120116
} else {
@@ -126,6 +122,10 @@ export class GameRecapCapture {
126122
blob: Blob;
127123
filename: string;
128124
}> {
125+
const fpsInput = Number.isFinite(targetFps)
126+
? targetFps
127+
: this.config.exportFps;
128+
const fps = Math.min(60, Math.max(1, Math.round(fpsInput)));
129129
const frames = this.frameStore.getFrames();
130130
if (frames.length === 0) {
131131
throw new Error("No recap frames available for export");
@@ -153,7 +153,7 @@ export class GameRecapCapture {
153153
);
154154
}
155155

156-
const stream = canvas.captureStream(targetFps);
156+
const stream = canvas.captureStream(fps);
157157
const recorderOptions: MediaRecorderOptions = { mimeType };
158158
if (this.config.exportVideoBitsPerSecond) {
159159
recorderOptions.videoBitsPerSecond = this.config.exportVideoBitsPerSecond;
@@ -210,7 +210,7 @@ export class GameRecapCapture {
210210

211211
const framesToEncode =
212212
frames.length === 1 ? [...frames, frames[0]] : [...frames];
213-
const frameInterval = Math.max(1000 / targetFps, 16);
213+
const frameInterval = Math.max(1000 / fps, 16);
214214

215215
await drawFrame(framesToEncode[0]);
216216

@@ -348,9 +348,6 @@ export class GameRecapCapture {
348348
if (this.pendingFinalCapture) {
349349
this.pendingFinalCapture = false;
350350
this.queueCapture(this.game.ticks());
351-
} else if (this.disableOverridesAfterCapture) {
352-
this.disableOverridesAfterCapture = false;
353-
this.setLayerCaptureOverrides(false);
354351
}
355352
});
356353
};
@@ -362,21 +359,6 @@ export class GameRecapCapture {
362359
}
363360
}
364361

365-
private setLayerCaptureOverrides(enabled: boolean) {
366-
for (const layer of this.layers) {
367-
const candidate = layer as {
368-
setCaptureRenderEnabled?: (
369-
capture: boolean,
370-
mode?: "normal" | "shape",
371-
) => void;
372-
};
373-
candidate.setCaptureRenderEnabled?.(
374-
enabled,
375-
enabled ? "shape" : "normal",
376-
);
377-
}
378-
}
379-
380362
private snapshotTransform(): TransformSnapshot {
381363
const handler = this.transformHandler as unknown as TransformSnapshot;
382364
return {

src/client/graphics/recapCapture/RecapCaptureConfig.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export const defaultRecapCaptureConfig: RecapCaptureConfig = {
1616
maxFrames: 900,
1717
targetWidth: 1920,
1818
targetHeight: 1080,
19-
imageMimeType: "image/png",
20-
imageQuality: 1,
19+
imageMimeType: "image/webp",
20+
imageQuality: 0.92,
2121
loopTailHoldMs: 1000,
2222
exportFps: 10,
2323
exportVideoBitsPerSecond: 8_000_000,

src/client/graphics/recapCapture/RecapFrameStore.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ export class RecapFrameStore {
5858
removed.forEach((frame) => {
5959
this.totalBlobBytes -= frame.blob.size;
6060
URL.revokeObjectURL(frame.objectUrl);
61+
try {
62+
frame.imageBitmap?.close();
63+
} catch {
64+
/* ignore */
65+
}
6166
});
6267
this.frames = next;
6368
}
@@ -79,6 +84,11 @@ export class RecapFrameStore {
7984
clear() {
8085
for (const frame of this.frames) {
8186
URL.revokeObjectURL(frame.objectUrl);
87+
try {
88+
frame.imageBitmap?.close();
89+
} catch {
90+
/* ignore */
91+
}
8292
}
8393
this.frames = [];
8494
this.loopPauseMs = 0;

0 commit comments

Comments
 (0)