@editframe/elements 0.11.0-beta.1 → 0.11.0-beta.14
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/EF_FRAMEGEN.d.ts +8 -15
- package/dist/elements/EFMedia.d.ts +2 -2
- package/dist/elements/EFTemporal.browsertest.d.ts +10 -0
- package/dist/elements/EFTemporal.d.ts +10 -2
- package/dist/elements/EFTimegroup.browsertest.d.ts +4 -0
- package/dist/elements/EFTimegroup.d.ts +12 -1
- package/dist/elements/EFWaveform.d.ts +3 -3
- package/dist/elements/durationConverter.d.ts +4 -0
- package/dist/elements/src/EF_FRAMEGEN.js +24 -26
- package/dist/elements/src/elements/EFImage.js +3 -7
- package/dist/elements/src/elements/EFMedia.js +27 -9
- package/dist/elements/src/elements/EFTemporal.js +106 -13
- package/dist/elements/src/elements/EFTimegroup.js +26 -5
- package/dist/elements/src/elements/EFVideo.js +7 -7
- package/dist/elements/src/elements/EFWaveform.js +14 -8
- package/dist/elements/src/gui/ContextMixin.js +22 -6
- package/dist/elements/src/gui/EFFilmstrip.js +28 -8
- package/dist/elements/src/gui/EFTogglePlay.js +38 -6
- package/dist/elements/src/gui/EFWorkbench.js +1 -24
- package/dist/elements/src/gui/TWMixin.css.js +1 -1
- package/dist/gui/ContextMixin.d.ts +1 -0
- package/dist/gui/EFFilmstrip.d.ts +4 -4
- package/dist/gui/EFTogglePlay.d.ts +4 -0
- package/dist/gui/EFWorkbench.d.ts +0 -1
- package/dist/style.css +15 -4
- package/package.json +2 -2
- package/src/elements/EFImage.ts +4 -8
- package/src/elements/EFMedia.browsertest.ts +231 -2
- package/src/elements/EFMedia.ts +48 -9
- package/src/elements/EFTemporal.browsertest.ts +79 -0
- package/src/elements/EFTemporal.ts +139 -6
- package/src/elements/EFTimegroup.browsertest.ts +38 -1
- package/src/elements/EFTimegroup.ts +28 -5
- package/src/elements/EFVideo.ts +7 -8
- package/src/elements/EFWaveform.ts +14 -9
- package/src/elements/durationConverter.ts +4 -0
- package/src/gui/ContextMixin.browsertest.ts +28 -2
- package/src/gui/ContextMixin.ts +25 -7
- package/src/gui/EFFilmstrip.ts +37 -17
- package/src/gui/EFTogglePlay.ts +38 -7
- package/src/gui/EFWorkbench.ts +3 -36
package/dist/EF_FRAMEGEN.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ declare global {
|
|
|
3
3
|
interface Window {
|
|
4
4
|
EF_FRAMEGEN?: EfFramegen;
|
|
5
5
|
FRAMEGEN_BRIDGE?: {
|
|
6
|
-
onInitialize: (callback: (
|
|
7
|
-
initialized(
|
|
8
|
-
onBeginFrame(callback: (
|
|
6
|
+
onInitialize: (callback: (renderOptions: VideoRenderOptions) => void) => void;
|
|
7
|
+
initialized(): void;
|
|
8
|
+
onBeginFrame(callback: (frameNumber: number, isLast: boolean) => void): void;
|
|
9
9
|
onTriggerCanvas(callback: () => void): void;
|
|
10
|
-
frameReady(
|
|
11
|
-
error(
|
|
10
|
+
frameReady(frameNumber: number, audioSamples: ArrayBuffer): void;
|
|
11
|
+
error(error: Error): void;
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -25,19 +25,12 @@ export declare class EfFramegen {
|
|
|
25
25
|
audioBufferPromise?: Promise<AudioBuffer>;
|
|
26
26
|
renderOptions?: VideoRenderOptions;
|
|
27
27
|
frameBox: HTMLDivElement;
|
|
28
|
-
BRIDGE:
|
|
29
|
-
onInitialize: (callback: (renderId: string, renderOptions: VideoRenderOptions) => void) => void;
|
|
30
|
-
initialized(renderId: string): void;
|
|
31
|
-
onBeginFrame(callback: (renderId: string, frameNumber: number, isLast: boolean) => void): void;
|
|
32
|
-
onTriggerCanvas(callback: () => void): void;
|
|
33
|
-
frameReady(renderId: string, frameNumber: number, audioSamples: ArrayBuffer): void;
|
|
34
|
-
error(renderId: string, error: Error): void;
|
|
35
|
-
} | undefined;
|
|
28
|
+
BRIDGE: typeof window.FRAMEGEN_BRIDGE;
|
|
36
29
|
triggerCanvas: TriggerCanvas;
|
|
37
30
|
trace(...args: any[]): void;
|
|
38
31
|
constructor();
|
|
39
32
|
connectToBridge(): void;
|
|
40
|
-
initialize(
|
|
41
|
-
beginFrame(
|
|
33
|
+
initialize(renderOptions: VideoRenderOptions): Promise<void>;
|
|
34
|
+
beginFrame(frameNumber: number, isLast: boolean): Promise<string | ArrayBuffer | null | undefined>;
|
|
42
35
|
}
|
|
43
36
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { LitElement, PropertyValueMap } from 'lit';
|
|
2
1
|
import { Task } from '@lit/task';
|
|
2
|
+
import { LitElement, PropertyValueMap } from 'lit';
|
|
3
3
|
import { TrackFragmentIndex, TrackSegment } from '../../../assets/src/index.ts';
|
|
4
|
-
import { MP4File } from '../../../assets/src/MP4File.ts';
|
|
5
4
|
import { VideoAsset } from '../../../assets/src/EncodedAsset.ts';
|
|
5
|
+
import { MP4File } from '../../../assets/src/MP4File.ts';
|
|
6
6
|
import type * as MP4Box from "mp4box";
|
|
7
7
|
export declare const deepGetMediaElements: (element: Element, medias?: EFMedia[]) => EFMedia[];
|
|
8
8
|
declare const EFMedia_base: (new (...args: any[]) => import('./EFSourceMixin.ts').EFSourceMixinInterface) & (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & (new (...args: any[]) => import('./FetchMixin.ts').FetchMixinInterface) & typeof LitElement;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
declare const TestTemporal_base: (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & typeof LitElement;
|
|
3
|
+
declare class TestTemporal extends TestTemporal_base {
|
|
4
|
+
}
|
|
5
|
+
declare global {
|
|
6
|
+
interface HTMLElementTagNameMap {
|
|
7
|
+
"test-temporal": TestTemporal;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export {};
|
|
@@ -8,6 +8,16 @@ export declare class TemporalMixinInterface {
|
|
|
8
8
|
get hasOwnDuration(): boolean;
|
|
9
9
|
get trimStartMs(): number;
|
|
10
10
|
get trimEndMs(): number;
|
|
11
|
+
set trimStartMs(value: number);
|
|
12
|
+
set trimEndMs(value: number);
|
|
13
|
+
set trimstart(value: string);
|
|
14
|
+
set trimend(value: string);
|
|
15
|
+
get sourceInMs(): number;
|
|
16
|
+
get sourceOutMs(): number;
|
|
17
|
+
set sourceInMs(value: number);
|
|
18
|
+
set sourceOutMs(value: number);
|
|
19
|
+
set sourcein(value: string);
|
|
20
|
+
set sourceout(value: string);
|
|
11
21
|
get durationMs(): number;
|
|
12
22
|
get startTimeMs(): number;
|
|
13
23
|
get startTimeWithinParentMs(): number;
|
|
@@ -16,8 +26,6 @@ export declare class TemporalMixinInterface {
|
|
|
16
26
|
get trimAdjustedOwnCurrentTimeMs(): number;
|
|
17
27
|
set duration(value: string);
|
|
18
28
|
get duration(): string;
|
|
19
|
-
set trimstart(value: string);
|
|
20
|
-
set trimend(value: string);
|
|
21
29
|
parentTimegroup?: EFTimegroup;
|
|
22
30
|
rootTimegroup?: EFTimegroup;
|
|
23
31
|
frameTask: Task<readonly unknown[], unknown>;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
+
declare const TestContext_base: (new (...args: any[]) => import('../gui/ContextMixin.ts').ContextMixinInterface) & typeof LitElement;
|
|
3
|
+
declare class TestContext extends TestContext_base {
|
|
4
|
+
}
|
|
2
5
|
declare const TestTemporal_base: (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & typeof LitElement;
|
|
3
6
|
declare class TestTemporal extends TestTemporal_base {
|
|
4
7
|
get hasOwnDuration(): boolean;
|
|
@@ -6,6 +9,7 @@ declare class TestTemporal extends TestTemporal_base {
|
|
|
6
9
|
declare global {
|
|
7
10
|
interface HTMLElementTagNameMap {
|
|
8
11
|
"test-temporal": TestTemporal;
|
|
12
|
+
"test-context": TestContext;
|
|
9
13
|
}
|
|
10
14
|
}
|
|
11
15
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LitElement, PropertyValueMap } from 'lit';
|
|
2
1
|
import { Task } from '@lit/task';
|
|
2
|
+
import { LitElement, PropertyValueMap } from 'lit';
|
|
3
3
|
export declare const shallowGetTimegroups: (element: Element, groups?: EFTimegroup[]) => EFTimegroup[];
|
|
4
4
|
declare const EFTimegroup_base: (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & typeof LitElement;
|
|
5
5
|
export declare class EFTimegroup extends EFTimegroup_base {
|
|
@@ -20,6 +20,17 @@ export declare class EFTimegroup extends EFTimegroup_base {
|
|
|
20
20
|
waitForMediaDurations(): Promise<Record<number, import('../../../assets/src/index.ts').TrackFragmentIndex>[]>;
|
|
21
21
|
get childTemporals(): import('./EFTemporal.ts').TemporalMixinInterface[];
|
|
22
22
|
protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
|
|
23
|
+
get contextProvider(): (ParentNode & import('../gui/ContextMixin.ts').ContextMixinInterface) | null;
|
|
24
|
+
/**
|
|
25
|
+
* Returns true if the timegroup should be wrapped with a workbench.
|
|
26
|
+
*
|
|
27
|
+
* A timegroup should be wrapped with a workbench if it is the root-most timegroup
|
|
28
|
+
* and EF_INTERACTIVE is true.
|
|
29
|
+
*
|
|
30
|
+
* If the timegroup is already wrappedin a context provider like ef-preview,
|
|
31
|
+
* it should NOT be wrapped in a workbench.
|
|
32
|
+
*
|
|
33
|
+
*/
|
|
23
34
|
shouldWrapWithWorkbench(): boolean;
|
|
24
35
|
wrapWithWorkbench(): void;
|
|
25
36
|
get hasOwnDuration(): boolean;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { EFAudio } from './EFAudio.ts';
|
|
2
|
-
import { LitElement } from 'lit';
|
|
3
|
-
import { EFVideo } from './EFVideo.ts';
|
|
4
2
|
import { Task } from '@lit/task';
|
|
3
|
+
import { LitElement } from 'lit';
|
|
5
4
|
import { Ref } from 'lit/directives/ref.js';
|
|
5
|
+
import { EFVideo } from './EFVideo.ts';
|
|
6
6
|
declare const EFWaveform_base: (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & typeof LitElement;
|
|
7
7
|
export declare class EFWaveform extends EFWaveform_base {
|
|
8
|
-
static styles:
|
|
8
|
+
static styles: import('lit').CSSResult[];
|
|
9
9
|
svgRef: Ref<SVGElement>;
|
|
10
10
|
createRenderRoot(): this;
|
|
11
11
|
render(): import('lit-html').TemplateResult<1>;
|
|
@@ -10,3 +10,7 @@ export declare const imageDurationConverter: {
|
|
|
10
10
|
fromAttribute: (value: string) => number;
|
|
11
11
|
toAttribute: (value: number) => string;
|
|
12
12
|
};
|
|
13
|
+
export declare const sourceDurationConverter: {
|
|
14
|
+
fromAttribute: (value: string) => number;
|
|
15
|
+
toAttribute: (value: number) => string;
|
|
16
|
+
};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import debug from "debug";
|
|
2
1
|
import { TaskStatus } from "@lit/task";
|
|
3
2
|
import { deepGetElementsWithFrameTasks } from "./elements/EFTemporal.js";
|
|
4
3
|
import { shallowGetTimegroups } from "./elements/EFTimegroup.js";
|
|
5
|
-
const log = debug("ef:elements:EF_FRAMEGEN");
|
|
6
4
|
class TriggerCanvas {
|
|
7
5
|
constructor() {
|
|
8
6
|
this.canvas = document.createElement("canvas");
|
|
@@ -23,7 +21,7 @@ class TriggerCanvas {
|
|
|
23
21
|
this.ctx.fillStyle = "black";
|
|
24
22
|
}
|
|
25
23
|
trigger() {
|
|
26
|
-
log("TRIGGERING CANVAS");
|
|
24
|
+
console.log("TRIGGERING CANVAS");
|
|
27
25
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
28
26
|
}
|
|
29
27
|
}
|
|
@@ -33,9 +31,10 @@ class EfFramegen {
|
|
|
33
31
|
this.frameDurationMs = 0;
|
|
34
32
|
this.initialBusyTasks = Promise.resolve([]);
|
|
35
33
|
this.frameBox = document.createElement("div");
|
|
36
|
-
this.BRIDGE = window.FRAMEGEN_BRIDGE;
|
|
37
34
|
this.triggerCanvas = new TriggerCanvas();
|
|
35
|
+
this.BRIDGE = window.FRAMEGEN_BRIDGE;
|
|
38
36
|
if (this.BRIDGE) {
|
|
37
|
+
console.log("BRIDGE.constructor (connecting to bridge)");
|
|
39
38
|
this.connectToBridge();
|
|
40
39
|
}
|
|
41
40
|
}
|
|
@@ -47,27 +46,28 @@ class EfFramegen {
|
|
|
47
46
|
if (!BRIDGE) {
|
|
48
47
|
throw new Error("No BRIDGE when attempting to connect to bridge");
|
|
49
48
|
}
|
|
50
|
-
BRIDGE.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
console.log("BRIDGE.connectToBridge");
|
|
50
|
+
BRIDGE.onInitialize(async (renderOptions) => {
|
|
51
|
+
console.log("BRIDGE.onInitialize", renderOptions);
|
|
52
|
+
await this.initialize(renderOptions);
|
|
53
|
+
BRIDGE.initialized();
|
|
54
54
|
});
|
|
55
|
-
BRIDGE.onBeginFrame((
|
|
56
|
-
log("BRIDGE.onBeginFrame",
|
|
57
|
-
this.beginFrame(
|
|
55
|
+
BRIDGE.onBeginFrame((frameNumber, isLast) => {
|
|
56
|
+
console.log("BRIDGE.onBeginFrame", frameNumber, isLast);
|
|
57
|
+
this.beginFrame(frameNumber, isLast);
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
|
-
async initialize(
|
|
60
|
+
async initialize(renderOptions) {
|
|
61
61
|
addEventListener("unhandledrejection", (event) => {
|
|
62
62
|
this.trace("Unhandled rejection:", event.reason);
|
|
63
63
|
if (this.BRIDGE) {
|
|
64
|
-
this.BRIDGE.error(
|
|
64
|
+
this.BRIDGE.error(event.reason);
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
addEventListener("error", (event) => {
|
|
68
68
|
this.trace("Uncaught error", event.error);
|
|
69
69
|
if (this.BRIDGE) {
|
|
70
|
-
this.BRIDGE.error(
|
|
70
|
+
this.BRIDGE.error(event.error);
|
|
71
71
|
}
|
|
72
72
|
});
|
|
73
73
|
this.renderOptions = renderOptions;
|
|
@@ -107,9 +107,9 @@ class EfFramegen {
|
|
|
107
107
|
// renderOptions.encoderOptions.fromMs,
|
|
108
108
|
// renderOptions.encoderOptions.toMs,
|
|
109
109
|
);
|
|
110
|
-
log("Initialized");
|
|
110
|
+
console.log("Initialized");
|
|
111
111
|
}
|
|
112
|
-
async beginFrame(
|
|
112
|
+
async beginFrame(frameNumber, isLast) {
|
|
113
113
|
if (this.renderOptions === void 0) {
|
|
114
114
|
throw new Error("No renderOptions");
|
|
115
115
|
}
|
|
@@ -132,18 +132,20 @@ class EfFramegen {
|
|
|
132
132
|
}
|
|
133
133
|
this.time = this.renderOptions.encoderOptions.fromMs + frameNumber * this.frameDurationMs;
|
|
134
134
|
firstGroup.currentTimeMs = this.time;
|
|
135
|
-
log("Awaiting initialBusyTasks");
|
|
135
|
+
console.log("Awaiting initialBusyTasks");
|
|
136
136
|
await this.initialBusyTasks;
|
|
137
|
-
log("Awaiting microtask");
|
|
137
|
+
console.log("Awaiting microtask");
|
|
138
138
|
await new Promise(queueMicrotask);
|
|
139
|
-
log("Awaiting frame tasks");
|
|
139
|
+
console.log("Awaiting frame tasks");
|
|
140
140
|
const now = performance.now();
|
|
141
141
|
await Promise.all(
|
|
142
142
|
temporals.filter((temporal) => temporal.frameTask.status < TaskStatus.COMPLETE).map((temporal) => {
|
|
143
143
|
return temporal.frameTask;
|
|
144
144
|
}).map((task) => task.taskComplete)
|
|
145
145
|
);
|
|
146
|
-
log(
|
|
146
|
+
console.log(
|
|
147
|
+
`frame:${frameNumber} All tasks complete ${performance.now() - now}ms`
|
|
148
|
+
);
|
|
147
149
|
if (isLast && this.audioBufferPromise) {
|
|
148
150
|
const renderedAudio = await this.audioBufferPromise;
|
|
149
151
|
const channelCount = renderedAudio.numberOfChannels;
|
|
@@ -160,11 +162,7 @@ class EfFramegen {
|
|
|
160
162
|
}
|
|
161
163
|
if (this.BRIDGE) {
|
|
162
164
|
this.triggerCanvas.trigger();
|
|
163
|
-
this.BRIDGE.frameReady(
|
|
164
|
-
renderId,
|
|
165
|
-
frameNumber,
|
|
166
|
-
interleavedSamples.buffer
|
|
167
|
-
);
|
|
165
|
+
this.BRIDGE.frameReady(frameNumber, interleavedSamples.buffer);
|
|
168
166
|
} else {
|
|
169
167
|
const fileReader = new FileReader();
|
|
170
168
|
fileReader.readAsDataURL(new Blob([interleavedSamples.buffer]));
|
|
@@ -177,7 +175,7 @@ class EfFramegen {
|
|
|
177
175
|
} else {
|
|
178
176
|
if (this.BRIDGE) {
|
|
179
177
|
this.triggerCanvas.trigger();
|
|
180
|
-
this.BRIDGE.frameReady(
|
|
178
|
+
this.BRIDGE.frameReady(frameNumber, new ArrayBuffer(0));
|
|
181
179
|
} else {
|
|
182
180
|
const fileReader = new FileReader();
|
|
183
181
|
fileReader.readAsDataURL(new Blob([]));
|
|
@@ -2,10 +2,10 @@ import { Task } from "@lit/task";
|
|
|
2
2
|
import { html, css, LitElement } from "lit";
|
|
3
3
|
import { property, customElement } from "lit/decorators.js";
|
|
4
4
|
import { createRef, ref } from "lit/directives/ref.js";
|
|
5
|
-
import { FetchMixin } from "./FetchMixin.js";
|
|
6
|
-
import { EFSourceMixin } from "./EFSourceMixin.js";
|
|
7
5
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
8
6
|
import { EF_RENDERING } from "../EF_RENDERING.js";
|
|
7
|
+
import { EFSourceMixin } from "./EFSourceMixin.js";
|
|
8
|
+
import { FetchMixin } from "./FetchMixin.js";
|
|
9
9
|
var __defProp = Object.defineProperty;
|
|
10
10
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
11
|
var __typeError = (msg) => {
|
|
@@ -90,11 +90,7 @@ EFImage.styles = [
|
|
|
90
90
|
display: block;
|
|
91
91
|
}
|
|
92
92
|
canvas {
|
|
93
|
-
|
|
94
|
-
width: 100%;
|
|
95
|
-
height: 100%;
|
|
96
|
-
object-fit: fill;
|
|
97
|
-
object-position: center;
|
|
93
|
+
all: inherit
|
|
98
94
|
}
|
|
99
95
|
`
|
|
100
96
|
];
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { css, LitElement } from "lit";
|
|
2
|
-
import { property, state } from "lit/decorators.js";
|
|
3
|
-
import { deepArrayEquals } from "@lit/task/deep-equals.js";
|
|
4
|
-
import { Task } from "@lit/task";
|
|
5
1
|
import { consume } from "@lit/context";
|
|
2
|
+
import { Task } from "@lit/task";
|
|
3
|
+
import { deepArrayEquals } from "@lit/task/deep-equals.js";
|
|
6
4
|
import debug from "debug";
|
|
7
|
-
import {
|
|
5
|
+
import { css, LitElement } from "lit";
|
|
6
|
+
import { property, state } from "lit/decorators.js";
|
|
8
7
|
import { VideoAsset } from "../../../assets/src/EncodedAsset.js";
|
|
8
|
+
import { MP4File } from "../../../assets/src/MP4File.js";
|
|
9
|
+
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
10
|
+
import { EF_RENDERING } from "../EF_RENDERING.js";
|
|
11
|
+
import { apiHostContext } from "../gui/apiHostContext.js";
|
|
12
|
+
import { EFSourceMixin } from "./EFSourceMixin.js";
|
|
9
13
|
import { EFTemporal } from "./EFTemporal.js";
|
|
10
14
|
import { FetchMixin } from "./FetchMixin.js";
|
|
11
|
-
import { EFSourceMixin } from "./EFSourceMixin.js";
|
|
12
15
|
import { getStartTimeMs } from "./util.js";
|
|
13
|
-
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
14
|
-
import { apiHostContext } from "../gui/apiHostContext.js";
|
|
15
|
-
import { EF_RENDERING } from "../EF_RENDERING.js";
|
|
16
16
|
var __defProp = Object.defineProperty;
|
|
17
17
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
18
18
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -291,6 +291,18 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
291
291
|
if (durations.length === 0) {
|
|
292
292
|
return 0;
|
|
293
293
|
}
|
|
294
|
+
if (this.sourceInMs && this.sourceOutMs && this.sourceOutMs > this.sourceInMs) {
|
|
295
|
+
return Math.max(this.sourceOutMs - this.sourceInMs);
|
|
296
|
+
}
|
|
297
|
+
if (this.sourceInMs) {
|
|
298
|
+
return Math.max(...durations) - this.trimStartMs - this.trimEndMs - this.sourceInMs;
|
|
299
|
+
}
|
|
300
|
+
if (this.sourceOutMs) {
|
|
301
|
+
return Math.max(...durations) - this.trimStartMs - this.trimEndMs - this.sourceOutMs;
|
|
302
|
+
}
|
|
303
|
+
if (this.sourceInMs && this.sourceOutMs) {
|
|
304
|
+
return Math.max(...durations) - this.trimStartMs - this.trimEndMs - this.sourceOutMs - this.sourceInMs;
|
|
305
|
+
}
|
|
294
306
|
return Math.max(...durations) - this.trimStartMs - this.trimEndMs;
|
|
295
307
|
}
|
|
296
308
|
get startTimeMs() {
|
|
@@ -298,6 +310,12 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
298
310
|
}
|
|
299
311
|
#audioContext;
|
|
300
312
|
async fetchAudioSpanningTime(fromMs, toMs) {
|
|
313
|
+
if (this.sourceInMs) {
|
|
314
|
+
fromMs -= this.startTimeMs - this.trimStartMs - this.sourceInMs;
|
|
315
|
+
}
|
|
316
|
+
if (this.sourceOutMs) {
|
|
317
|
+
toMs -= this.startTimeMs - this.trimStartMs - this.sourceOutMs;
|
|
318
|
+
}
|
|
301
319
|
fromMs -= this.startTimeMs - this.trimStartMs;
|
|
302
320
|
toMs -= this.startTimeMs - this.trimStartMs;
|
|
303
321
|
await this.trackFragmentIndexLoader.taskComplete;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createContext, consume } from "@lit/context";
|
|
2
2
|
import { property, state } from "lit/decorators.js";
|
|
3
|
-
import { durationConverter } from "./durationConverter.js";
|
|
4
3
|
import { Task } from "@lit/task";
|
|
5
4
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
5
|
+
import { durationConverter } from "./durationConverter.js";
|
|
6
6
|
var __defProp = Object.defineProperty;
|
|
7
7
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
8
8
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -18,15 +18,6 @@ const timegroupContext = createContext(
|
|
|
18
18
|
);
|
|
19
19
|
const isEFTemporal = (obj) => obj[EF_TEMPORAL];
|
|
20
20
|
const EF_TEMPORAL = Symbol("EF_TEMPORAL");
|
|
21
|
-
const deepGetTemporalElements = (element, temporals = []) => {
|
|
22
|
-
for (const child of element.children) {
|
|
23
|
-
if (isEFTemporal(child)) {
|
|
24
|
-
temporals.push(child);
|
|
25
|
-
}
|
|
26
|
-
deepGetTemporalElements(child, temporals);
|
|
27
|
-
}
|
|
28
|
-
return temporals;
|
|
29
|
-
};
|
|
30
21
|
const deepGetElementsWithFrameTasks = (element, elements = []) => {
|
|
31
22
|
for (const child of element.children) {
|
|
32
23
|
if ("frameTask" in child && child.frameTask instanceof Task) {
|
|
@@ -115,12 +106,84 @@ const EFTemporal = (superClass) => {
|
|
|
115
106
|
get parentTimegroup() {
|
|
116
107
|
return this.#parentTimegroup;
|
|
117
108
|
}
|
|
109
|
+
set duration(value) {
|
|
110
|
+
if (value !== void 0) {
|
|
111
|
+
this.setAttribute("duration", value);
|
|
112
|
+
} else {
|
|
113
|
+
this.removeAttribute("duration");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
118
116
|
get trimStartMs() {
|
|
119
117
|
return this._trimStartMs;
|
|
120
118
|
}
|
|
119
|
+
set trimStartMs(value) {
|
|
120
|
+
if (this._trimStartMs === value) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this._trimStartMs = value;
|
|
124
|
+
this.setAttribute(
|
|
125
|
+
"trimstart",
|
|
126
|
+
durationConverter.toAttribute(value / 1e3)
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
set trimstart(value) {
|
|
130
|
+
if (value !== void 0) {
|
|
131
|
+
this.setAttribute("trimstart", value);
|
|
132
|
+
} else {
|
|
133
|
+
this.removeAttribute("trimstart");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
121
136
|
get trimEndMs() {
|
|
122
137
|
return this._trimEndMs;
|
|
123
138
|
}
|
|
139
|
+
set trimEndMs(value) {
|
|
140
|
+
if (this._trimEndMs === value) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
this._trimEndMs = value;
|
|
144
|
+
this.setAttribute("trimend", durationConverter.toAttribute(value / 1e3));
|
|
145
|
+
}
|
|
146
|
+
set trimend(value) {
|
|
147
|
+
if (value !== void 0) {
|
|
148
|
+
this.setAttribute("trimend", value);
|
|
149
|
+
} else {
|
|
150
|
+
this.removeAttribute("trimend");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
get sourceInMs() {
|
|
154
|
+
return this._sourceInMs;
|
|
155
|
+
}
|
|
156
|
+
set sourceInMs(value) {
|
|
157
|
+
this._sourceInMs = value;
|
|
158
|
+
value !== void 0 ? this.setAttribute(
|
|
159
|
+
"sourcein",
|
|
160
|
+
durationConverter.toAttribute(value / 1e3)
|
|
161
|
+
) : this.removeAttribute("sourcein");
|
|
162
|
+
}
|
|
163
|
+
set sourcein(value) {
|
|
164
|
+
if (value !== void 0) {
|
|
165
|
+
this.setAttribute("sourcein", value);
|
|
166
|
+
} else {
|
|
167
|
+
this.removeAttribute("sourcein");
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
get sourceOutMs() {
|
|
171
|
+
return this._sourceOutMs;
|
|
172
|
+
}
|
|
173
|
+
set sourceOutMs(value) {
|
|
174
|
+
this._sourceOutMs = value;
|
|
175
|
+
value !== void 0 ? this.setAttribute(
|
|
176
|
+
"sourceout",
|
|
177
|
+
durationConverter.toAttribute(value / 1e3)
|
|
178
|
+
) : this.removeAttribute("sourceout");
|
|
179
|
+
}
|
|
180
|
+
set sourceout(value) {
|
|
181
|
+
if (value !== void 0) {
|
|
182
|
+
this.setAttribute("sourceout", value);
|
|
183
|
+
} else {
|
|
184
|
+
this.removeAttribute("sourceout");
|
|
185
|
+
}
|
|
186
|
+
}
|
|
124
187
|
get startOffsetMs() {
|
|
125
188
|
return this._startOffsetMs;
|
|
126
189
|
}
|
|
@@ -137,6 +200,12 @@ const EFTemporal = (superClass) => {
|
|
|
137
200
|
// Defining this as a getter to a private property allows us to
|
|
138
201
|
// override it classes that include this mixin.
|
|
139
202
|
get durationMs() {
|
|
203
|
+
if (this.sourceInMs) {
|
|
204
|
+
return this._durationMs || this.parentTimegroup?.durationMs || 0 - this.sourceInMs;
|
|
205
|
+
}
|
|
206
|
+
if (this.sourceOutMs) {
|
|
207
|
+
return this._durationMs || this.parentTimegroup?.durationMs || 0 - this.sourceOutMs;
|
|
208
|
+
}
|
|
140
209
|
return this._durationMs || this.parentTimegroup?.durationMs || 0;
|
|
141
210
|
}
|
|
142
211
|
get offsetMs() {
|
|
@@ -214,6 +283,15 @@ const EFTemporal = (superClass) => {
|
|
|
214
283
|
*/
|
|
215
284
|
get trimAdjustedOwnCurrentTimeMs() {
|
|
216
285
|
if (this.rootTimegroup) {
|
|
286
|
+
if (this.sourceInMs && this.sourceOutMs) {
|
|
287
|
+
return Math.min(
|
|
288
|
+
Math.max(
|
|
289
|
+
0,
|
|
290
|
+
this.rootTimegroup.currentTimeMs - this.startTimeMs + this.trimStartMs + this.sourceInMs
|
|
291
|
+
),
|
|
292
|
+
this.durationMs + Math.abs(this.startOffsetMs) + this.trimStartMs + this.sourceInMs
|
|
293
|
+
);
|
|
294
|
+
}
|
|
217
295
|
return Math.min(
|
|
218
296
|
Math.max(
|
|
219
297
|
0,
|
|
@@ -249,14 +327,30 @@ const EFTemporal = (superClass) => {
|
|
|
249
327
|
attribute: "trimstart",
|
|
250
328
|
converter: durationConverter
|
|
251
329
|
})
|
|
252
|
-
], TemporalMixinClass.prototype, "
|
|
330
|
+
], TemporalMixinClass.prototype, "trimStartMs", 1);
|
|
253
331
|
__decorateClass([
|
|
254
332
|
property({
|
|
255
333
|
type: Number,
|
|
256
334
|
attribute: "trimend",
|
|
257
335
|
converter: durationConverter
|
|
258
336
|
})
|
|
259
|
-
], TemporalMixinClass.prototype, "
|
|
337
|
+
], TemporalMixinClass.prototype, "trimEndMs", 1);
|
|
338
|
+
__decorateClass([
|
|
339
|
+
property({
|
|
340
|
+
type: Number,
|
|
341
|
+
attribute: "sourcein",
|
|
342
|
+
converter: durationConverter,
|
|
343
|
+
reflect: true
|
|
344
|
+
})
|
|
345
|
+
], TemporalMixinClass.prototype, "sourceInMs", 1);
|
|
346
|
+
__decorateClass([
|
|
347
|
+
property({
|
|
348
|
+
type: Number,
|
|
349
|
+
attribute: "sourceout",
|
|
350
|
+
converter: durationConverter,
|
|
351
|
+
reflect: true
|
|
352
|
+
})
|
|
353
|
+
], TemporalMixinClass.prototype, "sourceOutMs", 1);
|
|
260
354
|
__decorateClass([
|
|
261
355
|
property({
|
|
262
356
|
type: Number,
|
|
@@ -276,7 +370,6 @@ export {
|
|
|
276
370
|
EFTemporal,
|
|
277
371
|
OwnCurrentTimeController,
|
|
278
372
|
deepGetElementsWithFrameTasks,
|
|
279
|
-
deepGetTemporalElements,
|
|
280
373
|
isEFTemporal,
|
|
281
374
|
shallowGetTemporalElements,
|
|
282
375
|
timegroupContext
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { html, css, LitElement } from "lit";
|
|
2
1
|
import { provide } from "@lit/context";
|
|
3
2
|
import { Task } from "@lit/task";
|
|
4
|
-
import { property, customElement } from "lit/decorators.js";
|
|
5
3
|
import debug from "debug";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { html, css, LitElement } from "lit";
|
|
5
|
+
import { property, customElement } from "lit/decorators.js";
|
|
8
6
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
7
|
+
import { isContextMixin } from "../gui/ContextMixin.js";
|
|
9
8
|
import { deepGetMediaElements } from "./EFMedia.js";
|
|
9
|
+
import { EFTemporal, shallowGetTemporalElements, isEFTemporal, timegroupContext } from "./EFTemporal.js";
|
|
10
|
+
import { TimegroupController } from "./TimegroupController.js";
|
|
10
11
|
import { durationConverter } from "./durationConverter.js";
|
|
11
12
|
var __defProp = Object.defineProperty;
|
|
12
13
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -212,8 +213,28 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
|
|
|
212
213
|
}
|
|
213
214
|
}
|
|
214
215
|
}
|
|
216
|
+
get contextProvider() {
|
|
217
|
+
let parent = this.parentNode;
|
|
218
|
+
while (parent) {
|
|
219
|
+
if (isContextMixin(parent)) {
|
|
220
|
+
return parent;
|
|
221
|
+
}
|
|
222
|
+
parent = parent.parentNode;
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Returns true if the timegroup should be wrapped with a workbench.
|
|
228
|
+
*
|
|
229
|
+
* A timegroup should be wrapped with a workbench if it is the root-most timegroup
|
|
230
|
+
* and EF_INTERACTIVE is true.
|
|
231
|
+
*
|
|
232
|
+
* If the timegroup is already wrappedin a context provider like ef-preview,
|
|
233
|
+
* it should NOT be wrapped in a workbench.
|
|
234
|
+
*
|
|
235
|
+
*/
|
|
215
236
|
shouldWrapWithWorkbench() {
|
|
216
|
-
return EF_INTERACTIVE && this.closest("ef-timegroup") === this && this.closest("ef-
|
|
237
|
+
return EF_INTERACTIVE && this.closest("ef-timegroup") === this && this.closest("ef-preview") === null && this.closest("ef-workbench") === null && this.closest("test-context") === null;
|
|
217
238
|
}
|
|
218
239
|
wrapWithWorkbench() {
|
|
219
240
|
const workbench = document.createElement("ef-workbench");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { css, html } from "lit";
|
|
2
1
|
import { Task } from "@lit/task";
|
|
3
|
-
import {
|
|
2
|
+
import { css, html } from "lit";
|
|
4
3
|
import { customElement } from "lit/decorators.js";
|
|
5
|
-
import {
|
|
4
|
+
import { createRef, ref } from "lit/directives/ref.js";
|
|
6
5
|
import { TWMixin } from "../gui/TWMixin.js";
|
|
6
|
+
import { EFMedia } from "./EFMedia.js";
|
|
7
7
|
var __defProp = Object.defineProperty;
|
|
8
8
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
9
|
var __typeError = (msg) => {
|
|
@@ -85,10 +85,7 @@ let EFVideo = class extends TWMixin(EFMedia) {
|
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
87
|
render() {
|
|
88
|
-
return html` <canvas
|
|
89
|
-
class="h-full w-full object-fill"
|
|
90
|
-
${ref(this.canvasRef)}
|
|
91
|
-
></canvas>`;
|
|
88
|
+
return html` <canvas ${ref(this.canvasRef)}></canvas>`;
|
|
92
89
|
}
|
|
93
90
|
get canvasElement() {
|
|
94
91
|
return this.canvasRef.value;
|
|
@@ -100,6 +97,9 @@ EFVideo.styles = [
|
|
|
100
97
|
:host {
|
|
101
98
|
display: block;
|
|
102
99
|
}
|
|
100
|
+
canvas {
|
|
101
|
+
all: inherit;
|
|
102
|
+
}
|
|
103
103
|
`
|
|
104
104
|
];
|
|
105
105
|
EFVideo = __decorateClass([
|