diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-04-13 04:41:33 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-04-13 05:08:29 +0200 |
| commit | 7d4e166678c35d48b22b8d1d05639f981a956a8b (patch) | |
| tree | eb596d4f4609053524224169c247db24052db353 /apps/web/src/services | |
| parent | cad88ee4d1c9e06e7529b88ef5e5d3fdf3f89149 (diff) | |
| download | opencut-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.ts | 16 |
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; |
