@editframe/elements 0.7.0-beta.1 → 0.7.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/av/EncodedAsset.cjs +21 -14
- package/dist/lib/av/EncodedAsset.js +21 -14
- package/dist/lib/av/MP4File.cjs +6 -1
- package/dist/lib/av/MP4File.js +6 -1
- package/dist/packages/elements/src/EF_FRAMEGEN.cjs +10 -13
- package/dist/packages/elements/src/EF_FRAMEGEN.d.ts +0 -1
- package/dist/packages/elements/src/EF_FRAMEGEN.js +10 -13
- package/dist/packages/elements/src/elements/EFMedia.cjs +9 -7
- package/dist/packages/elements/src/elements/EFMedia.d.ts +1 -1
- package/dist/packages/elements/src/elements/EFMedia.js +9 -7
- package/dist/packages/elements/src/elements/EFTemporal.cjs +4 -3
- package/dist/packages/elements/src/elements/EFTemporal.d.ts +2 -0
- package/dist/packages/elements/src/elements/EFTemporal.js +4 -3
- package/dist/packages/elements/src/elements/EFTimegroup.cjs +6 -4
- package/dist/packages/elements/src/elements/EFTimegroup.js +6 -4
- package/dist/packages/elements/src/gui/EFFilmstrip.cjs +24 -19
- package/dist/packages/elements/src/gui/EFFilmstrip.js +24 -19
- package/dist/packages/elements/src/gui/EFWorkbench.cjs +6 -5
- package/dist/packages/elements/src/gui/EFWorkbench.d.ts +4 -4
- package/dist/packages/elements/src/gui/EFWorkbench.js +6 -5
- package/dist/packages/elements/src/gui/TWMixin.css.cjs +1 -1
- package/dist/packages/elements/src/gui/TWMixin.css.js +1 -1
- package/dist/packages/elements/src/index.cjs +1 -2
- package/dist/packages/elements/src/index.d.ts +1 -1
- package/dist/packages/elements/src/index.js +1 -2
- package/dist/style.css +4 -0
- package/package.json +14 -8
- package/src/elements/EFMedia.ts +13 -8
- package/src/elements/EFTemporal.ts +8 -5
- package/src/elements/EFTimegroup.ts +8 -4
- package/src/gui/EFFilmstrip.ts +24 -20
- package/src/gui/EFWorkbench.ts +9 -7
- package/dist/packages/elements/src/elements/EFTimeline.cjs +0 -15
- package/dist/packages/elements/src/elements/EFTimeline.d.ts +0 -3
- package/dist/packages/elements/src/elements/EFTimeline.js +0 -15
- package/src/elements/EFTimeline.ts +0 -13
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const MP4Box = require("mp4box");
|
|
4
|
+
const debug = require("debug");
|
|
4
5
|
const memoize = require("../util/memoize.cjs");
|
|
5
6
|
const MP4File = require("./MP4File.cjs");
|
|
6
7
|
function _interopNamespaceDefault(e) {
|
|
@@ -30,6 +31,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
30
31
|
if (result) __defProp(target, key, result);
|
|
31
32
|
return result;
|
|
32
33
|
};
|
|
34
|
+
const log = debug("ef:av");
|
|
33
35
|
const BUFFER_SIZE = 10;
|
|
34
36
|
class AssetNotAvailableLocally extends Error {
|
|
35
37
|
}
|
|
@@ -84,12 +86,14 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
84
86
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
85
87
|
output: async (decodedFrame) => {
|
|
86
88
|
const clone = decodedFrame.clone();
|
|
89
|
+
log("🖼️ frame cts=", decodedFrame.timestamp);
|
|
87
90
|
this.decodedFrames.push(clone);
|
|
88
91
|
this.pruneBuffer();
|
|
89
92
|
decodedFrame.close();
|
|
90
93
|
this.outCursor = this.samples.findIndex(
|
|
91
94
|
(sample) => sample.cts === decodedFrame.timestamp
|
|
92
95
|
);
|
|
96
|
+
log(`cursor=${this.sampleCursor} outCursor=${this.outCursor}`);
|
|
93
97
|
this.emit("frame", clone);
|
|
94
98
|
}
|
|
95
99
|
});
|
|
@@ -191,19 +195,6 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
191
195
|
this.decodedFrames.shift()?.close();
|
|
192
196
|
}
|
|
193
197
|
}
|
|
194
|
-
prettyPrint() {
|
|
195
|
-
const samplesInEncoder = this.sampleCursor - this.outCursor;
|
|
196
|
-
const cachedSamples = this.decodedFrames.length;
|
|
197
|
-
console.log(
|
|
198
|
-
Array.from({
|
|
199
|
-
length: this.sampleCursor - samplesInEncoder - cachedSamples
|
|
200
|
-
}).fill("⬜️").join(" "),
|
|
201
|
-
Array.from({ length: cachedSamples }).fill("🟩").join(" "),
|
|
202
|
-
Array.from({
|
|
203
|
-
length: samplesInEncoder
|
|
204
|
-
}).fill("🟨").join(" ")
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
198
|
get editsOffset() {
|
|
208
199
|
if (!this.defaultVideoTrack?.edits) {
|
|
209
200
|
return 0;
|
|
@@ -251,6 +242,7 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
251
242
|
for (let i = start; i <= end; i++) {
|
|
252
243
|
await this.waitUntilVideoQueueDrained();
|
|
253
244
|
const sample = this.getSample(i);
|
|
245
|
+
log("Decoding sample #", i, `cts=${sample.cts}`);
|
|
254
246
|
const sampleStart = sample.offset - firstSampleOffset;
|
|
255
247
|
const sampleEnd = sample.offset + sample.size - firstSampleOffset;
|
|
256
248
|
const chunk = new EncodedVideoChunk({
|
|
@@ -262,6 +254,7 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
262
254
|
this.videoDecoder.decode(chunk);
|
|
263
255
|
const nextSample = this.defaultVideoTrak?.samples?.[i + 1];
|
|
264
256
|
if (nextSample === void 0) {
|
|
257
|
+
log("ENDFLUSH");
|
|
265
258
|
await this.videoDecoder.flush();
|
|
266
259
|
}
|
|
267
260
|
}
|
|
@@ -304,6 +297,7 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
304
297
|
if (this.videoDecoder.state === "configured") {
|
|
305
298
|
this.videoDecoder.reset();
|
|
306
299
|
}
|
|
300
|
+
log("Attempting to configure decoder", this.decoderConfiguration);
|
|
307
301
|
this.videoDecoder.configure(this.decoderConfiguration);
|
|
308
302
|
}
|
|
309
303
|
// Default to -1 to throw error if called without an index
|
|
@@ -374,12 +368,24 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
374
368
|
(frame) => frame.timestamp === targetSample.cts
|
|
375
369
|
);
|
|
376
370
|
const atEnd = this.sampleCursor === this.samples.length - 1;
|
|
371
|
+
log(
|
|
372
|
+
"this.outCursor <= targetSample.number",
|
|
373
|
+
this.outCursor <= targetSample.number
|
|
374
|
+
);
|
|
375
|
+
log("this.outCursor <= targetIndex", this.outCursor <= targetIndex);
|
|
377
376
|
if (atEnd) {
|
|
378
377
|
return false;
|
|
379
378
|
}
|
|
380
379
|
if (targetInCache) {
|
|
381
380
|
return false;
|
|
382
381
|
}
|
|
382
|
+
log("========");
|
|
383
|
+
log("sampleCursor", this.sampleCursor);
|
|
384
|
+
log(" outCursor", this.outCursor);
|
|
385
|
+
log(" target", targetSample.number);
|
|
386
|
+
log(" targetIndex", targetIndex);
|
|
387
|
+
log(" inCache", !!targetInCache);
|
|
388
|
+
log(" atEnd", atEnd);
|
|
383
389
|
return this.outCursor > targetIndex;
|
|
384
390
|
}
|
|
385
391
|
async seekToTime(seconds) {
|
|
@@ -404,7 +410,7 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
404
410
|
this.sampleCursor = syncSampleNumber;
|
|
405
411
|
}
|
|
406
412
|
if (this.seekingWillGoBackwards(seconds)) {
|
|
407
|
-
|
|
413
|
+
log("BACKWARDS FLUSH");
|
|
408
414
|
await this.videoDecoder.flush();
|
|
409
415
|
for (const frame2 of this.decodedFrames) {
|
|
410
416
|
frame2.close();
|
|
@@ -424,6 +430,7 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
424
430
|
if (frame) {
|
|
425
431
|
return;
|
|
426
432
|
}
|
|
433
|
+
log("Maybe frame", _frame.timestamp, cts);
|
|
427
434
|
if (_frame.timestamp === cts) {
|
|
428
435
|
this.removeEventListener("frame", maybeFrame);
|
|
429
436
|
frame = _frame;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as MP4Box from "mp4box";
|
|
2
|
+
import debug from "debug";
|
|
2
3
|
import { memoize } from "../util/memoize.js";
|
|
3
4
|
import { MP4File } from "./MP4File.js";
|
|
4
5
|
var __defProp = Object.defineProperty;
|
|
@@ -11,6 +12,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
11
12
|
if (result) __defProp(target, key, result);
|
|
12
13
|
return result;
|
|
13
14
|
};
|
|
15
|
+
const log = debug("ef:av");
|
|
14
16
|
const BUFFER_SIZE = 10;
|
|
15
17
|
class AssetNotAvailableLocally extends Error {
|
|
16
18
|
}
|
|
@@ -65,12 +67,14 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
65
67
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
66
68
|
output: async (decodedFrame) => {
|
|
67
69
|
const clone = decodedFrame.clone();
|
|
70
|
+
log("🖼️ frame cts=", decodedFrame.timestamp);
|
|
68
71
|
this.decodedFrames.push(clone);
|
|
69
72
|
this.pruneBuffer();
|
|
70
73
|
decodedFrame.close();
|
|
71
74
|
this.outCursor = this.samples.findIndex(
|
|
72
75
|
(sample) => sample.cts === decodedFrame.timestamp
|
|
73
76
|
);
|
|
77
|
+
log(`cursor=${this.sampleCursor} outCursor=${this.outCursor}`);
|
|
74
78
|
this.emit("frame", clone);
|
|
75
79
|
}
|
|
76
80
|
});
|
|
@@ -172,19 +176,6 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
172
176
|
this.decodedFrames.shift()?.close();
|
|
173
177
|
}
|
|
174
178
|
}
|
|
175
|
-
prettyPrint() {
|
|
176
|
-
const samplesInEncoder = this.sampleCursor - this.outCursor;
|
|
177
|
-
const cachedSamples = this.decodedFrames.length;
|
|
178
|
-
console.log(
|
|
179
|
-
Array.from({
|
|
180
|
-
length: this.sampleCursor - samplesInEncoder - cachedSamples
|
|
181
|
-
}).fill("⬜️").join(" "),
|
|
182
|
-
Array.from({ length: cachedSamples }).fill("🟩").join(" "),
|
|
183
|
-
Array.from({
|
|
184
|
-
length: samplesInEncoder
|
|
185
|
-
}).fill("🟨").join(" ")
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
179
|
get editsOffset() {
|
|
189
180
|
if (!this.defaultVideoTrack?.edits) {
|
|
190
181
|
return 0;
|
|
@@ -232,6 +223,7 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
232
223
|
for (let i = start; i <= end; i++) {
|
|
233
224
|
await this.waitUntilVideoQueueDrained();
|
|
234
225
|
const sample = this.getSample(i);
|
|
226
|
+
log("Decoding sample #", i, `cts=${sample.cts}`);
|
|
235
227
|
const sampleStart = sample.offset - firstSampleOffset;
|
|
236
228
|
const sampleEnd = sample.offset + sample.size - firstSampleOffset;
|
|
237
229
|
const chunk = new EncodedVideoChunk({
|
|
@@ -243,6 +235,7 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
243
235
|
this.videoDecoder.decode(chunk);
|
|
244
236
|
const nextSample = this.defaultVideoTrak?.samples?.[i + 1];
|
|
245
237
|
if (nextSample === void 0) {
|
|
238
|
+
log("ENDFLUSH");
|
|
246
239
|
await this.videoDecoder.flush();
|
|
247
240
|
}
|
|
248
241
|
}
|
|
@@ -285,6 +278,7 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
285
278
|
if (this.videoDecoder.state === "configured") {
|
|
286
279
|
this.videoDecoder.reset();
|
|
287
280
|
}
|
|
281
|
+
log("Attempting to configure decoder", this.decoderConfiguration);
|
|
288
282
|
this.videoDecoder.configure(this.decoderConfiguration);
|
|
289
283
|
}
|
|
290
284
|
// Default to -1 to throw error if called without an index
|
|
@@ -355,12 +349,24 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
355
349
|
(frame) => frame.timestamp === targetSample.cts
|
|
356
350
|
);
|
|
357
351
|
const atEnd = this.sampleCursor === this.samples.length - 1;
|
|
352
|
+
log(
|
|
353
|
+
"this.outCursor <= targetSample.number",
|
|
354
|
+
this.outCursor <= targetSample.number
|
|
355
|
+
);
|
|
356
|
+
log("this.outCursor <= targetIndex", this.outCursor <= targetIndex);
|
|
358
357
|
if (atEnd) {
|
|
359
358
|
return false;
|
|
360
359
|
}
|
|
361
360
|
if (targetInCache) {
|
|
362
361
|
return false;
|
|
363
362
|
}
|
|
363
|
+
log("========");
|
|
364
|
+
log("sampleCursor", this.sampleCursor);
|
|
365
|
+
log(" outCursor", this.outCursor);
|
|
366
|
+
log(" target", targetSample.number);
|
|
367
|
+
log(" targetIndex", targetIndex);
|
|
368
|
+
log(" inCache", !!targetInCache);
|
|
369
|
+
log(" atEnd", atEnd);
|
|
364
370
|
return this.outCursor > targetIndex;
|
|
365
371
|
}
|
|
366
372
|
async seekToTime(seconds) {
|
|
@@ -385,7 +391,7 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
385
391
|
this.sampleCursor = syncSampleNumber;
|
|
386
392
|
}
|
|
387
393
|
if (this.seekingWillGoBackwards(seconds)) {
|
|
388
|
-
|
|
394
|
+
log("BACKWARDS FLUSH");
|
|
389
395
|
await this.videoDecoder.flush();
|
|
390
396
|
for (const frame2 of this.decodedFrames) {
|
|
391
397
|
frame2.close();
|
|
@@ -405,6 +411,7 @@ const _VideoAsset = class _VideoAsset2 extends ISOFileAsset {
|
|
|
405
411
|
if (frame) {
|
|
406
412
|
return;
|
|
407
413
|
}
|
|
414
|
+
log("Maybe frame", _frame.timestamp, cts);
|
|
408
415
|
if (_frame.timestamp === cts) {
|
|
409
416
|
this.removeEventListener("frame", maybeFrame);
|
|
410
417
|
frame = _frame;
|
package/dist/lib/av/MP4File.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const MP4Box = require("mp4box");
|
|
4
|
+
const debug = require("debug");
|
|
4
5
|
function _interopNamespaceDefault(e) {
|
|
5
6
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
6
7
|
if (e) {
|
|
@@ -18,6 +19,7 @@ function _interopNamespaceDefault(e) {
|
|
|
18
19
|
return Object.freeze(n);
|
|
19
20
|
}
|
|
20
21
|
const MP4Box__namespace = /* @__PURE__ */ _interopNamespaceDefault(MP4Box);
|
|
22
|
+
const log = debug("ef:av:mp4file");
|
|
21
23
|
class MP4File extends MP4Box__namespace.ISOFile {
|
|
22
24
|
constructor() {
|
|
23
25
|
super(...arguments);
|
|
@@ -114,7 +116,7 @@ class MP4File extends MP4Box__namespace.ISOFile {
|
|
|
114
116
|
fragTrak.segmentStream
|
|
115
117
|
);
|
|
116
118
|
} catch (error) {
|
|
117
|
-
console.
|
|
119
|
+
console.error("Failed to createFragment", error);
|
|
118
120
|
}
|
|
119
121
|
if (result) {
|
|
120
122
|
fragTrak.segmentStream = result;
|
|
@@ -140,6 +142,9 @@ class MP4File extends MP4Box__namespace.ISOFile {
|
|
|
140
142
|
if (trak.nextSample >= trak.samples.length) {
|
|
141
143
|
trackInfoForFrag.complete = true;
|
|
142
144
|
}
|
|
145
|
+
log(
|
|
146
|
+
`Yielding fragment #${trackInfoForFrag.index} for track=${fragTrak.id}`
|
|
147
|
+
);
|
|
143
148
|
const startSample = fragmentStartSamples[fragTrak.id];
|
|
144
149
|
const endSample = trak.samples[trak.nextSample - 1];
|
|
145
150
|
if (!startSample || !endSample) {
|
package/dist/lib/av/MP4File.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as MP4Box from "mp4box";
|
|
2
|
+
import debug from "debug";
|
|
3
|
+
const log = debug("ef:av:mp4file");
|
|
2
4
|
class MP4File extends MP4Box.ISOFile {
|
|
3
5
|
constructor() {
|
|
4
6
|
super(...arguments);
|
|
@@ -95,7 +97,7 @@ class MP4File extends MP4Box.ISOFile {
|
|
|
95
97
|
fragTrak.segmentStream
|
|
96
98
|
);
|
|
97
99
|
} catch (error) {
|
|
98
|
-
console.
|
|
100
|
+
console.error("Failed to createFragment", error);
|
|
99
101
|
}
|
|
100
102
|
if (result) {
|
|
101
103
|
fragTrak.segmentStream = result;
|
|
@@ -121,6 +123,9 @@ class MP4File extends MP4Box.ISOFile {
|
|
|
121
123
|
if (trak.nextSample >= trak.samples.length) {
|
|
122
124
|
trackInfoForFrag.complete = true;
|
|
123
125
|
}
|
|
126
|
+
log(
|
|
127
|
+
`Yielding fragment #${trackInfoForFrag.index} for track=${fragTrak.id}`
|
|
128
|
+
);
|
|
124
129
|
const startSample = fragmentStartSamples[fragTrak.id];
|
|
125
130
|
const endSample = trak.samples[trak.nextSample - 1];
|
|
126
131
|
if (!startSample || !endSample) {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const debug = require("debug");
|
|
3
4
|
const task = require("@lit/task");
|
|
4
5
|
const awaitMicrotask = require("../../../lib/util/awaitMicrotask.cjs");
|
|
5
6
|
const EFTemporal = require("./elements/EFTemporal.cjs");
|
|
6
7
|
const EFTimegroup = require("./elements/EFTimegroup.cjs");
|
|
8
|
+
const log = debug("ef:elements:EF_FRAMEGEN");
|
|
7
9
|
class TriggerCanvas {
|
|
8
10
|
constructor() {
|
|
9
11
|
this.canvas = document.createElement("canvas");
|
|
@@ -24,7 +26,7 @@ class TriggerCanvas {
|
|
|
24
26
|
this.ctx.fillStyle = "black";
|
|
25
27
|
}
|
|
26
28
|
trigger() {
|
|
27
|
-
|
|
29
|
+
log("TRIGGERING CANVAS");
|
|
28
30
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
29
31
|
}
|
|
30
32
|
}
|
|
@@ -40,9 +42,6 @@ class EfFramegen {
|
|
|
40
42
|
this.connectToBridge();
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
|
-
log(...args) {
|
|
44
|
-
console.log("[EF_FRAMEGEN]", ...args);
|
|
45
|
-
}
|
|
46
45
|
trace(...args) {
|
|
47
46
|
console.trace("[EF_FRAMEGEN]", ...args);
|
|
48
47
|
}
|
|
@@ -52,12 +51,12 @@ class EfFramegen {
|
|
|
52
51
|
throw new Error("No BRIDGE when attempting to connect to bridge");
|
|
53
52
|
}
|
|
54
53
|
BRIDGE.onInitialize(async (renderId, renderOptions) => {
|
|
55
|
-
|
|
54
|
+
log("BRIDGE.onInitialize", renderId, renderOptions);
|
|
56
55
|
await this.initialize(renderId, renderOptions);
|
|
57
56
|
BRIDGE.initialized(renderId);
|
|
58
57
|
});
|
|
59
58
|
BRIDGE.onBeginFrame((renderId, frameNumber, isLast) => {
|
|
60
|
-
|
|
59
|
+
log("BRIDGE.onBeginFrame", renderId, frameNumber, isLast);
|
|
61
60
|
this.beginFrame(renderId, frameNumber, isLast);
|
|
62
61
|
});
|
|
63
62
|
}
|
|
@@ -111,7 +110,7 @@ class EfFramegen {
|
|
|
111
110
|
// renderOptions.encoderOptions.fromMs,
|
|
112
111
|
// renderOptions.encoderOptions.toMs,
|
|
113
112
|
);
|
|
114
|
-
|
|
113
|
+
log("Initialized");
|
|
115
114
|
}
|
|
116
115
|
async beginFrame(renderId, frameNumber, isLast) {
|
|
117
116
|
if (this.renderOptions === void 0) {
|
|
@@ -136,20 +135,18 @@ class EfFramegen {
|
|
|
136
135
|
}
|
|
137
136
|
this.time = this.renderOptions.encoderOptions.fromMs + frameNumber * this.frameDurationMs;
|
|
138
137
|
firstGroup.currentTimeMs = this.time;
|
|
139
|
-
|
|
138
|
+
log("Awaiting initialBusyTasks");
|
|
140
139
|
await this.initialBusyTasks;
|
|
141
|
-
|
|
140
|
+
log("Awaiting microtask");
|
|
142
141
|
await awaitMicrotask.awaitMicrotask();
|
|
143
|
-
|
|
142
|
+
log("Awaiting frame tasks");
|
|
144
143
|
const now = performance.now();
|
|
145
144
|
await Promise.all(
|
|
146
145
|
temporals.filter((temporal) => temporal.frameTask.status < task.TaskStatus.COMPLETE).map((temporal) => {
|
|
147
146
|
return temporal.frameTask;
|
|
148
147
|
}).map((task2) => task2.taskComplete)
|
|
149
148
|
);
|
|
150
|
-
|
|
151
|
-
`frame:${frameNumber} All tasks complete ${performance.now() - now}ms`
|
|
152
|
-
);
|
|
149
|
+
log(`frame:${frameNumber} All tasks complete ${performance.now() - now}ms`);
|
|
153
150
|
if (isLast && this.audioBufferPromise) {
|
|
154
151
|
const renderedAudio = await this.audioBufferPromise;
|
|
155
152
|
const channelCount = renderedAudio.numberOfChannels;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import debug from "debug";
|
|
1
2
|
import { TaskStatus } from "@lit/task";
|
|
2
3
|
import { awaitMicrotask } from "../../../lib/util/awaitMicrotask.js";
|
|
3
4
|
import { deepGetElementsWithFrameTasks } from "./elements/EFTemporal.js";
|
|
4
5
|
import { shallowGetTimegroups } from "./elements/EFTimegroup.js";
|
|
6
|
+
const log = debug("ef:elements:EF_FRAMEGEN");
|
|
5
7
|
class TriggerCanvas {
|
|
6
8
|
constructor() {
|
|
7
9
|
this.canvas = document.createElement("canvas");
|
|
@@ -22,7 +24,7 @@ class TriggerCanvas {
|
|
|
22
24
|
this.ctx.fillStyle = "black";
|
|
23
25
|
}
|
|
24
26
|
trigger() {
|
|
25
|
-
|
|
27
|
+
log("TRIGGERING CANVAS");
|
|
26
28
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
27
29
|
}
|
|
28
30
|
}
|
|
@@ -38,9 +40,6 @@ class EfFramegen {
|
|
|
38
40
|
this.connectToBridge();
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
|
-
log(...args) {
|
|
42
|
-
console.log("[EF_FRAMEGEN]", ...args);
|
|
43
|
-
}
|
|
44
43
|
trace(...args) {
|
|
45
44
|
console.trace("[EF_FRAMEGEN]", ...args);
|
|
46
45
|
}
|
|
@@ -50,12 +49,12 @@ class EfFramegen {
|
|
|
50
49
|
throw new Error("No BRIDGE when attempting to connect to bridge");
|
|
51
50
|
}
|
|
52
51
|
BRIDGE.onInitialize(async (renderId, renderOptions) => {
|
|
53
|
-
|
|
52
|
+
log("BRIDGE.onInitialize", renderId, renderOptions);
|
|
54
53
|
await this.initialize(renderId, renderOptions);
|
|
55
54
|
BRIDGE.initialized(renderId);
|
|
56
55
|
});
|
|
57
56
|
BRIDGE.onBeginFrame((renderId, frameNumber, isLast) => {
|
|
58
|
-
|
|
57
|
+
log("BRIDGE.onBeginFrame", renderId, frameNumber, isLast);
|
|
59
58
|
this.beginFrame(renderId, frameNumber, isLast);
|
|
60
59
|
});
|
|
61
60
|
}
|
|
@@ -109,7 +108,7 @@ class EfFramegen {
|
|
|
109
108
|
// renderOptions.encoderOptions.fromMs,
|
|
110
109
|
// renderOptions.encoderOptions.toMs,
|
|
111
110
|
);
|
|
112
|
-
|
|
111
|
+
log("Initialized");
|
|
113
112
|
}
|
|
114
113
|
async beginFrame(renderId, frameNumber, isLast) {
|
|
115
114
|
if (this.renderOptions === void 0) {
|
|
@@ -134,20 +133,18 @@ class EfFramegen {
|
|
|
134
133
|
}
|
|
135
134
|
this.time = this.renderOptions.encoderOptions.fromMs + frameNumber * this.frameDurationMs;
|
|
136
135
|
firstGroup.currentTimeMs = this.time;
|
|
137
|
-
|
|
136
|
+
log("Awaiting initialBusyTasks");
|
|
138
137
|
await this.initialBusyTasks;
|
|
139
|
-
|
|
138
|
+
log("Awaiting microtask");
|
|
140
139
|
await awaitMicrotask();
|
|
141
|
-
|
|
140
|
+
log("Awaiting frame tasks");
|
|
142
141
|
const now = performance.now();
|
|
143
142
|
await Promise.all(
|
|
144
143
|
temporals.filter((temporal) => temporal.frameTask.status < TaskStatus.COMPLETE).map((temporal) => {
|
|
145
144
|
return temporal.frameTask;
|
|
146
145
|
}).map((task) => task.taskComplete)
|
|
147
146
|
);
|
|
148
|
-
|
|
149
|
-
`frame:${frameNumber} All tasks complete ${performance.now() - now}ms`
|
|
150
|
-
);
|
|
147
|
+
log(`frame:${frameNumber} All tasks complete ${performance.now() - now}ms`);
|
|
151
148
|
if (isLast && this.audioBufferPromise) {
|
|
152
149
|
const renderedAudio = await this.audioBufferPromise;
|
|
153
150
|
const channelCount = renderedAudio.numberOfChannels;
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const lit = require("lit");
|
|
4
|
-
const EFTemporal = require("./EFTemporal.cjs");
|
|
5
4
|
const decorators_js = require("lit/decorators.js");
|
|
6
5
|
const deepEquals_js = require("@lit/task/deep-equals.js");
|
|
7
6
|
const task = require("@lit/task");
|
|
7
|
+
const context = require("@lit/context");
|
|
8
|
+
const debug = require("debug");
|
|
8
9
|
const MP4File = require("../../../../lib/av/MP4File.cjs");
|
|
9
|
-
const
|
|
10
|
+
const EFTemporal = require("./EFTemporal.cjs");
|
|
10
11
|
const EncodedAsset = require("../../../../lib/av/EncodedAsset.cjs");
|
|
11
12
|
const FetchMixin = require("./FetchMixin.cjs");
|
|
12
13
|
const EFWorkbench = require("../gui/EFWorkbench.cjs");
|
|
13
|
-
const context = require("@lit/context");
|
|
14
14
|
const EFSourceMixin = require("./EFSourceMixin.cjs");
|
|
15
|
+
const util = require("./util.cjs");
|
|
15
16
|
const EF_INTERACTIVE = require("../EF_INTERACTIVE.cjs");
|
|
16
17
|
var __defProp = Object.defineProperty;
|
|
17
18
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -22,6 +23,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
22
23
|
if (result) __defProp(target, key, result);
|
|
23
24
|
return result;
|
|
24
25
|
};
|
|
26
|
+
const log = debug("ef:elements:EFMedia");
|
|
25
27
|
const deepGetMediaElements = (element, medias = []) => {
|
|
26
28
|
for (const child of Array.from(element.children)) {
|
|
27
29
|
if (child instanceof EFMedia) {
|
|
@@ -265,12 +267,12 @@ class EFMedia extends EFSourceMixin.EFSourceMixin(EFTemporal.EFTemporal(FetchMix
|
|
|
265
267
|
await this.trackFragmentIndexLoader.taskComplete;
|
|
266
268
|
const audioTrackId = this.defaultAudioTrackId;
|
|
267
269
|
if (!audioTrackId) {
|
|
268
|
-
|
|
270
|
+
log("No audio track found");
|
|
269
271
|
return;
|
|
270
272
|
}
|
|
271
273
|
const audioTrackIndex = this.trackFragmentIndexLoader.value?.[audioTrackId];
|
|
272
274
|
if (!audioTrackIndex) {
|
|
273
|
-
|
|
275
|
+
log("No audio track found");
|
|
274
276
|
return;
|
|
275
277
|
}
|
|
276
278
|
const start = audioTrackIndex.initSegment.offset;
|
|
@@ -290,12 +292,12 @@ class EFMedia extends EFSourceMixin.EFSourceMixin(EFTemporal.EFTemporal(FetchMix
|
|
|
290
292
|
);
|
|
291
293
|
const firstFragment = fragments[0];
|
|
292
294
|
if (!firstFragment) {
|
|
293
|
-
|
|
295
|
+
log("No audio fragments found");
|
|
294
296
|
return;
|
|
295
297
|
}
|
|
296
298
|
const lastFragment = fragments[fragments.length - 1];
|
|
297
299
|
if (!lastFragment) {
|
|
298
|
-
|
|
300
|
+
log("No audio fragments found");
|
|
299
301
|
return;
|
|
300
302
|
}
|
|
301
303
|
const fragmentStart = firstFragment.offset;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LitElement, PropertyValueMap } from 'lit';
|
|
2
2
|
import { Task } from '@lit/task';
|
|
3
|
-
import { MP4File } from '../../../../lib/av/MP4File';
|
|
4
3
|
import { TrackFragmentIndex, TrackSegment } from '../../../assets/src';
|
|
4
|
+
import { MP4File } from '../../../../lib/av/MP4File';
|
|
5
5
|
import { VideoAsset } from '../../../../lib/av/EncodedAsset';
|
|
6
6
|
|
|
7
7
|
import type * as MP4Box from "mp4box";
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { css, LitElement } from "lit";
|
|
2
|
-
import { EFTemporal } from "./EFTemporal.js";
|
|
3
2
|
import { property, state } from "lit/decorators.js";
|
|
4
3
|
import { deepArrayEquals } from "@lit/task/deep-equals.js";
|
|
5
4
|
import { Task } from "@lit/task";
|
|
5
|
+
import { consume } from "@lit/context";
|
|
6
|
+
import debug from "debug";
|
|
6
7
|
import { MP4File } from "../../../../lib/av/MP4File.js";
|
|
7
|
-
import {
|
|
8
|
+
import { EFTemporal } from "./EFTemporal.js";
|
|
8
9
|
import { VideoAsset } from "../../../../lib/av/EncodedAsset.js";
|
|
9
10
|
import { FetchMixin } from "./FetchMixin.js";
|
|
10
11
|
import { apiHostContext } from "../gui/EFWorkbench.js";
|
|
11
|
-
import { consume } from "@lit/context";
|
|
12
12
|
import { EFSourceMixin } from "./EFSourceMixin.js";
|
|
13
|
+
import { getStartTimeMs } from "./util.js";
|
|
13
14
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
14
15
|
var __defProp = Object.defineProperty;
|
|
15
16
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -20,6 +21,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
20
21
|
if (result) __defProp(target, key, result);
|
|
21
22
|
return result;
|
|
22
23
|
};
|
|
24
|
+
const log = debug("ef:elements:EFMedia");
|
|
23
25
|
const deepGetMediaElements = (element, medias = []) => {
|
|
24
26
|
for (const child of Array.from(element.children)) {
|
|
25
27
|
if (child instanceof EFMedia) {
|
|
@@ -263,12 +265,12 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
263
265
|
await this.trackFragmentIndexLoader.taskComplete;
|
|
264
266
|
const audioTrackId = this.defaultAudioTrackId;
|
|
265
267
|
if (!audioTrackId) {
|
|
266
|
-
|
|
268
|
+
log("No audio track found");
|
|
267
269
|
return;
|
|
268
270
|
}
|
|
269
271
|
const audioTrackIndex = this.trackFragmentIndexLoader.value?.[audioTrackId];
|
|
270
272
|
if (!audioTrackIndex) {
|
|
271
|
-
|
|
273
|
+
log("No audio track found");
|
|
272
274
|
return;
|
|
273
275
|
}
|
|
274
276
|
const start = audioTrackIndex.initSegment.offset;
|
|
@@ -288,12 +290,12 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
288
290
|
);
|
|
289
291
|
const firstFragment = fragments[0];
|
|
290
292
|
if (!firstFragment) {
|
|
291
|
-
|
|
293
|
+
log("No audio fragments found");
|
|
292
294
|
return;
|
|
293
295
|
}
|
|
294
296
|
const lastFragment = fragments[fragments.length - 1];
|
|
295
297
|
if (!lastFragment) {
|
|
296
|
-
|
|
298
|
+
log("No audio fragments found");
|
|
297
299
|
return;
|
|
298
300
|
}
|
|
299
301
|
const fragmentStart = firstFragment.offset;
|
|
@@ -106,8 +106,7 @@ const EFTemporal = (superClass) => {
|
|
|
106
106
|
// Defining this as a getter to a private property allows us to
|
|
107
107
|
// override it classes that include this mixin.
|
|
108
108
|
get durationMs() {
|
|
109
|
-
|
|
110
|
-
return durationMs || 0;
|
|
109
|
+
return this._durationMs || this.parentTimegroup?.durationMs || 0;
|
|
111
110
|
}
|
|
112
111
|
get offsetMs() {
|
|
113
112
|
return this._offsetMs || 0;
|
|
@@ -133,7 +132,9 @@ const EFTemporal = (superClass) => {
|
|
|
133
132
|
switch (parentTimegroup.mode) {
|
|
134
133
|
case "sequence": {
|
|
135
134
|
const siblingTemorals = shallowGetTemporalElements(parentTimegroup);
|
|
136
|
-
const ownIndex = siblingTemorals.indexOf(
|
|
135
|
+
const ownIndex = siblingTemorals.indexOf(
|
|
136
|
+
this
|
|
137
|
+
);
|
|
137
138
|
if (ownIndex === 0) {
|
|
138
139
|
return parentTimegroup.startTimeMs;
|
|
139
140
|
}
|
|
@@ -12,6 +12,8 @@ export declare class TemporalMixinInterface {
|
|
|
12
12
|
get startTimeWithinParentMs(): number;
|
|
13
13
|
get endTimeMs(): number;
|
|
14
14
|
get ownCurrentTimeMs(): number;
|
|
15
|
+
set duration(value: string);
|
|
16
|
+
get duration(): string;
|
|
15
17
|
parentTimegroup?: EFTimegroup;
|
|
16
18
|
rootTimegroup?: EFTimegroup;
|
|
17
19
|
frameTask: Task<readonly unknown[], unknown>;
|
|
@@ -104,8 +104,7 @@ const EFTemporal = (superClass) => {
|
|
|
104
104
|
// Defining this as a getter to a private property allows us to
|
|
105
105
|
// override it classes that include this mixin.
|
|
106
106
|
get durationMs() {
|
|
107
|
-
|
|
108
|
-
return durationMs || 0;
|
|
107
|
+
return this._durationMs || this.parentTimegroup?.durationMs || 0;
|
|
109
108
|
}
|
|
110
109
|
get offsetMs() {
|
|
111
110
|
return this._offsetMs || 0;
|
|
@@ -131,7 +130,9 @@ const EFTemporal = (superClass) => {
|
|
|
131
130
|
switch (parentTimegroup.mode) {
|
|
132
131
|
case "sequence": {
|
|
133
132
|
const siblingTemorals = shallowGetTemporalElements(parentTimegroup);
|
|
134
|
-
const ownIndex = siblingTemorals.indexOf(
|
|
133
|
+
const ownIndex = siblingTemorals.indexOf(
|
|
134
|
+
this
|
|
135
|
+
);
|
|
135
136
|
if (ownIndex === 0) {
|
|
136
137
|
return parentTimegroup.startTimeMs;
|
|
137
138
|
}
|