@editframe/elements 0.5.0-beta.8 → 0.6.0-beta.1
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 +561 -0
- package/dist/{editor/util/EncodedAsset/EncodedAsset.mjs → lib/av/EncodedAsset.js} +40 -33
- package/dist/lib/av/MP4File.cjs +182 -0
- package/dist/{editor/util/MP4File.mjs → lib/av/MP4File.js} +55 -51
- package/dist/lib/av/msToTimeCode.cjs +15 -0
- package/dist/lib/util/awaitMicrotask.cjs +8 -0
- package/dist/lib/util/memoize.cjs +14 -0
- package/dist/{util/memoize.mjs → lib/util/memoize.js} +1 -2
- package/dist/packages/elements/src/EF_FRAMEGEN.cjs +197 -0
- package/dist/packages/elements/src/EF_FRAMEGEN.d.ts +45 -0
- package/dist/packages/elements/src/EF_FRAMEGEN.js +197 -0
- package/dist/packages/elements/src/EF_INTERACTIVE.cjs +4 -0
- package/dist/packages/elements/src/EF_INTERACTIVE.d.ts +1 -0
- package/dist/packages/elements/src/elements/CrossUpdateController.cjs +16 -0
- package/dist/packages/elements/src/elements/CrossUpdateController.d.ts +9 -0
- package/dist/packages/elements/src/elements/EFAudio.cjs +53 -0
- package/dist/packages/elements/src/elements/EFAudio.d.ts +10 -0
- package/dist/{elements/src/elements/EFAudio.mjs → packages/elements/src/elements/EFAudio.js} +2 -5
- package/dist/packages/elements/src/elements/EFCaptions.cjs +171 -0
- package/dist/packages/elements/src/elements/EFCaptions.d.ts +39 -0
- package/dist/{elements/src/elements/EFCaptions.mjs → packages/elements/src/elements/EFCaptions.js} +18 -20
- package/dist/packages/elements/src/elements/EFImage.cjs +79 -0
- package/dist/packages/elements/src/elements/EFImage.d.ts +14 -0
- package/dist/{elements/src/elements/EFImage.mjs → packages/elements/src/elements/EFImage.js} +8 -7
- package/dist/packages/elements/src/elements/EFMedia.cjs +334 -0
- package/dist/packages/elements/src/elements/EFMedia.d.ts +61 -0
- package/dist/{elements/src/elements/EFMedia.mjs → packages/elements/src/elements/EFMedia.js} +40 -38
- package/dist/packages/elements/src/elements/EFSourceMixin.cjs +55 -0
- package/dist/packages/elements/src/elements/EFSourceMixin.d.ts +12 -0
- package/dist/{elements/src/elements/EFSourceMixin.mjs → packages/elements/src/elements/EFSourceMixin.js} +6 -8
- package/dist/packages/elements/src/elements/EFTemporal.cjs +198 -0
- package/dist/packages/elements/src/elements/EFTemporal.d.ts +36 -0
- package/dist/{elements/src/elements/EFTemporal.mjs → packages/elements/src/elements/EFTemporal.js} +6 -22
- package/dist/packages/elements/src/elements/EFTimegroup.browsertest.d.ts +12 -0
- package/{src/elements/EFTimegroup.ts → dist/packages/elements/src/elements/EFTimegroup.cjs} +162 -213
- package/dist/packages/elements/src/elements/EFTimegroup.d.ts +39 -0
- package/dist/{elements/src/elements/EFTimegroup.mjs → packages/elements/src/elements/EFTimegroup.js} +55 -65
- package/{src/elements/EFTimeline.ts → dist/packages/elements/src/elements/EFTimeline.cjs} +5 -3
- package/dist/packages/elements/src/elements/EFTimeline.d.ts +3 -0
- package/dist/{elements/src/elements/EFTimeline.mjs → packages/elements/src/elements/EFTimeline.js} +5 -2
- package/dist/packages/elements/src/elements/EFVideo.cjs +110 -0
- package/dist/packages/elements/src/elements/EFVideo.d.ts +14 -0
- package/dist/{elements/src/elements/EFVideo.mjs → packages/elements/src/elements/EFVideo.js} +10 -32
- package/dist/packages/elements/src/elements/EFWaveform.cjs +235 -0
- package/dist/packages/elements/src/elements/EFWaveform.d.ts +28 -0
- package/dist/{elements/src/elements/EFWaveform.mjs → packages/elements/src/elements/EFWaveform.js} +15 -16
- package/dist/packages/elements/src/elements/FetchMixin.cjs +28 -0
- package/dist/packages/elements/src/elements/FetchMixin.d.ts +8 -0
- package/dist/{elements/src/elements/FetchMixin.mjs → packages/elements/src/elements/FetchMixin.js} +5 -7
- package/dist/packages/elements/src/elements/TimegroupController.cjs +20 -0
- package/dist/packages/elements/src/elements/TimegroupController.d.ts +14 -0
- package/dist/packages/elements/src/elements/durationConverter.cjs +8 -0
- package/dist/packages/elements/src/elements/durationConverter.d.ts +4 -0
- package/dist/{elements/src/elements/durationConverter.mjs → packages/elements/src/elements/durationConverter.js} +1 -1
- package/dist/packages/elements/src/elements/parseTimeToMs.cjs +12 -0
- package/dist/packages/elements/src/elements/parseTimeToMs.d.ts +1 -0
- package/dist/packages/elements/src/elements/parseTimeToMs.js +12 -0
- package/dist/packages/elements/src/elements/util.cjs +11 -0
- package/dist/packages/elements/src/elements/util.d.ts +4 -0
- package/dist/{elements/src/elements/util.mjs → packages/elements/src/elements/util.js} +1 -1
- package/dist/packages/elements/src/gui/EFFilmstrip.cjs +675 -0
- package/dist/packages/elements/src/gui/EFFilmstrip.d.ts +138 -0
- package/dist/{elements/src/gui/EFFilmstrip.mjs → packages/elements/src/gui/EFFilmstrip.js} +57 -55
- package/dist/packages/elements/src/gui/EFWorkbench.cjs +199 -0
- package/dist/packages/elements/src/gui/EFWorkbench.d.ts +44 -0
- package/dist/{elements/src/gui/EFWorkbench.mjs → packages/elements/src/gui/EFWorkbench.js} +27 -49
- package/{src/gui/TWMixin.ts → dist/packages/elements/src/gui/TWMixin.cjs} +11 -10
- package/dist/packages/elements/src/gui/TWMixin.css.cjs +3 -0
- package/dist/packages/elements/src/gui/TWMixin.css.js +4 -0
- package/dist/packages/elements/src/gui/TWMixin.d.ts +3 -0
- package/dist/{elements/src/gui/TWMixin.mjs → packages/elements/src/gui/TWMixin.js} +4 -3
- package/dist/packages/elements/src/index.cjs +47 -0
- package/dist/packages/elements/src/index.d.ts +10 -0
- package/dist/packages/elements/src/index.js +23 -0
- package/dist/style.css +13 -4
- package/package.json +23 -4
- package/dist/elements/src/EF_FRAMEGEN.mjs +0 -130
- package/dist/elements/src/elements/parseTimeToMs.mjs +0 -13
- package/dist/elements/src/elements.mjs +0 -12
- package/dist/elements/src/gui/TWMixin.css.mjs +0 -4
- package/dist/util/awaitAnimationFrame.mjs +0 -11
- package/docker-compose.yaml +0 -17
- package/src/EF_FRAMEGEN.ts +0 -208
- package/src/EF_INTERACTIVE.ts +0 -2
- package/src/elements/CrossUpdateController.ts +0 -18
- package/src/elements/EFAudio.ts +0 -42
- package/src/elements/EFCaptions.ts +0 -202
- package/src/elements/EFImage.ts +0 -70
- package/src/elements/EFMedia.ts +0 -395
- package/src/elements/EFSourceMixin.ts +0 -57
- package/src/elements/EFTemporal.ts +0 -246
- package/src/elements/EFTimegroup.browsertest.ts +0 -360
- package/src/elements/EFVideo.ts +0 -114
- package/src/elements/EFWaveform.ts +0 -407
- package/src/elements/FetchMixin.ts +0 -18
- package/src/elements/TimegroupController.ts +0 -25
- package/src/elements/buildLitFixture.ts +0 -13
- package/src/elements/durationConverter.ts +0 -6
- package/src/elements/parseTimeToMs.ts +0 -10
- package/src/elements/util.ts +0 -24
- package/src/gui/EFFilmstrip.ts +0 -702
- package/src/gui/EFWorkbench.ts +0 -242
- package/src/gui/TWMixin.css +0 -3
- package/src/util.d.ts +0 -1
- /package/dist/{editor/msToTimeCode.mjs → lib/av/msToTimeCode.js} +0 -0
- /package/dist/{util/awaitMicrotask.mjs → lib/util/awaitMicrotask.js} +0 -0
- /package/dist/{elements/src/EF_INTERACTIVE.mjs → packages/elements/src/EF_INTERACTIVE.js} +0 -0
- /package/dist/{elements/src/elements/CrossUpdateController.mjs → packages/elements/src/elements/CrossUpdateController.js} +0 -0
- /package/dist/{elements/src/elements/TimegroupController.mjs → packages/elements/src/elements/TimegroupController.js} +0 -0
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
import { LitElement, render, html } from "lit";
|
|
2
|
-
import { customElement } from "lit/decorators.js";
|
|
3
|
-
import { describe, test, assert, beforeEach } from "vitest";
|
|
4
|
-
import "./EFTimegroup";
|
|
5
|
-
import { EFTimegroup } from "./EFTimegroup";
|
|
6
|
-
import { EFTemporal } from "./EFTemporal";
|
|
7
|
-
import { buildLitFixture } from "./buildLitFixture";
|
|
8
|
-
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
11
|
-
localStorage.removeItem(localStorage.key(i)!);
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
@customElement("test-temporal")
|
|
16
|
-
class TestTemporal extends EFTemporal(LitElement) {
|
|
17
|
-
get hasOwnDuration(): boolean {
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
declare global {
|
|
23
|
-
interface HTMLElementTagNameMap {
|
|
24
|
-
"test-temporal": TestTemporal;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const litTest = test.extend<{
|
|
29
|
-
container: HTMLDivElement;
|
|
30
|
-
timegroup: EFTimegroup;
|
|
31
|
-
containTimegroup: EFTimegroup;
|
|
32
|
-
sequenceTimegroup: EFTimegroup;
|
|
33
|
-
fixedTimegroup: EFTimegroup;
|
|
34
|
-
tenSecondTimegroup: EFTimegroup;
|
|
35
|
-
}>({
|
|
36
|
-
container: async ({}, use) => {
|
|
37
|
-
const container = document.createElement("div");
|
|
38
|
-
document.body.appendChild(container);
|
|
39
|
-
await use(container);
|
|
40
|
-
document.body.removeChild(container);
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
timegroup: buildLitFixture<EFTimegroup>(html`<ef-timegroup></ef-timegroup>`),
|
|
44
|
-
containTimegroup: buildLitFixture<EFTimegroup>(
|
|
45
|
-
html`<ef-timegroup mode="contain"></ef-timegroup>`,
|
|
46
|
-
),
|
|
47
|
-
sequenceTimegroup: buildLitFixture<EFTimegroup>(
|
|
48
|
-
html`<ef-timegroup mode="sequence"></ef-timegroup>`,
|
|
49
|
-
),
|
|
50
|
-
fixedTimegroup: buildLitFixture<EFTimegroup>(
|
|
51
|
-
html`<ef-timegroup mode="fixed"></ef-timegroup>`,
|
|
52
|
-
),
|
|
53
|
-
tenSecondTimegroup: buildLitFixture<EFTimegroup>(
|
|
54
|
-
html`<ef-timegroup id="ten-second" duration="10s"></ef-timegroup>`,
|
|
55
|
-
),
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe(`<ef-timegroup mode="fixed">`, () => {
|
|
59
|
-
litTest(
|
|
60
|
-
"can explicitly set a duration in seconds",
|
|
61
|
-
async ({ fixedTimegroup: timegroup }) => {
|
|
62
|
-
timegroup.setAttribute("duration", "10s");
|
|
63
|
-
assert.equal(timegroup.durationMs, 10_000);
|
|
64
|
-
},
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
litTest(
|
|
68
|
-
"can explicitly set a duration in milliseconds",
|
|
69
|
-
async ({ fixedTimegroup: timegroup }) => {
|
|
70
|
-
timegroup.setAttribute("duration", "10ms");
|
|
71
|
-
assert.equal(timegroup.durationMs, 10);
|
|
72
|
-
},
|
|
73
|
-
);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
describe(`<ef-timegroup mode="sequence">`, () => {
|
|
77
|
-
litTest("fixed duration is ignored", ({ sequenceTimegroup: timegroup }) => {
|
|
78
|
-
timegroup.setAttribute("duration", "10s");
|
|
79
|
-
assert.equal(timegroup.durationMs, 0);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
litTest(
|
|
83
|
-
"duration is the sum of child time groups",
|
|
84
|
-
async ({ sequenceTimegroup: timegroup }) => {
|
|
85
|
-
render(
|
|
86
|
-
html`
|
|
87
|
-
<ef-timegroup mode="fixed" duration="5s"></ef-timegroup>
|
|
88
|
-
<ef-timegroup mode="fixed" duration="5s"></ef-timegroup>
|
|
89
|
-
`,
|
|
90
|
-
timegroup,
|
|
91
|
-
);
|
|
92
|
-
await timegroup.updateComplete;
|
|
93
|
-
assert.equal(timegroup.durationMs, 10_000);
|
|
94
|
-
},
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
litTest(
|
|
98
|
-
"duration can include any element with a durationMs value",
|
|
99
|
-
async ({ sequenceTimegroup: TimeGroup }) => {
|
|
100
|
-
render(
|
|
101
|
-
html`
|
|
102
|
-
<ef-timegroup mode="fixed" duration="5s"></ef-timegroup>
|
|
103
|
-
<test-temporal duration="5s"></test-temporal>
|
|
104
|
-
`,
|
|
105
|
-
TimeGroup,
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
assert.equal(TimeGroup.durationMs, 10_000);
|
|
109
|
-
},
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
litTest("arbitrary html is ignored", ({ sequenceTimegroup: timegroup }) => {
|
|
113
|
-
render(
|
|
114
|
-
html`
|
|
115
|
-
<div>
|
|
116
|
-
<ef-timegroup mode="fixed" duration="5s"></ef-timegroup>
|
|
117
|
-
</div>
|
|
118
|
-
`,
|
|
119
|
-
timegroup,
|
|
120
|
-
);
|
|
121
|
-
assert.equal(timegroup.durationMs, 5_000);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
litTest(
|
|
125
|
-
"nested time groups are ignored",
|
|
126
|
-
async ({ sequenceTimegroup: timegroup }) => {
|
|
127
|
-
render(
|
|
128
|
-
html`
|
|
129
|
-
<ef-timegroup mode="fixed" duration="5s">
|
|
130
|
-
<ef-timegroup mode="fixed" duration="5s"></ef-timegroup>
|
|
131
|
-
</ef-timegroup>
|
|
132
|
-
`,
|
|
133
|
-
timegroup,
|
|
134
|
-
);
|
|
135
|
-
await timegroup.updateComplete;
|
|
136
|
-
assert.equal(timegroup.durationMs, 5_000);
|
|
137
|
-
},
|
|
138
|
-
);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe(`<ef-timegroup mode="contain">`, () => {
|
|
142
|
-
litTest("fixed duration is ignored", ({ containTimegroup: timegroup }) => {
|
|
143
|
-
timegroup.setAttribute("duration", "10s");
|
|
144
|
-
assert.equal(timegroup.durationMs, 0);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
litTest(
|
|
148
|
-
"duration is the max of child time groups",
|
|
149
|
-
async ({ containTimegroup: timegroup }) => {
|
|
150
|
-
render(
|
|
151
|
-
html`
|
|
152
|
-
<ef-timegroup mode="fixed" duration="5s"></ef-timegroup>
|
|
153
|
-
<ef-timegroup mode="fixed" duration="10s"></ef-timegroup>
|
|
154
|
-
`,
|
|
155
|
-
timegroup,
|
|
156
|
-
);
|
|
157
|
-
await timegroup.updateComplete;
|
|
158
|
-
assert.equal(timegroup.durationMs, 10_000);
|
|
159
|
-
},
|
|
160
|
-
);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe("startTimeMs", () => {
|
|
164
|
-
litTest(
|
|
165
|
-
"is computed relative to the root time group",
|
|
166
|
-
async ({ container }) => {
|
|
167
|
-
render(
|
|
168
|
-
html`<ef-timegroup id="root" mode="sequence">
|
|
169
|
-
<ef-timegroup id="a" mode="fixed" duration="5s"></ef-timegroup>
|
|
170
|
-
<ef-timegroup id="b" mode="sequence">
|
|
171
|
-
<ef-timegroup id="c" mode="fixed" duration="5s"></ef-timegroup>
|
|
172
|
-
<ef-timegroup id="d" mode="contain">
|
|
173
|
-
<ef-timegroup id="e" mode="fixed" duration="5s"></ef-timegroup>
|
|
174
|
-
<ef-timegroup id="f" mode="fixed" duration="5s"></ef-timegroup>
|
|
175
|
-
</ef-timegroup>
|
|
176
|
-
</ef-timegroup>
|
|
177
|
-
</ef-timegroup>`,
|
|
178
|
-
container,
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
const a = container.querySelector("#a") as EFTimegroup;
|
|
182
|
-
const b = container.querySelector("#b") as EFTimegroup;
|
|
183
|
-
const c = container.querySelector("#c") as EFTimegroup;
|
|
184
|
-
const d = container.querySelector("#d") as EFTimegroup;
|
|
185
|
-
const e = container.querySelector("#e") as EFTimegroup;
|
|
186
|
-
const f = container.querySelector("#f") as EFTimegroup;
|
|
187
|
-
|
|
188
|
-
assert.equal(a.startTimeMs, 0);
|
|
189
|
-
assert.equal(b.startTimeMs, 5_000);
|
|
190
|
-
assert.equal(c.startTimeMs, 5_000);
|
|
191
|
-
assert.equal(d.startTimeMs, 10_000);
|
|
192
|
-
assert.equal(e.startTimeMs, 10_000);
|
|
193
|
-
assert.equal(f.startTimeMs, 10_000);
|
|
194
|
-
},
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
// TODO: Rethink offset math, it shouldn't effect the duration of a temporal item
|
|
198
|
-
// but actually change the start and end time.
|
|
199
|
-
litTest.skip("can be offset with offset attribute", async ({ container }) => {
|
|
200
|
-
render(
|
|
201
|
-
html`<ef-timegroup id="root" mode="contain">
|
|
202
|
-
<test-temporal id="a" duration="5s" offset="5s"></test-temporal>
|
|
203
|
-
</ef-timegroup> `,
|
|
204
|
-
container,
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
const root = container.querySelector("#root") as EFTimegroup;
|
|
208
|
-
const a = container.querySelector("#a") as TestTemporal;
|
|
209
|
-
|
|
210
|
-
assert.equal(a.durationMs, 5_000);
|
|
211
|
-
assert.equal(root.durationMs, 10_000);
|
|
212
|
-
assert.equal(a.startTimeMs, 5_000);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
litTest.skip(
|
|
216
|
-
"offsets do not affect start time when in a sequence group",
|
|
217
|
-
async ({ container }) => {
|
|
218
|
-
render(
|
|
219
|
-
html`<ef-timegroup id="root" mode="sequence">
|
|
220
|
-
<test-temporal id="a" duration="5s"></test-temporal>
|
|
221
|
-
<test-temporal id="b" duration="5s" offset="5s"></test-temporal>
|
|
222
|
-
</ef-timegroup> `,
|
|
223
|
-
container,
|
|
224
|
-
);
|
|
225
|
-
|
|
226
|
-
const root = container.querySelector("#root") as EFTimegroup;
|
|
227
|
-
const a = container.querySelector("#a") as TestTemporal;
|
|
228
|
-
const b = container.querySelector("#b") as TestTemporal;
|
|
229
|
-
|
|
230
|
-
assert.equal(root.durationMs, 10_000);
|
|
231
|
-
assert.equal(a.startTimeMs, 0);
|
|
232
|
-
assert.equal(b.startTimeMs, 5_000);
|
|
233
|
-
},
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
litTest(
|
|
237
|
-
"temporal elements default to expand to fill a timegroup",
|
|
238
|
-
async ({ container }) => {
|
|
239
|
-
render(
|
|
240
|
-
html`<ef-timegroup id="root" mode="fixed" duration="10s">
|
|
241
|
-
<test-temporal id="a"></test-temporal>
|
|
242
|
-
</ef-timegroup> `,
|
|
243
|
-
container,
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
const root = container.querySelector("#root") as EFTimegroup;
|
|
247
|
-
const a = container.querySelector("#a") as TestTemporal;
|
|
248
|
-
|
|
249
|
-
assert.equal(root.durationMs, 10_000);
|
|
250
|
-
assert.equal(a.durationMs, 10_000);
|
|
251
|
-
},
|
|
252
|
-
);
|
|
253
|
-
|
|
254
|
-
litTest(
|
|
255
|
-
"element's parentTimegroup updates as they move",
|
|
256
|
-
async ({ container }) => {
|
|
257
|
-
const timegroup1 = document.createElement("ef-timegroup");
|
|
258
|
-
timegroup1.setAttribute("mode", "fixed");
|
|
259
|
-
timegroup1.setAttribute("duration", "5s");
|
|
260
|
-
|
|
261
|
-
const timegroup2 = document.createElement("ef-timegroup");
|
|
262
|
-
timegroup2.setAttribute("mode", "fixed");
|
|
263
|
-
timegroup2.setAttribute("duration", "5s");
|
|
264
|
-
|
|
265
|
-
container.appendChild(timegroup1);
|
|
266
|
-
container.appendChild(timegroup2);
|
|
267
|
-
|
|
268
|
-
const temporal = document.createElement("test-temporal");
|
|
269
|
-
|
|
270
|
-
timegroup1.appendChild(temporal);
|
|
271
|
-
|
|
272
|
-
assert.equal(temporal.parentTimegroup, timegroup1);
|
|
273
|
-
|
|
274
|
-
timegroup2.appendChild(temporal);
|
|
275
|
-
assert.equal(temporal.parentTimegroup, timegroup2);
|
|
276
|
-
},
|
|
277
|
-
);
|
|
278
|
-
|
|
279
|
-
litTest(
|
|
280
|
-
"elements can access their root temporal element",
|
|
281
|
-
async ({ container }) => {
|
|
282
|
-
render(
|
|
283
|
-
html`<ef-timegroup id="root" mode="contain" duration="10s">
|
|
284
|
-
<ef-timegroup id="a" mode="contain">
|
|
285
|
-
<div>
|
|
286
|
-
<ef-timegroup id="b" mode="contain">
|
|
287
|
-
<div>
|
|
288
|
-
<test-temporal id="c" duration="5s"></test-temporal>
|
|
289
|
-
</div>
|
|
290
|
-
</ef-timegroup>
|
|
291
|
-
</div>
|
|
292
|
-
</ef-timegroup>
|
|
293
|
-
</ef-timegroup> `,
|
|
294
|
-
container,
|
|
295
|
-
);
|
|
296
|
-
|
|
297
|
-
const root = container.querySelector("#root") as EFTimegroup;
|
|
298
|
-
const a = container.querySelector("#a") as EFTimegroup;
|
|
299
|
-
const b = container.querySelector("#b") as EFTimegroup;
|
|
300
|
-
const c = container.querySelector("#c") as TestTemporal;
|
|
301
|
-
|
|
302
|
-
assert.equal(root.rootTimegroup, root);
|
|
303
|
-
|
|
304
|
-
assert.equal(a.rootTimegroup, root);
|
|
305
|
-
assert.equal(b.rootTimegroup, root);
|
|
306
|
-
assert.equal(c.rootTimegroup, root);
|
|
307
|
-
},
|
|
308
|
-
);
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
describe("setting currentTime", () => {
|
|
312
|
-
litTest(
|
|
313
|
-
"persists in localStorage if the timegroup has an id",
|
|
314
|
-
async ({ tenSecondTimegroup: timegroup }) => {
|
|
315
|
-
assert.isNull(localStorage.getItem(timegroup.storageKey));
|
|
316
|
-
timegroup.currentTime = 5_000;
|
|
317
|
-
assert.equal(localStorage.getItem(timegroup.storageKey), "5000");
|
|
318
|
-
},
|
|
319
|
-
);
|
|
320
|
-
|
|
321
|
-
litTest(
|
|
322
|
-
"does not persist in localStorage if the timegroup has no id",
|
|
323
|
-
async ({ timegroup }) => {
|
|
324
|
-
timegroup.currentTime = 5_000;
|
|
325
|
-
assert.isNull(localStorage.getItem(timegroup.storageKey));
|
|
326
|
-
},
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
litTest(
|
|
330
|
-
"nested items derive their ownCurrentTimeMs",
|
|
331
|
-
async ({ container }) => {
|
|
332
|
-
render(
|
|
333
|
-
html`
|
|
334
|
-
<ef-timegroup id="root" mode="sequence">
|
|
335
|
-
<ef-timegroup id="a" mode="fixed" duration="5s"> </ef-timegroup>
|
|
336
|
-
<test-temporal id="b" mode="fixed" duration="5s"> </test-temporal>
|
|
337
|
-
</ef-timegroup>
|
|
338
|
-
`,
|
|
339
|
-
container,
|
|
340
|
-
);
|
|
341
|
-
|
|
342
|
-
const root = container.querySelector("#root") as EFTimegroup;
|
|
343
|
-
const a = container.querySelector("#a") as TestTemporal;
|
|
344
|
-
const b = container.querySelector("#b") as TestTemporal;
|
|
345
|
-
|
|
346
|
-
assert.equal(a.ownCurrentTimeMs, 0);
|
|
347
|
-
assert.equal(b.ownCurrentTimeMs, 0);
|
|
348
|
-
|
|
349
|
-
root.currentTimeMs = 2_500;
|
|
350
|
-
|
|
351
|
-
assert.equal(a.ownCurrentTimeMs, 2_500);
|
|
352
|
-
assert.equal(b.ownCurrentTimeMs, 0);
|
|
353
|
-
|
|
354
|
-
root.currentTimeMs = 7_500;
|
|
355
|
-
|
|
356
|
-
assert.equal(a.ownCurrentTimeMs, 5_000);
|
|
357
|
-
assert.equal(b.ownCurrentTimeMs, 2_500);
|
|
358
|
-
},
|
|
359
|
-
);
|
|
360
|
-
});
|
package/src/elements/EFVideo.ts
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { html, css } from "lit";
|
|
2
|
-
import { Task } from "@lit/task";
|
|
3
|
-
import { createRef, ref } from "lit/directives/ref.js";
|
|
4
|
-
import { customElement } from "lit/decorators.js";
|
|
5
|
-
|
|
6
|
-
import { EFMedia } from "./EFMedia";
|
|
7
|
-
import { TWMixin } from "../gui/TWMixin";
|
|
8
|
-
|
|
9
|
-
@customElement("ef-video")
|
|
10
|
-
export class EFVideo extends TWMixin(EFMedia) {
|
|
11
|
-
static styles = [
|
|
12
|
-
css`
|
|
13
|
-
:host {
|
|
14
|
-
display: block;
|
|
15
|
-
}
|
|
16
|
-
`,
|
|
17
|
-
];
|
|
18
|
-
canvasRef = createRef<HTMLCanvasElement>();
|
|
19
|
-
|
|
20
|
-
render() {
|
|
21
|
-
return html` <canvas
|
|
22
|
-
class="h-full w-full object-fill"
|
|
23
|
-
${ref(this.canvasRef)}
|
|
24
|
-
></canvas>`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
get canvasElement() {
|
|
28
|
-
return this.canvasRef.value;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// The underlying video decoder MUST NOT be used concurrently.
|
|
32
|
-
// If frames are fed in out of order, the decoder may crash.
|
|
33
|
-
#decoderLock = false;
|
|
34
|
-
|
|
35
|
-
frameTask = new Task(this, {
|
|
36
|
-
args: () =>
|
|
37
|
-
[
|
|
38
|
-
this.trackFragmentIndexLoader.status,
|
|
39
|
-
this.initSegmentsLoader.status,
|
|
40
|
-
this.seekTask.status,
|
|
41
|
-
this.fetchSeekTask.status,
|
|
42
|
-
this.videoAssetTask.status,
|
|
43
|
-
this.paintTask.status,
|
|
44
|
-
] as const,
|
|
45
|
-
task: async () => {
|
|
46
|
-
console.log("EFVideo frameTask", this.ownCurrentTimeMs);
|
|
47
|
-
await this.trackFragmentIndexLoader.taskComplete;
|
|
48
|
-
await this.initSegmentsLoader.taskComplete;
|
|
49
|
-
await this.seekTask.taskComplete;
|
|
50
|
-
await this.fetchSeekTask.taskComplete;
|
|
51
|
-
await this.videoAssetTask.taskComplete;
|
|
52
|
-
await this.paintTask.taskComplete;
|
|
53
|
-
console.log("EFVideo frameTask complete", this.ownCurrentTimeMs);
|
|
54
|
-
this.rootTimegroup?.requestUpdate();
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
paintTask = new Task(this, {
|
|
59
|
-
args: () => [this.videoAssetTask.value, this.desiredSeekTimeMs] as const,
|
|
60
|
-
task: async (
|
|
61
|
-
[videoAsset, seekToMs],
|
|
62
|
-
{
|
|
63
|
-
signal:
|
|
64
|
-
_signal /** Aborting seeks is counter-productive. It is better to drop seeks. */,
|
|
65
|
-
},
|
|
66
|
-
) => {
|
|
67
|
-
console.log(`EFVideo paintTask decoderLock=${this.#decoderLock}`);
|
|
68
|
-
if (!videoAsset) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
if (this.#decoderLock) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
try {
|
|
75
|
-
this.#decoderLock = true;
|
|
76
|
-
const frame = await videoAsset.seekToTime(seekToMs / 1000);
|
|
77
|
-
console.log(
|
|
78
|
-
"Painting frame",
|
|
79
|
-
"seekToMs",
|
|
80
|
-
seekToMs,
|
|
81
|
-
"timestamp",
|
|
82
|
-
frame?.timestamp,
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
if (!this.canvasElement) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
const ctx = this.canvasElement.getContext("2d");
|
|
89
|
-
if (!(frame && ctx)) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
this.canvasElement.width = frame?.codedWidth;
|
|
94
|
-
this.canvasElement.height = frame?.codedHeight;
|
|
95
|
-
|
|
96
|
-
ctx.drawImage(
|
|
97
|
-
frame,
|
|
98
|
-
0,
|
|
99
|
-
0,
|
|
100
|
-
this.canvasElement.width,
|
|
101
|
-
this.canvasElement.height,
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
return seekToMs;
|
|
105
|
-
} catch (error) {
|
|
106
|
-
console.trace("Unexpected error while seeking video", error);
|
|
107
|
-
// As a practical matter, we should probably just re-create the VideoAsset if decoding fails.
|
|
108
|
-
// The decoder is probably in an invalid state anyway.
|
|
109
|
-
} finally {
|
|
110
|
-
this.#decoderLock = false;
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
}
|