aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/Player/Video.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/Player/Video.ts')
-rw-r--r--src/lib/Player/Video.ts55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/lib/Player/Video.ts b/src/lib/Player/Video.ts
new file mode 100644
index 0000000..78b3b8f
--- /dev/null
+++ b/src/lib/Player/Video.ts
@@ -0,0 +1,55 @@
+export type FrameTime = {
+ milliseconds: number,
+ seconds: number,
+ frames: number
+}
+export abstract class Video {
+ public constructor(public canvas: HTMLCanvasElement) { };
+ public abstract renderFrame(time: FrameTime): Promise<void> | void;
+ /** (re-)Initializes the Video object. Also called on window resizes. */
+ public abstract init(): void | Promise<void>;
+ private _isInit = false;
+ /** The frames per second to render at */
+ public abstract get fps(): number;
+ /** Length in frames */
+ public abstract get length(): number;
+ /** A URL (and matching filename) to an ffmpeg-compatible audio file */
+ public audioUrl?: readonly [filename: string, fileUrl: string];
+ /** Resizes the canvas to a predetermined render resolution - must only be called in init() - do not overwrite */
+ public resize(x: number, y: number) {
+ if (!this._isInit) throw new Error('Must only call resize() in init.')
+ this.canvas.width = x;
+ this.canvas.height = y;
+ const parentW = this.canvas.parentElement!.clientWidth,
+ parentH = this.canvas.parentElement!.clientHeight
+ if (x <= parentW && y <= parentH) {
+ this.canvas.style.width = `${x}px`;
+ this.canvas.style.height = `${y}px`;
+ } else if (x <= parentW && y > parentH) {
+ this.canvas.style.width = `${x / y * parentH}px`;
+ this.canvas.style.height = `${parentH}px`;
+ } else if (y <= parentH && x > parentW) {
+ this.canvas.style.width = `${parentW}px`;
+ this.canvas.style.height = `${y / x * parentW}px`;
+ } else {
+ if ((parentW / x) * y > parentH) {
+ this.canvas.style.width = `${(parentH / y) * x}px`
+ this.canvas.style.height = `${parentH}px`
+ } else {
+ this.canvas.style.width = `${parentW}px`
+ this.canvas.style.height = `${(parentW / x) * y}px`
+ }
+ }
+ }
+ /** The width of the video, in pixels */
+ public get w() {
+ return this.canvas.width;
+ }
+ /** The height of the video, in pixels */
+ public get h() {
+ return this.canvas.height;
+ }
+ /** Use to cleanup any mess you made - do not remove the canvas, it may be reused. */
+ public cleanup() { };
+}
+export type VideoConstructor = new (...params: ConstructorParameters<typeof Video>) => Video