2026-01-31 00:20:04 +01:00
|
|
|
import type { CanvasRenderer } from "../canvas-renderer";
|
2026-02-08 22:21:17 +01:00
|
|
|
import { VisualNode, type VisualNodeParams } from "./visual-node";
|
2026-01-31 22:54:33 +01:00
|
|
|
import { videoCache } from "@/services/video-cache/service";
|
2026-01-31 00:20:04 +01:00
|
|
|
|
2026-02-08 22:21:17 +01:00
|
|
|
export interface VideoNodeParams extends VisualNodeParams {
|
2026-02-05 12:53:56 +01:00
|
|
|
url: string;
|
2026-01-31 00:20:04 +01:00
|
|
|
file: File;
|
2026-02-05 12:53:56 +01:00
|
|
|
mediaId: string;
|
2026-01-31 00:20:04 +01:00
|
|
|
}
|
|
|
|
|
|
2026-02-08 22:21:17 +01:00
|
|
|
export class VideoNode extends VisualNode<VideoNodeParams> {
|
2026-01-31 00:20:04 +01:00
|
|
|
async render({ renderer, time }: { renderer: CanvasRenderer; time: number }) {
|
|
|
|
|
await super.render({ renderer, time });
|
|
|
|
|
|
|
|
|
|
if (!this.isInRange(time)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-27 16:33:57 +01:00
|
|
|
const videoTime = this.getSourceLocalTime(time);
|
2026-01-31 00:20:04 +01:00
|
|
|
const frame = await videoCache.getFrameAt({
|
|
|
|
|
mediaId: this.params.mediaId,
|
|
|
|
|
file: this.params.file,
|
|
|
|
|
time: videoTime,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (frame) {
|
2026-02-08 22:21:17 +01:00
|
|
|
this.renderVisual({
|
|
|
|
|
renderer,
|
|
|
|
|
source: frame.canvas,
|
|
|
|
|
sourceWidth: frame.canvas.width,
|
|
|
|
|
sourceHeight: frame.canvas.height,
|
2026-02-27 16:33:57 +01:00
|
|
|
timelineTime: time,
|
2026-02-08 22:21:17 +01:00
|
|
|
});
|
2026-01-31 00:20:04 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|