@editframe/elements 0.12.0-beta.2 → 0.12.0-beta.21
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/elements/EFAudio.d.ts +1 -1
- package/dist/elements/EFCaptions.d.ts +5 -5
- package/dist/elements/EFImage.d.ts +1 -1
- package/dist/elements/EFMedia.browsertest.d.ts +1 -1
- package/dist/elements/EFMedia.d.ts +1 -2
- package/dist/elements/{src/elements/EFMedia.js → EFMedia.js} +72 -15
- package/dist/elements/EFTemporal.browsertest.d.ts +1 -1
- package/dist/elements/EFTemporal.d.ts +4 -1
- package/dist/elements/{src/elements/EFTemporal.js → EFTemporal.js} +3 -0
- package/dist/elements/EFTimegroup.browsertest.d.ts +2 -2
- package/dist/elements/EFTimegroup.d.ts +3 -3
- package/dist/elements/EFVideo.d.ts +1 -1
- package/dist/elements/{src/elements/EFVideo.js → EFVideo.js} +10 -2
- package/dist/elements/EFWaveform.d.ts +7 -4
- package/dist/elements/{src/elements/EFWaveform.js → EFWaveform.js} +48 -56
- package/dist/elements/TimegroupController.d.ts +2 -2
- package/dist/elements/util.d.ts +1 -1
- package/dist/gui/ContextMixin.browsertest.d.ts +1 -1
- package/dist/gui/ContextMixin.d.ts +1 -1
- package/dist/{elements/src/gui → gui}/ContextMixin.js +8 -4
- package/dist/gui/EFFilmstrip.d.ts +7 -7
- package/dist/gui/EFPreview.d.ts +1 -1
- package/dist/{elements/src/gui → gui}/EFPreview.js +3 -1
- package/dist/gui/EFScrubber.d.ts +1 -1
- package/dist/gui/EFTimeDisplay.d.ts +1 -1
- package/dist/gui/EFToggleLoop.d.ts +1 -1
- package/dist/gui/EFTogglePlay.d.ts +1 -3
- package/dist/{elements/src/gui → gui}/EFTogglePlay.js +1 -9
- package/dist/gui/EFWorkbench.d.ts +1 -1
- package/dist/{elements/src/gui → gui}/TWMixin.css.js +1 -1
- package/dist/gui/efContext.d.ts +1 -1
- package/dist/index.d.ts +14 -14
- package/package.json +5 -4
- package/src/elements/EFAudio.ts +3 -3
- package/src/elements/EFCaptions.browsertest.ts +3 -3
- package/src/elements/EFCaptions.ts +9 -9
- package/src/elements/EFImage.browsertest.ts +2 -2
- package/src/elements/EFImage.ts +4 -4
- package/src/elements/EFMedia.browsertest.ts +7 -5
- package/src/elements/EFMedia.ts +91 -19
- package/src/elements/EFSourceMixin.ts +3 -3
- package/src/elements/EFTemporal.browsertest.ts +1 -1
- package/src/elements/EFTemporal.ts +9 -3
- package/src/elements/EFTimegroup.browsertest.ts +5 -5
- package/src/elements/EFTimegroup.ts +6 -6
- package/src/elements/EFVideo.ts +15 -4
- package/src/elements/EFWaveform.ts +82 -98
- package/src/elements/FetchMixin.ts +2 -2
- package/src/elements/TimegroupController.ts +2 -2
- package/src/elements/durationConverter.ts +1 -1
- package/src/elements/util.ts +1 -1
- package/src/gui/ContextMixin.browsertest.ts +3 -3
- package/src/gui/ContextMixin.ts +18 -12
- package/src/gui/EFFilmstrip.ts +15 -15
- package/src/gui/EFPreview.ts +5 -3
- package/src/gui/EFScrubber.ts +3 -3
- package/src/gui/EFTimeDisplay.ts +2 -2
- package/src/gui/EFToggleLoop.ts +4 -4
- package/src/gui/EFTogglePlay.ts +4 -10
- package/src/gui/EFWorkbench.ts +2 -2
- package/src/gui/efContext.ts +1 -1
- package/dist/assets/src/EncodedAsset.js +0 -560
- package/dist/assets/src/MP4File.js +0 -172
- package/dist/assets/src/memoize.js +0 -14
- package/dist/elements/src/elements/util.js +0 -11
- package/dist/{elements/src/EF_FRAMEGEN.js → EF_FRAMEGEN.js} +0 -0
- package/dist/{elements/src/EF_INTERACTIVE.js → EF_INTERACTIVE.js} +0 -0
- package/dist/{elements/src/EF_RENDERING.js → EF_RENDERING.js} +0 -0
- package/dist/elements/{src/elements/CrossUpdateController.js → CrossUpdateController.js} +0 -0
- package/dist/elements/{src/elements/EFAudio.js → EFAudio.js} +2 -2
- package/dist/elements/{src/elements/EFCaptions.js → EFCaptions.js} +0 -0
- package/dist/elements/{src/elements/EFImage.js → EFImage.js} +0 -0
- package/dist/elements/{src/elements/EFSourceMixin.js → EFSourceMixin.js} +1 -1
- package/dist/elements/{src/elements/EFTimegroup.js → EFTimegroup.js} +0 -0
- package/dist/elements/{src/elements/FetchMixin.js → FetchMixin.js} +0 -0
- package/dist/elements/{src/elements/TimegroupController.js → TimegroupController.js} +0 -0
- package/dist/elements/{src/elements/durationConverter.js → durationConverter.js} +0 -0
- package/dist/elements/{src/elements/parseTimeToMs.js → parseTimeToMs.js} +0 -0
- package/dist/{elements/src/gui → gui}/EFFilmstrip.js +0 -0
- package/dist/{elements/src/gui → gui}/EFScrubber.js +0 -0
- package/dist/{elements/src/gui → gui}/EFTimeDisplay.js +0 -0
- package/dist/{elements/src/gui → gui}/EFToggleLoop.js +1 -1
- /package/dist/{elements/src/gui → gui}/EFWorkbench.js +0 -0
- /package/dist/{elements/src/gui → gui}/TWMixin.js +0 -0
- /package/dist/{elements/src/gui → gui}/apiHostContext.js +0 -0
- /package/dist/{elements/src/gui → gui}/efContext.js +0 -0
- /package/dist/{elements/src/gui → gui}/fetchContext.js +0 -0
- /package/dist/{elements/src/gui → gui}/focusContext.js +0 -0
- /package/dist/{elements/src/gui → gui}/focusedElementContext.js +0 -0
- /package/dist/{elements/src/gui → gui}/playingContext.js +0 -0
- /package/dist/{elements/src/index.js → index.js} +0 -0
- /package/dist/{elements/src/msToTimeCode.js → msToTimeCode.js} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Task } from '@lit/task';
|
|
2
2
|
import { LitElement, PropertyValueMap } from 'lit';
|
|
3
|
-
import { EFAudio } from './EFAudio.
|
|
4
|
-
import { EFVideo } from './EFVideo.
|
|
5
|
-
declare const EFCaptionsActiveWord_base: (new (...args: any[]) => import('./EFTemporal.
|
|
3
|
+
import { EFAudio } from './EFAudio.js';
|
|
4
|
+
import { EFVideo } from './EFVideo.js';
|
|
5
|
+
declare const EFCaptionsActiveWord_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
6
6
|
export declare class EFCaptionsActiveWord extends EFCaptionsActiveWord_base {
|
|
7
7
|
static styles: import('lit').CSSResult[];
|
|
8
8
|
render(): import('lit-html').TemplateResult<1> | undefined;
|
|
@@ -13,7 +13,7 @@ export declare class EFCaptionsActiveWord extends EFCaptionsActiveWord_base {
|
|
|
13
13
|
get startTimeMs(): number;
|
|
14
14
|
get durationMs(): number;
|
|
15
15
|
}
|
|
16
|
-
declare const EFCaptionsSegment_base: (new (...args: any[]) => import('./EFTemporal.
|
|
16
|
+
declare const EFCaptionsSegment_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
17
17
|
export declare class EFCaptionsSegment extends EFCaptionsSegment_base {
|
|
18
18
|
static styles: import('lit').CSSResult[];
|
|
19
19
|
render(): import('lit-html').TemplateResult<1> | undefined;
|
|
@@ -44,7 +44,7 @@ export declare class EFCaptionsAfterActiveWord extends EFCaptionsSegment {
|
|
|
44
44
|
get startTimeMs(): number;
|
|
45
45
|
get durationMs(): number;
|
|
46
46
|
}
|
|
47
|
-
declare const EFCaptions_base: (new (...args: any[]) => import('./EFSourceMixin.
|
|
47
|
+
declare const EFCaptions_base: (new (...args: any[]) => import('./EFSourceMixin.js').EFSourceMixinInterface) & (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & (new (...args: any[]) => import('./FetchMixin.js').FetchMixinInterface) & typeof LitElement;
|
|
48
48
|
export declare class EFCaptions extends EFCaptions_base {
|
|
49
49
|
static styles: import('lit').CSSResult[];
|
|
50
50
|
displayMode: "word" | "segment" | "context";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Task } from '@lit/task';
|
|
2
2
|
import { LitElement } from 'lit';
|
|
3
|
-
declare const EFImage_base: (new (...args: any[]) => import('./EFSourceMixin.
|
|
3
|
+
declare const EFImage_base: (new (...args: any[]) => import('./EFSourceMixin.js').EFSourceMixinInterface) & (new (...args: any[]) => import('./FetchMixin.js').FetchMixinInterface) & typeof LitElement;
|
|
4
4
|
export declare class EFImage extends EFImage_base {
|
|
5
5
|
#private;
|
|
6
6
|
static styles: import('lit').CSSResult[];
|
|
@@ -5,7 +5,7 @@ import { VideoAsset } from '../../../assets/src/EncodedAsset.ts';
|
|
|
5
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
|
-
declare const EFMedia_base: (new (...args: any[]) => import('./EFSourceMixin.
|
|
8
|
+
declare const EFMedia_base: (new (...args: any[]) => import('./EFSourceMixin.js').EFSourceMixinInterface) & (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & (new (...args: any[]) => import('./FetchMixin.js').FetchMixinInterface) & typeof LitElement;
|
|
9
9
|
export declare class EFMedia extends EFMedia_base {
|
|
10
10
|
#private;
|
|
11
11
|
static styles: import('lit').CSSResult[];
|
|
@@ -47,7 +47,6 @@ export declare class EFMedia extends EFMedia_base {
|
|
|
47
47
|
protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
|
|
48
48
|
get hasOwnDuration(): boolean;
|
|
49
49
|
get durationMs(): number;
|
|
50
|
-
get startTimeMs(): number;
|
|
51
50
|
audioBufferTask: Task<readonly [Record<string, File> | undefined, Record<string, {
|
|
52
51
|
segment: TrackSegment;
|
|
53
52
|
track: MP4Box.TrackInfo;
|
|
@@ -4,15 +4,14 @@ import { deepArrayEquals } from "@lit/task/deep-equals.js";
|
|
|
4
4
|
import debug from "debug";
|
|
5
5
|
import { css, LitElement } from "lit";
|
|
6
6
|
import { property, state } from "lit/decorators.js";
|
|
7
|
-
import { VideoAsset } from "
|
|
8
|
-
import { MP4File } from "
|
|
7
|
+
import { VideoAsset } from "@editframe/assets/EncodedAsset.js";
|
|
8
|
+
import { MP4File } from "@editframe/assets/MP4File.js";
|
|
9
9
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
10
10
|
import { EF_RENDERING } from "../EF_RENDERING.js";
|
|
11
11
|
import { apiHostContext } from "../gui/apiHostContext.js";
|
|
12
12
|
import { EFSourceMixin } from "./EFSourceMixin.js";
|
|
13
|
-
import { EFTemporal } from "./EFTemporal.js";
|
|
13
|
+
import { EFTemporal, isEFTemporal } from "./EFTemporal.js";
|
|
14
14
|
import { FetchMixin } from "./FetchMixin.js";
|
|
15
|
-
import { getStartTimeMs } from "./util.js";
|
|
16
15
|
var __defProp = Object.defineProperty;
|
|
17
16
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
18
17
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -62,10 +61,10 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
62
61
|
return await Promise.all(
|
|
63
62
|
Object.entries(fragmentIndex).map(async ([trackId, track]) => {
|
|
64
63
|
const start = track.initSegment.offset;
|
|
65
|
-
const end = track.initSegment.offset + track.initSegment.size
|
|
64
|
+
const end = track.initSegment.offset + track.initSegment.size;
|
|
66
65
|
const response = await fetch(this.fragmentTrackPath(trackId), {
|
|
67
66
|
signal,
|
|
68
|
-
headers: { Range: `bytes=${start}-${end}` }
|
|
67
|
+
headers: { Range: `bytes=${start}-${end - 1}` }
|
|
69
68
|
});
|
|
70
69
|
const buffer = await response.arrayBuffer();
|
|
71
70
|
buffer.fileStart = 0;
|
|
@@ -131,14 +130,14 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
131
130
|
const end = segment.offset + segment.size;
|
|
132
131
|
const response = await fetch(this.fragmentTrackPath(trackId), {
|
|
133
132
|
signal,
|
|
134
|
-
headers: { Range: `bytes=${start}-${end}` }
|
|
133
|
+
headers: { Range: `bytes=${start}-${end - 1}` }
|
|
135
134
|
});
|
|
136
135
|
if (nextSegment) {
|
|
137
136
|
const nextStart = nextSegment.offset;
|
|
138
137
|
const nextEnd = nextSegment.offset + nextSegment.size;
|
|
139
138
|
fetch(this.fragmentTrackPath(trackId), {
|
|
140
139
|
signal,
|
|
141
|
-
headers: { Range: `bytes=${nextStart}-${nextEnd}` }
|
|
140
|
+
headers: { Range: `bytes=${nextStart}-${nextEnd - 1}` }
|
|
142
141
|
}).then(() => {
|
|
143
142
|
log("Prefetched next segment");
|
|
144
143
|
}).catch((error) => {
|
|
@@ -270,6 +269,67 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
270
269
|
if (changedProperties.has("ownCurrentTimeMs")) {
|
|
271
270
|
this.executeSeek(this.trimAdjustedOwnCurrentTimeMs);
|
|
272
271
|
}
|
|
272
|
+
if (changedProperties.has("currentTime") || changedProperties.has("ownCurrentTimeMs")) {
|
|
273
|
+
const timelineTimeMs = (this.rootTimegroup ?? this).currentTimeMs;
|
|
274
|
+
if (this.startTimeMs > timelineTimeMs || this.endTimeMs < timelineTimeMs) {
|
|
275
|
+
this.style.display = "none";
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
this.style.display = "";
|
|
279
|
+
const animations = this.getAnimations({ subtree: true });
|
|
280
|
+
this.style.setProperty("--ef-duration", `${this.durationMs}ms`);
|
|
281
|
+
this.style.setProperty(
|
|
282
|
+
"--ef-transition--duration",
|
|
283
|
+
`${this.parentTimegroup?.overlapMs ?? 0}ms`
|
|
284
|
+
);
|
|
285
|
+
this.style.setProperty(
|
|
286
|
+
"--ef-transition-out-start",
|
|
287
|
+
`${this.durationMs - (this.parentTimegroup?.overlapMs ?? 0)}ms`
|
|
288
|
+
);
|
|
289
|
+
for (const animation of animations) {
|
|
290
|
+
if (animation.playState === "running") {
|
|
291
|
+
animation.pause();
|
|
292
|
+
}
|
|
293
|
+
const effect = animation.effect;
|
|
294
|
+
if (!(effect && effect instanceof KeyframeEffect)) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const target = effect.target;
|
|
298
|
+
if (!target) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
if (target.closest("ef-video, ef-audio") !== this) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (isEFTemporal(target)) {
|
|
305
|
+
const timing = effect.getTiming();
|
|
306
|
+
const duration = Number(timing.duration) ?? 0;
|
|
307
|
+
const delay = Number(timing.delay);
|
|
308
|
+
const newTime = Math.floor(
|
|
309
|
+
Math.min(target.ownCurrentTimeMs, duration - 1 + delay)
|
|
310
|
+
);
|
|
311
|
+
if (Number.isNaN(newTime)) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
animation.currentTime = newTime;
|
|
315
|
+
} else if (target) {
|
|
316
|
+
const nearestTimegroup = target.closest("ef-timegroup");
|
|
317
|
+
if (!nearestTimegroup) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
const timing = effect.getTiming();
|
|
321
|
+
const duration = Number(timing.duration) ?? 0;
|
|
322
|
+
const delay = Number(timing.delay);
|
|
323
|
+
const newTime = Math.floor(
|
|
324
|
+
Math.min(nearestTimegroup.ownCurrentTimeMs, duration - 1 + delay)
|
|
325
|
+
);
|
|
326
|
+
if (Number.isNaN(newTime)) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
animation.currentTime = newTime;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
273
333
|
}
|
|
274
334
|
get hasOwnDuration() {
|
|
275
335
|
return true;
|
|
@@ -300,9 +360,6 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
300
360
|
}
|
|
301
361
|
return Math.max(...durations) - this.trimStartMs - this.trimEndMs;
|
|
302
362
|
}
|
|
303
|
-
get startTimeMs() {
|
|
304
|
-
return getStartTimeMs(this);
|
|
305
|
-
}
|
|
306
363
|
#audioContext;
|
|
307
364
|
async fetchAudioSpanningTime(fromMs, toMs) {
|
|
308
365
|
if (this.sourceInMs) {
|
|
@@ -325,11 +382,11 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
325
382
|
return;
|
|
326
383
|
}
|
|
327
384
|
const start = audioTrackIndex.initSegment.offset;
|
|
328
|
-
const end = audioTrackIndex.initSegment.offset + audioTrackIndex.initSegment.size
|
|
385
|
+
const end = audioTrackIndex.initSegment.offset + audioTrackIndex.initSegment.size;
|
|
329
386
|
const audioInitFragmentRequest = this.fetch(
|
|
330
387
|
this.fragmentTrackPath(String(audioTrackId)),
|
|
331
388
|
{
|
|
332
|
-
headers: { Range: `bytes=${start}-${end}` }
|
|
389
|
+
headers: { Range: `bytes=${start}-${end - 1}` }
|
|
333
390
|
}
|
|
334
391
|
);
|
|
335
392
|
const fragments = Object.values(audioTrackIndex.segments).filter(
|
|
@@ -350,11 +407,11 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
|
|
|
350
407
|
return;
|
|
351
408
|
}
|
|
352
409
|
const fragmentStart = firstFragment.offset;
|
|
353
|
-
const fragmentEnd = lastFragment.offset + lastFragment.size
|
|
410
|
+
const fragmentEnd = lastFragment.offset + lastFragment.size;
|
|
354
411
|
const audioFragmentRequest = this.fetch(
|
|
355
412
|
this.fragmentTrackPath(String(audioTrackId)),
|
|
356
413
|
{
|
|
357
|
-
headers: { Range: `bytes=${fragmentStart}-${fragmentEnd}` }
|
|
414
|
+
headers: { Range: `bytes=${fragmentStart}-${fragmentEnd - 1}` }
|
|
358
415
|
}
|
|
359
416
|
);
|
|
360
417
|
const initResponse = await audioInitFragmentRequest;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
-
declare const TestTemporal_base: (new (...args: any[]) => import('./EFTemporal.
|
|
2
|
+
declare const TestTemporal_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
3
3
|
declare class TestTemporal extends TestTemporal_base {
|
|
4
4
|
}
|
|
5
5
|
declare global {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement, ReactiveController } from 'lit';
|
|
2
|
-
import { EFTimegroup } from './EFTimegroup.
|
|
2
|
+
import { EFTimegroup } from './EFTimegroup.js';
|
|
3
3
|
import { Task } from '@lit/task';
|
|
4
4
|
export declare const timegroupContext: {
|
|
5
5
|
__context__: EFTimegroup;
|
|
@@ -20,6 +20,9 @@ export declare class TemporalMixinInterface {
|
|
|
20
20
|
set sourceout(value: string);
|
|
21
21
|
get durationMs(): number;
|
|
22
22
|
get startTimeMs(): number;
|
|
23
|
+
/**
|
|
24
|
+
* The start time of the element within its parent timegroup.
|
|
25
|
+
*/
|
|
23
26
|
get startTimeWithinParentMs(): number;
|
|
24
27
|
get endTimeMs(): number;
|
|
25
28
|
get ownCurrentTimeMs(): number;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
-
declare const TestContext_base: (new (...args: any[]) => import('../gui/ContextMixin.
|
|
2
|
+
declare const TestContext_base: (new (...args: any[]) => import('../gui/ContextMixin.js').ContextMixinInterface) & typeof LitElement;
|
|
3
3
|
declare class TestContext extends TestContext_base {
|
|
4
4
|
}
|
|
5
|
-
declare const TestTemporal_base: (new (...args: any[]) => import('./EFTemporal.
|
|
5
|
+
declare const TestTemporal_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
6
6
|
declare class TestTemporal extends TestTemporal_base {
|
|
7
7
|
get hasOwnDuration(): boolean;
|
|
8
8
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Task } from '@lit/task';
|
|
2
2
|
import { LitElement, PropertyValueMap } from 'lit';
|
|
3
3
|
export declare const shallowGetTimegroups: (element: Element, groups?: EFTimegroup[]) => EFTimegroup[];
|
|
4
|
-
declare const EFTimegroup_base: (new (...args: any[]) => import('./EFTemporal.
|
|
4
|
+
declare const EFTimegroup_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
5
5
|
export declare class EFTimegroup extends EFTimegroup_base {
|
|
6
6
|
#private;
|
|
7
7
|
static styles: import('lit').CSSResult;
|
|
@@ -28,9 +28,9 @@ export declare class EFTimegroup extends EFTimegroup_base {
|
|
|
28
28
|
buffer: import('mp4box').MP4ArrayBuffer;
|
|
29
29
|
mp4File: import('../../../assets/src/MP4File.ts').MP4File;
|
|
30
30
|
}[] | undefined)[]>;
|
|
31
|
-
get childTemporals(): import('./EFTemporal.
|
|
31
|
+
get childTemporals(): import('./EFTemporal.js').TemporalMixinInterface[];
|
|
32
32
|
protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
|
|
33
|
-
get contextProvider(): import('../gui/ContextMixin.
|
|
33
|
+
get contextProvider(): import('../gui/ContextMixin.js').ContextMixinInterface | null;
|
|
34
34
|
/**
|
|
35
35
|
* Returns true if the timegroup should be wrapped with a workbench.
|
|
36
36
|
*
|
|
@@ -66,8 +66,16 @@ let EFVideo = class extends TWMixin(EFMedia) {
|
|
|
66
66
|
if (!(frame && ctx)) {
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
if (frame?.codedWidth && frame?.codedHeight) {
|
|
70
|
+
if (this.canvasElement.width !== frame.codedWidth || this.canvasElement.height !== frame.codedHeight) {
|
|
71
|
+
this.canvasElement.width = frame.codedWidth;
|
|
72
|
+
this.canvasElement.height = frame.codedHeight;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (frame.format === null) {
|
|
76
|
+
console.warn("Frame format is null", frame);
|
|
77
|
+
return seekToMs;
|
|
78
|
+
}
|
|
71
79
|
ctx.drawImage(
|
|
72
80
|
frame,
|
|
73
81
|
0,
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { EFAudio } from './EFAudio.
|
|
1
|
+
import { EFAudio } from './EFAudio.js';
|
|
2
2
|
import { Task } from '@lit/task';
|
|
3
3
|
import { LitElement, PropertyValueMap } from 'lit';
|
|
4
4
|
import { Ref } from 'lit/directives/ref.js';
|
|
5
|
-
import { EFVideo } from './EFVideo.
|
|
6
|
-
declare const EFWaveform_base: (new (...args: any[]) => import('./EFTemporal.
|
|
5
|
+
import { EFVideo } from './EFVideo.js';
|
|
6
|
+
declare const EFWaveform_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
7
7
|
export declare class EFWaveform extends EFWaveform_base {
|
|
8
8
|
static styles: import('lit').CSSResult[];
|
|
9
9
|
canvasRef: Ref<HTMLCanvasElement>;
|
|
10
10
|
private ctx;
|
|
11
|
+
private resizeObserver?;
|
|
12
|
+
private mutationObserver?;
|
|
11
13
|
createRenderRoot(): this;
|
|
12
14
|
render(): import('lit-html').TemplateResult<1>;
|
|
13
15
|
mode: "roundBars" | "bars" | "bricks" | "equalizer" | "curve" | "line" | "pixel" | "wave";
|
|
@@ -15,6 +17,8 @@ export declare class EFWaveform extends EFWaveform_base {
|
|
|
15
17
|
targetSelector: string;
|
|
16
18
|
set target(value: string);
|
|
17
19
|
connectedCallback(): void;
|
|
20
|
+
disconnectedCallback(): void;
|
|
21
|
+
private resizeCanvas;
|
|
18
22
|
protected initCanvas(): CanvasRenderingContext2D | null;
|
|
19
23
|
protected drawBars(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
|
|
20
24
|
protected drawBricks(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
|
|
@@ -24,7 +28,6 @@ export declare class EFWaveform extends EFWaveform_base {
|
|
|
24
28
|
protected drawCurve(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
|
|
25
29
|
protected drawPixel(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
|
|
26
30
|
protected drawWave(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array): void;
|
|
27
|
-
private lastFrameTime;
|
|
28
31
|
frameTask: Task<readonly [import('@lit/task').TaskStatus], void>;
|
|
29
32
|
get durationMs(): number;
|
|
30
33
|
get targetElement(): EFAudio | EFVideo;
|
|
@@ -26,53 +26,39 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
26
26
|
this.mode = "bars";
|
|
27
27
|
this.color = "currentColor";
|
|
28
28
|
this.targetSelector = "";
|
|
29
|
-
this.lastFrameTime = 0;
|
|
30
29
|
this.frameTask = new Task(this, {
|
|
31
30
|
autoRun: EF_INTERACTIVE,
|
|
32
31
|
args: () => [this.targetElement.audioBufferTask.status],
|
|
33
32
|
task: async () => {
|
|
34
|
-
const currentTime = performance.now();
|
|
35
|
-
const timeSinceLastFrame = this.lastFrameTime ? currentTime - this.lastFrameTime : 0;
|
|
36
|
-
console.log(`Time since last frame: ${timeSinceLastFrame.toFixed(2)}ms`);
|
|
37
|
-
this.lastFrameTime = currentTime;
|
|
38
33
|
await this.targetElement.audioBufferTask.taskComplete;
|
|
39
34
|
this.ctx ||= this.initCanvas();
|
|
40
35
|
const ctx = this.ctx;
|
|
41
36
|
if (!ctx) return;
|
|
42
37
|
if (!this.targetElement.audioBufferTask.value) return;
|
|
43
38
|
if (this.targetElement.trimAdjustedOwnCurrentTimeMs > 0) {
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const smoothedData = new Uint8Array(dataLength);
|
|
68
|
-
for (let i = 0; i < smoothedData.length; i++) {
|
|
69
|
-
let sum = 0;
|
|
70
|
-
for (const frameData of multiFrameData) {
|
|
71
|
-
sum += frameData[i] ?? 0;
|
|
72
|
-
}
|
|
73
|
-
let avg = sum / FRAMES_TO_ANALYZE;
|
|
74
|
-
avg = (avg / 255) ** 1.2 * 255;
|
|
75
|
-
smoothedData[i] = Math.round(avg);
|
|
39
|
+
const FRAME_DURATION_MS = 48e3 / 1e3;
|
|
40
|
+
const FRAME_SMEAR_MS = FRAME_DURATION_MS * 1;
|
|
41
|
+
const FRAME_SMEAR_S = FRAME_SMEAR_MS / 1e3;
|
|
42
|
+
const audioContext = new OfflineAudioContext(2, 48e3 / 25, 48e3);
|
|
43
|
+
const audioBufferSource = audioContext.createBufferSource();
|
|
44
|
+
audioBufferSource.buffer = this.targetElement.audioBufferTask.value.buffer;
|
|
45
|
+
const analyser = audioContext.createAnalyser();
|
|
46
|
+
analyser.fftSize = 128 * 8;
|
|
47
|
+
audioBufferSource.connect(analyser);
|
|
48
|
+
const startTime = Math.max(
|
|
49
|
+
0,
|
|
50
|
+
(this.targetElement.trimAdjustedOwnCurrentTimeMs - this.targetElement.audioBufferTask.value.startOffsetMs) / 1e3
|
|
51
|
+
);
|
|
52
|
+
audioBufferSource.start(0, startTime, FRAME_SMEAR_S);
|
|
53
|
+
await audioContext.startRendering();
|
|
54
|
+
const frameData = new Uint8Array(analyser.frequencyBinCount);
|
|
55
|
+
analyser.getByteFrequencyData(frameData);
|
|
56
|
+
const smoothedData = frameData.slice(0, frameData.length / 2);
|
|
57
|
+
if (this.color === "currentColor") {
|
|
58
|
+
const computedStyle = getComputedStyle(this);
|
|
59
|
+
const currentColor = computedStyle.color;
|
|
60
|
+
ctx.strokeStyle = currentColor;
|
|
61
|
+
ctx.fillStyle = currentColor;
|
|
76
62
|
}
|
|
77
63
|
switch (this.mode) {
|
|
78
64
|
case "bars":
|
|
@@ -118,9 +104,31 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
118
104
|
if (this.targetElement) {
|
|
119
105
|
new CrossUpdateController(this.targetElement, this);
|
|
120
106
|
}
|
|
107
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
108
|
+
this.resizeCanvas();
|
|
109
|
+
});
|
|
110
|
+
this.resizeObserver.observe(this);
|
|
111
|
+
this.mutationObserver = new MutationObserver((mutationsList) => {
|
|
112
|
+
for (const mutation of mutationsList) {
|
|
113
|
+
if (mutation.type === "attributes") {
|
|
114
|
+
this.frameTask.run();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
this.mutationObserver.observe(this, { attributes: true });
|
|
119
|
+
}
|
|
120
|
+
disconnectedCallback() {
|
|
121
|
+
super.disconnectedCallback();
|
|
122
|
+
this.resizeObserver?.disconnect();
|
|
123
|
+
this.mutationObserver?.disconnect();
|
|
124
|
+
}
|
|
125
|
+
resizeCanvas() {
|
|
126
|
+
this.ctx = this.initCanvas();
|
|
127
|
+
if (this.ctx) {
|
|
128
|
+
this.frameTask.run();
|
|
129
|
+
}
|
|
121
130
|
}
|
|
122
131
|
initCanvas() {
|
|
123
|
-
console.count("initCanvas");
|
|
124
132
|
const canvas = this.canvasRef.value;
|
|
125
133
|
if (!canvas) return null;
|
|
126
134
|
const rect = this.getBoundingClientRect();
|
|
@@ -135,8 +143,6 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
135
143
|
return ctx;
|
|
136
144
|
}
|
|
137
145
|
drawBars(ctx, frequencyData) {
|
|
138
|
-
ctx.strokeStyle = this.color;
|
|
139
|
-
ctx.fillStyle = this.color;
|
|
140
146
|
const canvas = ctx.canvas;
|
|
141
147
|
const waveWidth = canvas.width / devicePixelRatio;
|
|
142
148
|
const waveHeight = canvas.height / devicePixelRatio;
|
|
@@ -151,8 +157,6 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
151
157
|
});
|
|
152
158
|
}
|
|
153
159
|
drawBricks(ctx, frequencyData) {
|
|
154
|
-
ctx.strokeStyle = this.color;
|
|
155
|
-
ctx.fillStyle = this.color;
|
|
156
160
|
const canvas = ctx.canvas;
|
|
157
161
|
const waveWidth = canvas.width / devicePixelRatio;
|
|
158
162
|
const waveHeight = canvas.height / devicePixelRatio;
|
|
@@ -176,8 +180,6 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
176
180
|
});
|
|
177
181
|
}
|
|
178
182
|
drawLine(ctx, frequencyData) {
|
|
179
|
-
ctx.strokeStyle = this.color;
|
|
180
|
-
ctx.fillStyle = this.color;
|
|
181
183
|
const canvas = ctx.canvas;
|
|
182
184
|
const waveWidth = canvas.width / devicePixelRatio;
|
|
183
185
|
const waveHeight = canvas.height / devicePixelRatio;
|
|
@@ -196,8 +198,6 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
196
198
|
ctx.stroke();
|
|
197
199
|
}
|
|
198
200
|
drawRoundBars(ctx, frequencyData) {
|
|
199
|
-
ctx.strokeStyle = this.color;
|
|
200
|
-
ctx.fillStyle = this.color;
|
|
201
201
|
const canvas = ctx.canvas;
|
|
202
202
|
const waveWidth = canvas.width / devicePixelRatio;
|
|
203
203
|
const waveHeight = canvas.height / devicePixelRatio;
|
|
@@ -216,8 +216,6 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
216
216
|
});
|
|
217
217
|
}
|
|
218
218
|
drawEqualizer(ctx, frequencyData) {
|
|
219
|
-
ctx.strokeStyle = this.color;
|
|
220
|
-
ctx.fillStyle = this.color;
|
|
221
219
|
const canvas = ctx.canvas;
|
|
222
220
|
const waveWidth = canvas.width / devicePixelRatio;
|
|
223
221
|
const waveHeight = canvas.height / devicePixelRatio;
|
|
@@ -237,8 +235,6 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
237
235
|
});
|
|
238
236
|
}
|
|
239
237
|
drawCurve(ctx, frequencyData) {
|
|
240
|
-
ctx.strokeStyle = this.color;
|
|
241
|
-
ctx.fillStyle = this.color;
|
|
242
238
|
const canvas = ctx.canvas;
|
|
243
239
|
const waveWidth = canvas.width / devicePixelRatio;
|
|
244
240
|
const waveHeight = canvas.height / devicePixelRatio;
|
|
@@ -257,8 +253,6 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
257
253
|
ctx.stroke();
|
|
258
254
|
}
|
|
259
255
|
drawPixel(ctx, frequencyData) {
|
|
260
|
-
ctx.strokeStyle = this.color;
|
|
261
|
-
ctx.fillStyle = this.color;
|
|
262
256
|
const canvas = ctx.canvas;
|
|
263
257
|
const waveWidth = canvas.width / devicePixelRatio;
|
|
264
258
|
const waveHeight = canvas.height / devicePixelRatio;
|
|
@@ -273,8 +267,6 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
273
267
|
});
|
|
274
268
|
}
|
|
275
269
|
drawWave(ctx, frequencyData) {
|
|
276
|
-
ctx.strokeStyle = this.color;
|
|
277
|
-
ctx.fillStyle = this.color;
|
|
278
270
|
const canvas = ctx.canvas;
|
|
279
271
|
const waveWidth = canvas.width / devicePixelRatio;
|
|
280
272
|
const waveHeight = canvas.height / devicePixelRatio;
|
|
@@ -285,7 +277,7 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
285
277
|
ctx.moveTo(0, baseline);
|
|
286
278
|
ctx.lineTo(waveWidth, baseline);
|
|
287
279
|
ctx.strokeStyle = this.color;
|
|
288
|
-
ctx.lineWidth =
|
|
280
|
+
ctx.lineWidth = 1;
|
|
289
281
|
ctx.stroke();
|
|
290
282
|
frequencyData.forEach((value, i) => {
|
|
291
283
|
const x = i * (waveWidth / frequencyData.length);
|
|
@@ -306,7 +298,7 @@ let EFWaveform = class extends EFTemporal(TWMixin(LitElement)) {
|
|
|
306
298
|
}
|
|
307
299
|
updated(changedProperties) {
|
|
308
300
|
super.updated(changedProperties);
|
|
309
|
-
if (changedProperties.
|
|
301
|
+
if (changedProperties.size > 0) {
|
|
310
302
|
this.frameTask.run();
|
|
311
303
|
}
|
|
312
304
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { EFTimegroup } from './EFTimegroup.
|
|
1
|
+
import { LitElement, ReactiveController } from 'lit';
|
|
2
|
+
import { EFTimegroup } from './EFTimegroup.js';
|
|
3
3
|
export declare class TimegroupController implements ReactiveController {
|
|
4
4
|
private host;
|
|
5
5
|
private child;
|
package/dist/elements/util.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
-
declare const TestContext_base: (new (...args: any[]) => import('./ContextMixin.
|
|
2
|
+
declare const TestContext_base: (new (...args: any[]) => import('./ContextMixin.js').ContextMixinInterface) & typeof LitElement;
|
|
3
3
|
declare class TestContext extends TestContext_base {
|
|
4
4
|
}
|
|
5
5
|
declare global {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
import { createRef } from 'lit/directives/ref.js';
|
|
3
|
-
import { EFTimegroup } from '../elements/EFTimegroup.
|
|
3
|
+
import { EFTimegroup } from '../elements/EFTimegroup.js';
|
|
4
4
|
export declare class ContextMixinInterface extends LitElement {
|
|
5
5
|
signingURL?: string;
|
|
6
6
|
apiHost?: string;
|
|
@@ -83,14 +83,14 @@ function ContextMixin(superClass) {
|
|
|
83
83
|
const scale = stageHeight / canvasHeight;
|
|
84
84
|
if (this.stageScale !== scale) {
|
|
85
85
|
canvasElement.style.transform = `scale(${scale})`;
|
|
86
|
-
canvasElement.style.transformOrigin = "
|
|
86
|
+
canvasElement.style.transformOrigin = "center";
|
|
87
87
|
}
|
|
88
88
|
this.stageScale = scale;
|
|
89
89
|
} else {
|
|
90
90
|
const scale = stageWidth / canvasWidth;
|
|
91
91
|
if (this.stageScale !== scale) {
|
|
92
92
|
canvasElement.style.transform = `scale(${scale})`;
|
|
93
|
-
canvasElement.style.transformOrigin = "
|
|
93
|
+
canvasElement.style.transformOrigin = "center";
|
|
94
94
|
}
|
|
95
95
|
this.stageScale = scale;
|
|
96
96
|
}
|
|
@@ -187,6 +187,12 @@ function ContextMixin(superClass) {
|
|
|
187
187
|
}
|
|
188
188
|
await timegroup.waitForMediaDurations();
|
|
189
189
|
let currentMs = timegroup.currentTimeMs;
|
|
190
|
+
const fromMs = currentMs;
|
|
191
|
+
const toMs = timegroup.endTimeMs;
|
|
192
|
+
if (fromMs >= toMs) {
|
|
193
|
+
this.pause();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
190
196
|
let bufferCount = 0;
|
|
191
197
|
this.#playbackAudioContext = new AudioContext({
|
|
192
198
|
latencyHint: "playback"
|
|
@@ -213,8 +219,6 @@ function ContextMixin(superClass) {
|
|
|
213
219
|
fillBuffer();
|
|
214
220
|
}
|
|
215
221
|
};
|
|
216
|
-
const fromMs = currentMs;
|
|
217
|
-
const toMs = timegroup.endTimeMs;
|
|
218
222
|
const queueBufferSource = async () => {
|
|
219
223
|
if (currentMs >= toMs) {
|
|
220
224
|
return false;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { LitElement, PropertyValueMap, ReactiveController, TemplateResult, nothing } from 'lit';
|
|
2
|
-
import { EFAudio } from '../elements/EFAudio.
|
|
3
|
-
import { EFImage } from '../elements/EFImage.
|
|
4
|
-
import { TemporalMixinInterface } from '../elements/EFTemporal.
|
|
5
|
-
import { EFTimegroup } from '../elements/EFTimegroup.
|
|
6
|
-
import { EFVideo } from '../elements/EFVideo.
|
|
7
|
-
import { TimegroupController } from '../elements/TimegroupController.
|
|
8
|
-
import { FocusContext } from './focusContext.
|
|
2
|
+
import { EFAudio } from '../elements/EFAudio.js';
|
|
3
|
+
import { EFImage } from '../elements/EFImage.js';
|
|
4
|
+
import { TemporalMixinInterface } from '../elements/EFTemporal.js';
|
|
5
|
+
import { EFTimegroup } from '../elements/EFTimegroup.js';
|
|
6
|
+
import { EFVideo } from '../elements/EFVideo.js';
|
|
7
|
+
import { TimegroupController } from '../elements/TimegroupController.js';
|
|
8
|
+
import { FocusContext } from './focusContext.js';
|
|
9
9
|
declare class ElementFilmstripController implements ReactiveController {
|
|
10
10
|
private host;
|
|
11
11
|
private filmstrip;
|