summaryrefslogtreecommitdiff
path: root/apps/web/src/services
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-04-13 04:41:33 +0200
committerMaze Winther <mazewinther@gmail.com>2026-04-13 05:08:29 +0200
commit7d4e166678c35d48b22b8d1d05639f981a956a8b (patch)
treeeb596d4f4609053524224169c247db24052db353 /apps/web/src/services
parentcad88ee4d1c9e06e7529b88ef5e5d3fdf3f89149 (diff)
downloadopencut-7d4e166678c35d48b22b8d1d05639f981a956a8b.tar.gz
fix: text measurement, rotation handle, video cache races, playback sync
Made-with: Cursor
Diffstat (limited to 'apps/web/src/services')
-rw-r--r--apps/web/src/services/video-cache/service.ts16
1 files changed, 16 insertions, 0 deletions
diff --git a/apps/web/src/services/video-cache/service.ts b/apps/web/src/services/video-cache/service.ts
index 36441981..e5f3991d 100644
--- a/apps/web/src/services/video-cache/service.ts
+++ b/apps/web/src/services/video-cache/service.ts
@@ -19,6 +19,7 @@ interface VideoSinkData {
export class VideoCache {
private sinks = new Map<string, VideoSinkData>();
private initPromises = new Map<string, Promise<void>>();
+ private frameChain = new Map<string, Promise<unknown>>();
async getFrameAt({
mediaId,
@@ -34,6 +35,21 @@ export class VideoCache {
const sinkData = this.sinks.get(mediaId);
if (!sinkData) return null;
+ const previous = this.frameChain.get(mediaId) ?? Promise.resolve();
+ const current = previous.then(() =>
+ this.resolveFrame({ sinkData, time }),
+ );
+ this.frameChain.set(mediaId, current.catch(() => {}));
+ return current;
+ }
+
+ private async resolveFrame({
+ sinkData,
+ time,
+ }: {
+ sinkData: VideoSinkData;
+ time: number;
+ }): Promise<WrappedCanvas | null> {
if (sinkData.nextFrame && sinkData.nextFrame.timestamp <= time) {
sinkData.currentFrame = sinkData.nextFrame;
sinkData.nextFrame = null;