mirror of
https://codeberg.org/vlw/monkeydo.git
synced 2025-09-13 15:53:40 +02:00
Add media element sync
This commit is contained in:
parent
46f3a07c85
commit
cec5969a26
3 changed files with 57 additions and 2 deletions
30
Monkeydo.mjs
30
Monkeydo.mjs
|
@ -8,6 +8,25 @@ export default class Monkeydo extends MonkeyMaster {
|
||||||
super();
|
super();
|
||||||
this.methods = {};
|
this.methods = {};
|
||||||
Object.assign(this.methods,methods);
|
Object.assign(this.methods,methods);
|
||||||
|
|
||||||
|
this.media = {
|
||||||
|
_element: null,
|
||||||
|
get exists() {
|
||||||
|
return this._element instanceof HTMLMediaElement;
|
||||||
|
},
|
||||||
|
bind: (element) => {
|
||||||
|
if(element instanceof HTMLMediaElement !== true) throw new TypeError("Not a media element");
|
||||||
|
this.media.unbind();
|
||||||
|
|
||||||
|
this.media._element = element;
|
||||||
|
// Send timestamps to worker
|
||||||
|
this.media._element.addEventListener("timeupdate",event => this.mediaTimeUpdate(event.timeStamp));
|
||||||
|
},
|
||||||
|
unbind: () => {
|
||||||
|
this.stop();
|
||||||
|
this.media._element = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute a task
|
// Execute a task
|
||||||
|
@ -38,6 +57,15 @@ export default class Monkeydo extends MonkeyMaster {
|
||||||
async play(manifest = null) {
|
async play(manifest = null) {
|
||||||
if(!this.ready && !manifest) throw new Error("Can not start playback without a manifest");
|
if(!this.ready && !manifest) throw new Error("Can not start playback without a manifest");
|
||||||
if(manifest) await this.load(manifest);
|
if(manifest) await this.load(manifest);
|
||||||
return await this.start();
|
|
||||||
|
if(!this.media.exists) return await this.start();
|
||||||
|
|
||||||
|
// Start Monkeydo playback after media is playing
|
||||||
|
this.media._element.play()
|
||||||
|
.then(() => this.start())
|
||||||
|
// Poll the play function until the user interacts with the page
|
||||||
|
.catch(error => {
|
||||||
|
if(error instanceof DOMException && error.name === "NotAllowedError") this.play(manifest);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,6 +22,18 @@ class Monkey {
|
||||||
return this._target;
|
return this._target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync delays with media element
|
||||||
|
this.media = {
|
||||||
|
_timeStamp: null,
|
||||||
|
get time() {
|
||||||
|
return this._timeStamp;
|
||||||
|
},
|
||||||
|
set time(timeStamp) {
|
||||||
|
timeStamp = Math.floor(timeStamp);
|
||||||
|
this._timeStamp = timeStamp;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance to the next task or loop
|
// Advance to the next task or loop
|
||||||
|
@ -35,7 +47,9 @@ class Monkey {
|
||||||
|
|
||||||
this.tasks._i++;
|
this.tasks._i++;
|
||||||
const nextTask = this.tasks.task;
|
const nextTask = this.tasks.task;
|
||||||
this.tasks._target = performance.now() + nextTask[0];
|
const currentTime = this.media.time ? this.media.time : performance.now();
|
||||||
|
|
||||||
|
this.tasks._target = currentTime + nextTask[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main event loop, runs on every frame
|
// Main event loop, runs on every frame
|
||||||
|
@ -61,6 +75,12 @@ class Monkey {
|
||||||
return value ? this.flags[index] = value : this.flags[index];
|
return value ? this.flags[index] = value : this.flags[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use HTMLMediaElement.currentTime instead of performance.now()
|
||||||
|
setMedia(value = null) {
|
||||||
|
if(value instanceof HTMLMediaElement !== true) value = null;
|
||||||
|
this._media = value;
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch and install manifest from URL
|
// Fetch and install manifest from URL
|
||||||
async fetchManifest(url) {
|
async fetchManifest(url) {
|
||||||
const manifest = await fetch(url);
|
const manifest = await fetch(url);
|
||||||
|
|
|
@ -101,6 +101,12 @@ export default class MonkeyMaster {
|
||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update worker's media time override with a new timestamp
|
||||||
|
async mediaTimeUpdate(time) {
|
||||||
|
if(!this.ready) await this.init();
|
||||||
|
this.comlink.media.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
// Load a Monkeydo manifest by URL or JSON string
|
// Load a Monkeydo manifest by URL or JSON string
|
||||||
async loadManifest(manifest) {
|
async loadManifest(manifest) {
|
||||||
if(!this.ready) await this.init();
|
if(!this.ready) await this.init();
|
||||||
|
@ -122,6 +128,7 @@ export default class MonkeyMaster {
|
||||||
}
|
}
|
||||||
|
|
||||||
async stop() {
|
async stop() {
|
||||||
|
if(!this.ready) await this.init();
|
||||||
return await this.comlink.abort();
|
return await this.comlink.abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue