summaryrefslogtreecommitdiff
path: root/apps/web/src/services/renderer
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-02-05 12:53:56 +0100
committerMaze Winther <mazewinther@gmail.com>2026-02-05 12:53:56 +0100
commit2257ca2e6f9f8834880ea9bab4355c168ee6c33b (patch)
treef2ead774beda94d95fb771bc3eb16972fb08468a /apps/web/src/services/renderer
parent490fc170c0705703728a889cbc35a04ca41ae7eb (diff)
downloadopencut-2257ca2e6f9f8834880ea9bab4355c168ee6c33b.tar.gz
make storage versioning per-project + few other refactors
Diffstat (limited to 'apps/web/src/services/renderer')
-rw-r--r--apps/web/src/services/renderer/nodes/image-node.ts19
-rw-r--r--apps/web/src/services/renderer/nodes/video-node.ts8
-rw-r--r--apps/web/src/services/renderer/scene-builder.ts5
3 files changed, 19 insertions, 13 deletions
diff --git a/apps/web/src/services/renderer/nodes/image-node.ts b/apps/web/src/services/renderer/nodes/image-node.ts
index 2a684d5f..5405b60b 100644
--- a/apps/web/src/services/renderer/nodes/image-node.ts
+++ b/apps/web/src/services/renderer/nodes/image-node.ts
@@ -1,10 +1,20 @@
import type { CanvasRenderer } from "../canvas-renderer";
import { BaseNode } from "./base-node";
-import type { BaseMediaNodeParams } from "./video-node";
const IMAGE_EPSILON = 1 / 1000;
-export type ImageNodeParams = BaseMediaNodeParams;
+export interface ImageNodeParams {
+ url: string;
+ duration: number;
+ timeOffset: number;
+ trimStart: number;
+ trimEnd: number;
+ x?: number;
+ y?: number;
+ width?: number;
+ height?: number;
+ opacity?: number;
+}
export class ImageNode extends BaseNode<ImageNodeParams> {
private image?: HTMLImageElement;
@@ -18,15 +28,12 @@ export class ImageNode extends BaseNode<ImageNodeParams> {
private async load() {
const image = new Image();
this.image = image;
- const url = URL.createObjectURL(this.params.file);
await new Promise<void>((resolve, reject) => {
image.onload = () => resolve();
image.onerror = () => reject(new Error("Image load failed"));
- image.src = url;
+ image.src = this.params.url;
});
-
- URL.revokeObjectURL(url);
}
private getImageTime(time: number) {
diff --git a/apps/web/src/services/renderer/nodes/video-node.ts b/apps/web/src/services/renderer/nodes/video-node.ts
index b6911df7..841eb459 100644
--- a/apps/web/src/services/renderer/nodes/video-node.ts
+++ b/apps/web/src/services/renderer/nodes/video-node.ts
@@ -4,8 +4,10 @@ import { videoCache } from "@/services/video-cache/service";
const VIDEO_EPSILON = 1 / 1000;
-export interface BaseMediaNodeParams {
+export interface VideoNodeParams {
+ url: string;
file: File;
+ mediaId: string;
duration: number;
timeOffset: number;
trimStart: number;
@@ -17,10 +19,6 @@ export interface BaseMediaNodeParams {
opacity?: number;
}
-export interface VideoNodeParams extends BaseMediaNodeParams {
- mediaId: string;
-}
-
export class VideoNode extends BaseNode<VideoNodeParams> {
private getVideoTime(time: number) {
return time - this.params.timeOffset + this.params.trimStart;
diff --git a/apps/web/src/services/renderer/scene-builder.ts b/apps/web/src/services/renderer/scene-builder.ts
index b36edda1..598854ea 100644
--- a/apps/web/src/services/renderer/scene-builder.ts
+++ b/apps/web/src/services/renderer/scene-builder.ts
@@ -51,7 +51,7 @@ export function buildScene(params: BuildSceneParams) {
for (const element of elements) {
if (element.type === "video" || element.type === "image") {
const mediaAsset = mediaMap.get(element.mediaId);
- if (!mediaAsset?.file) {
+ if (!mediaAsset?.file || !mediaAsset?.url) {
continue;
}
@@ -59,6 +59,7 @@ export function buildScene(params: BuildSceneParams) {
contentNodes.push(
new VideoNode({
mediaId: mediaAsset.id,
+ url: mediaAsset.url,
file: mediaAsset.file,
duration: element.duration,
timeOffset: element.startTime,
@@ -70,7 +71,7 @@ export function buildScene(params: BuildSceneParams) {
if (mediaAsset.type === "image") {
contentNodes.push(
new ImageNode({
- file: mediaAsset.file,
+ url: mediaAsset.url,
duration: element.duration,
timeOffset: element.startTime,
trimStart: element.trimStart,