aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlonkaars <loek@pipeframe.xyz>2021-05-13 09:46:43 +0200
committerlonkaars <loek@pipeframe.xyz>2021-05-13 09:46:43 +0200
commit1c2bf928669d8afe5f8e0bc8290e7f25b2e524e0 (patch)
treebc2e8674e9d5169a7462727e1ff62edc3091700e
parent0eee3ce6321990244ac18e0f7e3b1f901e78279d (diff)
working demo
-rw-r--r--pages/present.tsx64
-rw-r--r--timeline.schema.json122
2 files changed, 102 insertions, 84 deletions
diff --git a/pages/present.tsx b/pages/present.tsx
index 3150784..032ce08 100644
--- a/pages/present.tsx
+++ b/pages/present.tsx
@@ -1,8 +1,8 @@
import Button from '@material-ui/core/Button';
+import Ajv from 'ajv';
import { useEffect, useState } from 'react';
-import { timeline } from '../timeline';
+import timeline, { slide } from '../timeline';
import * as timelineSchema from '../timeline.schema.json';
-import Ajv from 'ajv';
import ExitToAppRoundedIcon from '@material-ui/icons/ExitToAppRounded';
import PlayArrowRoundedIcon from '@material-ui/icons/PlayArrowRounded';
@@ -20,7 +20,7 @@ class TimedVideoPlayer {
video: string;
constructor(public framerate: number) {
- this.slide = 0;
+ this.slide = -1;
this.precision = 3;
}
@@ -38,11 +38,38 @@ class TimedVideoPlayer {
this.registerEventListeners();
}
+ jumpToFrame(frame: number) {
+ this.player.currentTime = this.frameToTimestamp(frame);
+ }
+
+ handleSlide(slide: slide) {
+ this.jumpToFrame(slide.frame);
+ this.player.pause();
+ }
+
registerEventListeners() {
- if(!this.video ||
- !this.player ||
- !this.timeline ) return;
- console.log('we\'re good to go!');
+ if (
+ !this.video
+ || !this.player
+ || !this.timeline
+ ) {
+ return;
+ }
+
+ setInterval(() => {
+ if (this.player.paused) return;
+ var frame = this.timestampToFrame(this.player.currentTime);
+
+ // debug
+ document.getElementById('frame').innerText = frame.toString();
+
+ var slide = this.timeline.slides[this.slide];
+ if (!slide) return;
+
+ if (frame >= slide.frame) {
+ this.handleSlide(slide);
+ }
+ }, 1e3 / (this.precision * this.framerate));
}
loadVideo(base64Video: string) {
@@ -55,23 +82,24 @@ class TimedVideoPlayer {
try {
var timeline = JSON.parse(jsonString);
} catch (e) {
- console.log("invalid json object!" + e);
+ console.log('invalid json object!' + e);
return;
}
var ajv = new Ajv({ allErrors: true });
var validate = ajv.compile(timelineSchema);
if (!validate(timeline)) {
- console.log("schema not passed!")
+ console.log('schema not passed!');
return;
}
- this.timeline = timeline;
+ this.timeline = timeline as timeline;
this.registerEventListeners();
}
-
+
next() {
- console.log('next slide');
+ this.slide++;
+ this.player.play();
}
previous() {
@@ -97,16 +125,6 @@ export default function Present() {
/* videoEL.addEventListener('canplaythrough', () => { */
/* console.log('full load') */
/* }); */
-
- /* setInterval(() => { */
- /* if (videoEL.paused) return; */
- /* var frame = TimedVideoPlayer.timestampToFrame(videoEL.currentTime, framerate); */
- /* document.getElementById('frame').innerText = frame.toString(); */
- /* if (frame >= framerate) { */
- /* videoEL.pause(); */
- /* console.log(videoEL.currentTime); */
- /* } */
- /* }, 1e3 / (precision * framerate)); */
}, []);
return <div className='presentation posfix a0 h100vh'>
@@ -127,7 +145,7 @@ export default function Present() {
document.getElementById('menu').classList.add('active');
}}
/>
- <div className='control next' onClick={player.next} />
+ <div className='control next' onClick={() => player.next()} />
</div>
<div className='menu posabs a0' id='menu'>
<div
diff --git a/timeline.schema.json b/timeline.schema.json
index a044993..8493d49 100644
--- a/timeline.schema.json
+++ b/timeline.schema.json
@@ -1,62 +1,62 @@
{
- "$ref": "#/definitions/timeline",
- "$schema": "http://json-schema.org/draft-07/schema#",
- "definitions": {
- "keyframeTypes": {
- "enum": [
- "default",
- "delay",
- "speedChange",
- "loop"
- ],
- "type": "string"
- },
- "slide": {
- "additionalProperties": false,
- "properties": {
- "clickThroughBehaviour": {
- "enum": [
- "ImmediatelySkip",
- "PlayOut"
- ],
- "type": "string"
- },
- "frame": {
- "type": "number"
- },
- "type": {
- "$ref": "#/definitions/keyframeTypes"
- }
- },
- "required": [
- "frame",
- "clickThroughBehaviour",
- "type"
- ],
- "type": "object"
- },
- "timeline": {
- "additionalProperties": false,
- "properties": {
- "framecount": {
- "type": "number"
- },
- "framerate": {
- "type": "number"
- },
- "slides": {
- "items": {
- "$ref": "#/definitions/slide"
- },
- "type": "array"
- }
- },
- "required": [
- "slides",
- "framecount",
- "framerate"
- ],
- "type": "object"
- }
- }
-} \ No newline at end of file
+ "$ref": "#/definitions/timeline",
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "definitions": {
+ "keyframeTypes": {
+ "enum": [
+ "default",
+ "delay",
+ "speedChange",
+ "loop"
+ ],
+ "type": "string"
+ },
+ "slide": {
+ "additionalProperties": false,
+ "properties": {
+ "clickThroughBehaviour": {
+ "enum": [
+ "ImmediatelySkip",
+ "PlayOut"
+ ],
+ "type": "string"
+ },
+ "frame": {
+ "type": "number"
+ },
+ "type": {
+ "$ref": "#/definitions/keyframeTypes"
+ }
+ },
+ "required": [
+ "frame",
+ "clickThroughBehaviour",
+ "type"
+ ],
+ "type": "object"
+ },
+ "timeline": {
+ "additionalProperties": false,
+ "properties": {
+ "framecount": {
+ "type": "number"
+ },
+ "framerate": {
+ "type": "number"
+ },
+ "slides": {
+ "items": {
+ "$ref": "#/definitions/slide"
+ },
+ "type": "array"
+ }
+ },
+ "required": [
+ "slides",
+ "framecount",
+ "framerate"
+ ],
+ "type": "object"
+ }
+ }
+}