@editframe/elements 0.21.0-beta.0 → 0.23.7-beta.0
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.js +2 -3
- package/dist/attachContextRoot.d.ts +1 -0
- package/dist/attachContextRoot.js +9 -0
- package/dist/elements/ContextProxiesController.d.ts +1 -2
- package/dist/elements/EFAudio.js +2 -2
- package/dist/elements/EFCaptions.d.ts +1 -3
- package/dist/elements/EFCaptions.js +59 -51
- package/dist/elements/EFImage.js +2 -2
- package/dist/elements/EFMedia/AssetIdMediaEngine.js +1 -2
- package/dist/elements/EFMedia/AssetMediaEngine.js +1 -3
- package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +1 -1
- package/dist/elements/EFMedia/BufferedSeekingInput.js +2 -4
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +4 -7
- package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +1 -2
- package/dist/elements/EFMedia/shared/AudioSpanUtils.js +5 -9
- package/dist/elements/EFMedia/shared/BufferUtils.js +1 -3
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +4 -7
- package/dist/elements/EFMedia.d.ts +19 -0
- package/dist/elements/EFMedia.js +19 -2
- package/dist/elements/EFSourceMixin.js +1 -1
- package/dist/elements/EFSurface.js +1 -1
- package/dist/elements/EFTemporal.browsertest.d.ts +11 -0
- package/dist/elements/EFTemporal.d.ts +10 -0
- package/dist/elements/EFTemporal.js +82 -5
- package/dist/elements/EFThumbnailStrip.js +9 -16
- package/dist/elements/EFTimegroup.browsertest.d.ts +3 -3
- package/dist/elements/EFTimegroup.d.ts +35 -14
- package/dist/elements/EFTimegroup.js +73 -120
- package/dist/elements/EFVideo.d.ts +10 -0
- package/dist/elements/EFVideo.js +15 -2
- package/dist/elements/EFWaveform.js +10 -18
- package/dist/elements/SampleBuffer.js +1 -2
- package/dist/elements/TargetController.js +2 -2
- package/dist/elements/renderTemporalAudio.d.ts +10 -0
- package/dist/elements/renderTemporalAudio.js +35 -0
- package/dist/elements/updateAnimations.js +7 -10
- package/dist/gui/ContextMixin.d.ts +5 -5
- package/dist/gui/ContextMixin.js +151 -117
- package/dist/gui/Controllable.browsertest.d.ts +0 -0
- package/dist/gui/Controllable.d.ts +15 -0
- package/dist/gui/Controllable.js +9 -0
- package/dist/gui/EFConfiguration.js +1 -1
- package/dist/gui/EFControls.browsertest.d.ts +11 -0
- package/dist/gui/EFControls.d.ts +18 -4
- package/dist/gui/EFControls.js +67 -25
- package/dist/gui/EFDial.browsertest.d.ts +0 -0
- package/dist/gui/EFDial.d.ts +18 -0
- package/dist/gui/EFDial.js +141 -0
- package/dist/gui/EFFilmstrip.browsertest.d.ts +11 -0
- package/dist/gui/EFFilmstrip.d.ts +12 -2
- package/dist/gui/EFFilmstrip.js +140 -34
- package/dist/gui/EFFitScale.js +2 -4
- package/dist/gui/EFFocusOverlay.js +1 -1
- package/dist/gui/EFPause.browsertest.d.ts +0 -0
- package/dist/gui/EFPause.d.ts +23 -0
- package/dist/gui/EFPause.js +59 -0
- package/dist/gui/EFPlay.browsertest.d.ts +0 -0
- package/dist/gui/EFPlay.d.ts +23 -0
- package/dist/gui/EFPlay.js +59 -0
- package/dist/gui/EFPreview.d.ts +4 -0
- package/dist/gui/EFPreview.js +15 -6
- package/dist/gui/EFResizableBox.browsertest.d.ts +0 -0
- package/dist/gui/EFResizableBox.d.ts +34 -0
- package/dist/gui/EFResizableBox.js +547 -0
- package/dist/gui/EFScrubber.d.ts +9 -3
- package/dist/gui/EFScrubber.js +7 -7
- package/dist/gui/EFTimeDisplay.d.ts +7 -1
- package/dist/gui/EFTimeDisplay.js +5 -5
- package/dist/gui/EFToggleLoop.d.ts +9 -3
- package/dist/gui/EFToggleLoop.js +6 -4
- package/dist/gui/EFTogglePlay.d.ts +12 -4
- package/dist/gui/EFTogglePlay.js +24 -19
- package/dist/gui/EFWorkbench.js +1 -1
- package/dist/gui/PlaybackController.d.ts +67 -0
- package/dist/gui/PlaybackController.js +310 -0
- package/dist/gui/TWMixin.js +1 -1
- package/dist/gui/TargetOrContextMixin.d.ts +10 -0
- package/dist/gui/TargetOrContextMixin.js +98 -0
- package/dist/gui/efContext.d.ts +2 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -1
- package/dist/otel/setupBrowserTracing.d.ts +1 -1
- package/dist/otel/setupBrowserTracing.js +6 -4
- package/dist/otel/tracingHelpers.js +1 -2
- package/dist/style.css +1 -1
- package/package.json +5 -5
- package/src/elements/ContextProxiesController.ts +10 -10
- package/src/elements/EFAudio.ts +1 -0
- package/src/elements/EFCaptions.browsertest.ts +128 -58
- package/src/elements/EFCaptions.ts +60 -34
- package/src/elements/EFImage.browsertest.ts +1 -2
- package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +3 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.ts +1 -1
- package/src/elements/EFMedia.browsertest.ts +8 -15
- package/src/elements/EFMedia.ts +38 -7
- package/src/elements/EFSurface.browsertest.ts +2 -6
- package/src/elements/EFSurface.ts +1 -0
- package/src/elements/EFTemporal.browsertest.ts +58 -1
- package/src/elements/EFTemporal.ts +140 -4
- package/src/elements/EFThumbnailStrip.browsertest.ts +2 -8
- package/src/elements/EFThumbnailStrip.ts +1 -0
- package/src/elements/EFTimegroup.browsertest.ts +6 -7
- package/src/elements/EFTimegroup.ts +163 -244
- package/src/elements/EFVideo.browsertest.ts +143 -47
- package/src/elements/EFVideo.ts +26 -0
- package/src/elements/FetchContext.browsertest.ts +7 -2
- package/src/elements/TargetController.browsertest.ts +1 -0
- package/src/elements/TargetController.ts +1 -0
- package/src/elements/renderTemporalAudio.ts +108 -0
- package/src/elements/updateAnimations.browsertest.ts +181 -6
- package/src/elements/updateAnimations.ts +6 -6
- package/src/gui/ContextMixin.browsertest.ts +274 -27
- package/src/gui/ContextMixin.ts +230 -175
- package/src/gui/Controllable.browsertest.ts +258 -0
- package/src/gui/Controllable.ts +41 -0
- package/src/gui/EFControls.browsertest.ts +294 -80
- package/src/gui/EFControls.ts +139 -28
- package/src/gui/EFDial.browsertest.ts +84 -0
- package/src/gui/EFDial.ts +172 -0
- package/src/gui/EFFilmstrip.browsertest.ts +712 -0
- package/src/gui/EFFilmstrip.ts +213 -23
- package/src/gui/EFPause.browsertest.ts +202 -0
- package/src/gui/EFPause.ts +73 -0
- package/src/gui/EFPlay.browsertest.ts +202 -0
- package/src/gui/EFPlay.ts +73 -0
- package/src/gui/EFPreview.ts +20 -5
- package/src/gui/EFResizableBox.browsertest.ts +79 -0
- package/src/gui/EFResizableBox.ts +898 -0
- package/src/gui/EFScrubber.ts +7 -5
- package/src/gui/EFTimeDisplay.browsertest.ts +19 -19
- package/src/gui/EFTimeDisplay.ts +3 -1
- package/src/gui/EFToggleLoop.ts +6 -5
- package/src/gui/EFTogglePlay.ts +30 -23
- package/src/gui/PlaybackController.ts +522 -0
- package/src/gui/TWMixin.css +3 -0
- package/src/gui/TargetOrContextMixin.ts +185 -0
- package/src/gui/efContext.ts +2 -2
- package/src/otel/setupBrowserTracing.ts +17 -12
- package/test/cache-integration-verification.browsertest.ts +1 -1
- package/types.json +1 -1
- package/dist/elements/ContextProxiesController.js +0 -49
- /package/dist/_virtual/{_@oxc-project_runtime@0.93.0 → _@oxc-project_runtime@0.94.0}/helpers/decorate.js +0 -0
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { Task } from '@lit/task';
|
|
2
2
|
import { LitElement, ReactiveController } from 'lit';
|
|
3
|
+
import { PlaybackController } from '../gui/PlaybackController.js';
|
|
3
4
|
import { EFTimegroup } from './EFTimegroup.js';
|
|
4
5
|
export declare const timegroupContext: {
|
|
5
6
|
__context__: EFTimegroup;
|
|
6
7
|
};
|
|
7
8
|
export declare class TemporalMixinInterface {
|
|
9
|
+
playbackController?: PlaybackController;
|
|
10
|
+
playing: boolean;
|
|
11
|
+
loop: boolean;
|
|
12
|
+
play(): void;
|
|
13
|
+
pause(): void;
|
|
8
14
|
get hasOwnDuration(): boolean;
|
|
9
15
|
/**
|
|
10
16
|
* Whether the element has a duration set as an attribute.
|
|
@@ -137,6 +143,7 @@ export declare class TemporalMixinInterface {
|
|
|
137
143
|
* For other temporal elements: their ownCurrentTimeMs
|
|
138
144
|
*/
|
|
139
145
|
get currentTimeMs(): number;
|
|
146
|
+
set currentTimeMs(value: number);
|
|
140
147
|
/**
|
|
141
148
|
* The current time of the element in milliseconds, adjusted for trimming.
|
|
142
149
|
*
|
|
@@ -185,6 +192,9 @@ export declare class TemporalMixinInterface {
|
|
|
185
192
|
*/
|
|
186
193
|
rootTimegroup?: EFTimegroup;
|
|
187
194
|
frameTask: Task<readonly unknown[], unknown>;
|
|
195
|
+
didBecomeRoot(): void;
|
|
196
|
+
didBecomeChild(): void;
|
|
197
|
+
updateComplete: Promise<boolean>;
|
|
188
198
|
}
|
|
189
199
|
export declare const isEFTemporal: (obj: any) => obj is TemporalMixinInterface;
|
|
190
200
|
export declare const deepGetTemporalElements: (element: Element, temporals?: Array<TemporalMixinInterface & HTMLElement>) => (TemporalMixinInterface & HTMLElement)[];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
2
|
-
import {
|
|
2
|
+
import { PlaybackController } from "../gui/PlaybackController.js";
|
|
3
3
|
import { durationConverter } from "./durationConverter.js";
|
|
4
|
+
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
|
|
4
5
|
import { consume, createContext } from "@lit/context";
|
|
5
6
|
import { Task } from "@lit/task";
|
|
6
7
|
import { property, state } from "lit/decorators.js";
|
|
@@ -79,18 +80,63 @@ const EFTemporal = (superClass) => {
|
|
|
79
80
|
}
|
|
80
81
|
#parentTimegroup;
|
|
81
82
|
set parentTimegroup(value) {
|
|
83
|
+
const oldParent = this.#parentTimegroup;
|
|
82
84
|
this.#parentTimegroup = value;
|
|
83
85
|
this.ownCurrentTimeController?.remove();
|
|
84
86
|
this.rootTimegroup = this.getRootTimegroup();
|
|
85
87
|
if (this.rootTimegroup) this.ownCurrentTimeController = new OwnCurrentTimeController(this.rootTimegroup, this);
|
|
88
|
+
if (oldParent !== value) if (!value) this.didBecomeRoot();
|
|
89
|
+
else this.didBecomeChild();
|
|
86
90
|
}
|
|
87
91
|
disconnectedCallback() {
|
|
88
92
|
super.disconnectedCallback();
|
|
89
93
|
this.ownCurrentTimeController?.remove();
|
|
94
|
+
if (this.playbackController) {
|
|
95
|
+
this.playbackController.remove();
|
|
96
|
+
this.playbackController = void 0;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
connectedCallback() {
|
|
100
|
+
super.connectedCallback();
|
|
101
|
+
if (!this.parentTimegroup) this.didBecomeRoot();
|
|
90
102
|
}
|
|
91
103
|
get parentTimegroup() {
|
|
92
104
|
return this.#parentTimegroup;
|
|
93
105
|
}
|
|
106
|
+
get playing() {
|
|
107
|
+
if (!this.playbackController) return false;
|
|
108
|
+
return this.playbackController.playing;
|
|
109
|
+
}
|
|
110
|
+
set playing(value) {
|
|
111
|
+
if (!this.playbackController) {
|
|
112
|
+
console.warn("Cannot set playing on non-root temporal element", this);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.playbackController.setPlaying(value);
|
|
116
|
+
}
|
|
117
|
+
play() {
|
|
118
|
+
if (!this.playbackController) {
|
|
119
|
+
console.warn("play() called on non-root temporal element", this);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
this.playbackController.play();
|
|
123
|
+
}
|
|
124
|
+
pause() {
|
|
125
|
+
if (!this.playbackController) {
|
|
126
|
+
console.warn("pause() called on non-root temporal element", this);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
this.playbackController.pause();
|
|
130
|
+
}
|
|
131
|
+
get loop() {
|
|
132
|
+
return this.playbackController?.loop ?? this.#loop;
|
|
133
|
+
}
|
|
134
|
+
set loop(value) {
|
|
135
|
+
const oldValue = this.#loop;
|
|
136
|
+
this.#loop = value;
|
|
137
|
+
if (this.playbackController) this.playbackController.setLoop(value);
|
|
138
|
+
this.requestUpdate("loop", oldValue);
|
|
139
|
+
}
|
|
94
140
|
set duration(value) {
|
|
95
141
|
if (value !== void 0) this.setAttribute("duration", value);
|
|
96
142
|
else this.removeAttribute("duration");
|
|
@@ -173,6 +219,7 @@ const EFTemporal = (superClass) => {
|
|
|
173
219
|
if (!this.parentTemporal) return 0;
|
|
174
220
|
return this.startTimeMs - this.parentTemporal.startTimeMs;
|
|
175
221
|
}
|
|
222
|
+
#loop = false;
|
|
176
223
|
get startTimeMs() {
|
|
177
224
|
const cachedStartTime = startTimeMsCache.get(this);
|
|
178
225
|
if (cachedStartTime !== void 0) return cachedStartTime;
|
|
@@ -212,22 +259,52 @@ const EFTemporal = (superClass) => {
|
|
|
212
259
|
get endTimeMs() {
|
|
213
260
|
return this.startTimeMs + this.durationMs;
|
|
214
261
|
}
|
|
262
|
+
#currentTimeMs = 0;
|
|
215
263
|
get ownCurrentTimeMs() {
|
|
216
|
-
if (this.
|
|
217
|
-
return 0;
|
|
264
|
+
if (this.playbackController) return Math.min(Math.max(0, this.playbackController.currentTimeMs), this.durationMs);
|
|
265
|
+
if (this.rootTimegroup && this.rootTimegroup !== this) return Math.min(Math.max(0, this.rootTimegroup.currentTimeMs - this.startTimeMs), this.durationMs);
|
|
266
|
+
return Math.min(Math.max(0, this.#currentTimeMs), this.durationMs);
|
|
218
267
|
}
|
|
219
268
|
get currentTimeMs() {
|
|
220
269
|
return this.ownCurrentTimeMs;
|
|
221
270
|
}
|
|
271
|
+
set currentTimeMs(value) {
|
|
272
|
+
if (this.playbackController) {
|
|
273
|
+
this.playbackController.currentTime = value / 1e3;
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (this.rootTimegroup && this.rootTimegroup !== this) this.rootTimegroup.currentTimeMs = value;
|
|
277
|
+
else {
|
|
278
|
+
this.#currentTimeMs = value;
|
|
279
|
+
this.requestUpdate("currentTimeMs");
|
|
280
|
+
}
|
|
281
|
+
}
|
|
222
282
|
get currentSourceTimeMs() {
|
|
223
283
|
const leadingTrimMs = this.sourceInMs || this.trimStartMs || 0;
|
|
224
284
|
return this.ownCurrentTimeMs + leadingTrimMs;
|
|
225
285
|
}
|
|
286
|
+
didBecomeRoot() {
|
|
287
|
+
if (!this.playbackController) {
|
|
288
|
+
this.playbackController = new PlaybackController(this);
|
|
289
|
+
if (this.#loop) this.playbackController.setLoop(this.#loop);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
didBecomeChild() {
|
|
293
|
+
if (this.playbackController) {
|
|
294
|
+
this.playbackController.remove();
|
|
295
|
+
this.playbackController = void 0;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
226
298
|
}
|
|
227
299
|
__decorate([consume({
|
|
228
300
|
context: timegroupContext,
|
|
229
301
|
subscribe: true
|
|
230
|
-
})
|
|
302
|
+
})], TemporalMixinClass.prototype, "parentTimegroup", null);
|
|
303
|
+
__decorate([property({
|
|
304
|
+
type: Boolean,
|
|
305
|
+
reflect: true,
|
|
306
|
+
attribute: "loop"
|
|
307
|
+
})], TemporalMixinClass.prototype, "loop", null);
|
|
231
308
|
__decorate([property({
|
|
232
309
|
type: String,
|
|
233
310
|
attribute: "offset",
|
|
@@ -267,4 +344,4 @@ const EFTemporal = (superClass) => {
|
|
|
267
344
|
Object.defineProperty(TemporalMixinClass.prototype, EF_TEMPORAL, { value: true });
|
|
268
345
|
return TemporalMixinClass;
|
|
269
346
|
};
|
|
270
|
-
export { EFTemporal, deepGetElementsWithFrameTasks, deepGetTemporalElements, flushStartTimeMsCache, resetTemporalCache, shallowGetTemporalElements, timegroupContext };
|
|
347
|
+
export { EFTemporal, deepGetElementsWithFrameTasks, deepGetTemporalElements, flushStartTimeMsCache, isEFTemporal, resetTemporalCache, shallowGetTemporalElements, timegroupContext };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
|
|
2
2
|
import { OrderedLRUCache } from "../utils/LRUCache.js";
|
|
3
3
|
import { TargetController } from "./TargetController.js";
|
|
4
4
|
import { Task } from "@lit/task";
|
|
@@ -8,9 +8,7 @@ import { createRef, ref } from "lit/directives/ref.js";
|
|
|
8
8
|
var thumbnailImageCache = new OrderedLRUCache(200, (a, b) => {
|
|
9
9
|
const partsA = a.split(":");
|
|
10
10
|
const partsB = b.split(":");
|
|
11
|
-
|
|
12
|
-
const timeB = Number.parseFloat(partsB[partsB.length - 1] || "0");
|
|
13
|
-
return timeA - timeB;
|
|
11
|
+
return Number.parseFloat(partsA[partsA.length - 1] || "0") - Number.parseFloat(partsB[partsB.length - 1] || "0");
|
|
14
12
|
});
|
|
15
13
|
globalThis.debugThumbnailCache = thumbnailImageCache;
|
|
16
14
|
function quantizeTimestamp(timeMs) {
|
|
@@ -18,8 +16,7 @@ function quantizeTimestamp(timeMs) {
|
|
|
18
16
|
return Math.round(timeMs / frameIntervalMs) * frameIntervalMs;
|
|
19
17
|
}
|
|
20
18
|
function getThumbnailCacheKey(videoSrc, timeMs) {
|
|
21
|
-
|
|
22
|
-
return `${videoSrc}:${quantizedTimeMs}`;
|
|
19
|
+
return `${videoSrc}:${quantizeTimestamp(timeMs)}`;
|
|
23
20
|
}
|
|
24
21
|
var THUMBNAIL_GAP = 1;
|
|
25
22
|
var STRIP_BORDER_PADDING = 4;
|
|
@@ -43,13 +40,12 @@ function calculateThumbnailLayout(stripWidth, thumbnailWidth, startTimeMs, endTi
|
|
|
43
40
|
if (!segmentMap.has(segmentId)) segmentMap.set(segmentId, []);
|
|
44
41
|
segmentMap.get(segmentId).push({ timeMs });
|
|
45
42
|
}
|
|
46
|
-
const segments = Array.from(segmentMap.entries()).sort(([a], [b]) => a - b).map(([segmentId, thumbnails]) => ({
|
|
47
|
-
segmentId,
|
|
48
|
-
thumbnails
|
|
49
|
-
}));
|
|
50
43
|
return {
|
|
51
44
|
count,
|
|
52
|
-
segments
|
|
45
|
+
segments: Array.from(segmentMap.entries()).sort(([a], [b]) => a - b).map(([segmentId, thumbnails]) => ({
|
|
46
|
+
segmentId,
|
|
47
|
+
thumbnails
|
|
48
|
+
}))
|
|
53
49
|
};
|
|
54
50
|
}
|
|
55
51
|
var EFThumbnailStrip = class EFThumbnailStrip$1 extends LitElement {
|
|
@@ -248,8 +244,7 @@ var EFThumbnailStrip = class EFThumbnailStrip$1 extends LitElement {
|
|
|
248
244
|
return this.generateLayoutFromTimeRange(stripWidth, thumbnailWidth, effectiveStartMs, effectiveEndMs, mediaEngine);
|
|
249
245
|
}
|
|
250
246
|
generateLayoutFromTimeRange(stripWidth, thumbnailWidth, effectiveStartMs, effectiveEndMs, mediaEngine) {
|
|
251
|
-
|
|
252
|
-
return calculateThumbnailLayout(stripWidth, thumbnailWidth, effectiveStartMs, effectiveEndMs, scrubSegmentDurationMs);
|
|
247
|
+
return calculateThumbnailLayout(stripWidth, thumbnailWidth, effectiveStartMs, effectiveEndMs, mediaEngine && typeof mediaEngine.getScrubVideoRendition === "function" ? mediaEngine.getScrubVideoRendition()?.segmentDurationMs : void 0);
|
|
253
248
|
}
|
|
254
249
|
async renderThumbnails(layout, targetElement, thumbnailWidth) {
|
|
255
250
|
if (!layout || !targetElement || layout.count === 0) return [];
|
|
@@ -274,9 +269,7 @@ var EFThumbnailStrip = class EFThumbnailStrip$1 extends LitElement {
|
|
|
274
269
|
const closestParts = closest.key.split(":");
|
|
275
270
|
const currentTime = Number.parseFloat(currentParts[currentParts.length - 1] || "0");
|
|
276
271
|
const closestTime = Number.parseFloat(closestParts[closestParts.length - 1] || "0");
|
|
277
|
-
|
|
278
|
-
const closestDiff = Math.abs(closestTime - thumbnail.timeMs);
|
|
279
|
-
return currentDiff < closestDiff ? current : closest;
|
|
272
|
+
return Math.abs(currentTime - thumbnail.timeMs) < Math.abs(closestTime - thumbnail.timeMs) ? current : closest;
|
|
280
273
|
});
|
|
281
274
|
imageData = nearestHit.value;
|
|
282
275
|
status = "near-hit";
|
|
@@ -12,17 +12,17 @@ declare class TimegroupTestMedia extends EFMedia {
|
|
|
12
12
|
declare const TestFrameTaskA_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
13
13
|
declare class TestFrameTaskA extends TestFrameTaskA_base {
|
|
14
14
|
frameTaskCount: number;
|
|
15
|
-
frameTask: Task<
|
|
15
|
+
frameTask: Task<readonly [], void>;
|
|
16
16
|
}
|
|
17
17
|
declare const TestFrameTaskB_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
18
18
|
declare class TestFrameTaskB extends TestFrameTaskB_base {
|
|
19
19
|
frameTaskCount: number;
|
|
20
|
-
frameTask: Task<
|
|
20
|
+
frameTask: Task<readonly [], void>;
|
|
21
21
|
}
|
|
22
22
|
declare const TestFrameTaskC_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
23
23
|
declare class TestFrameTaskC extends TestFrameTaskC_base {
|
|
24
24
|
frameTaskCount: number;
|
|
25
|
-
frameTask: Task<
|
|
25
|
+
frameTask: Task<readonly [], void>;
|
|
26
26
|
}
|
|
27
27
|
declare const TestTemporal_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
28
28
|
declare class TestTemporal extends TestTemporal_base {
|
|
@@ -1,35 +1,44 @@
|
|
|
1
1
|
import { Task } from '@lit/task';
|
|
2
2
|
import { LitElement, PropertyValues } from 'lit';
|
|
3
|
+
import { EFMedia } from './EFMedia.js';
|
|
4
|
+
declare global {
|
|
5
|
+
var EF_DEV_WORKBENCH: boolean | undefined;
|
|
6
|
+
}
|
|
3
7
|
export declare const flushSequenceDurationCache: () => void;
|
|
4
8
|
export declare const shallowGetTimegroups: (element: Element, groups?: EFTimegroup[]) => EFTimegroup[];
|
|
5
9
|
declare const EFTimegroup_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
|
|
6
10
|
export declare class EFTimegroup extends EFTimegroup_base {
|
|
7
11
|
#private;
|
|
12
|
+
static get observedAttributes(): string[];
|
|
8
13
|
static styles: import('lit').CSSResult;
|
|
9
14
|
_timeGroupContext: this;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
get overlapMs(): number;
|
|
15
|
-
private _overlapMs;
|
|
15
|
+
efContext: this;
|
|
16
|
+
mode: "fit" | "fixed" | "sequence" | "contain";
|
|
17
|
+
overlapMs: number;
|
|
18
|
+
attributeChangedCallback(name: string, old: string | null, value: string | null): void;
|
|
16
19
|
fit: "none" | "contain" | "cover";
|
|
17
|
-
/**
|
|
18
|
-
* Throttles frameTask execution to ensure only one runs at a time while preserving the last request
|
|
19
|
-
*/
|
|
20
20
|
private runThrottledFrameTask;
|
|
21
21
|
set currentTime(time: number);
|
|
22
22
|
get currentTime(): number;
|
|
23
23
|
set currentTimeMs(ms: number);
|
|
24
24
|
get currentTimeMs(): number;
|
|
25
|
+
/**
|
|
26
|
+
* Seek to a specific time and wait for all frames to be ready.
|
|
27
|
+
* This is the recommended way to seek in tests and programmatic control.
|
|
28
|
+
*
|
|
29
|
+
* @param timeMs - Time in milliseconds to seek to
|
|
30
|
+
* @returns Promise that resolves when the seek is complete and all visible children are ready
|
|
31
|
+
*/
|
|
32
|
+
seek(timeMs: number): Promise<void>;
|
|
25
33
|
/**
|
|
26
34
|
* Determines if this is a root timegroup (no parent timegroups)
|
|
27
35
|
*/
|
|
28
36
|
get isRootTimegroup(): boolean;
|
|
37
|
+
saveTimeToLocalStorage(time: number): void;
|
|
29
38
|
render(): import('lit-html').TemplateResult<1>;
|
|
30
|
-
|
|
39
|
+
loadTimeFromLocalStorage(): number | undefined;
|
|
31
40
|
connectedCallback(): void;
|
|
32
|
-
protected updated(
|
|
41
|
+
protected updated(changedProperties: PropertyValues): void;
|
|
33
42
|
disconnectedCallback(): void;
|
|
34
43
|
get storageKey(): string;
|
|
35
44
|
get intrinsicDurationMs(): number | undefined;
|
|
@@ -45,15 +54,27 @@ export declare class EFTimegroup extends EFTimegroup_base {
|
|
|
45
54
|
/**
|
|
46
55
|
* Returns true if the timegroup should be wrapped with a workbench.
|
|
47
56
|
*
|
|
48
|
-
* A timegroup should be wrapped with a workbench if
|
|
49
|
-
*
|
|
57
|
+
* A timegroup should be wrapped with a workbench if:
|
|
58
|
+
* - It's being rendered (EF_RENDERING), OR
|
|
59
|
+
* - It's in interactive mode (EF_INTERACTIVE) with the dev workbench flag set
|
|
50
60
|
*
|
|
51
|
-
* If the timegroup is already
|
|
61
|
+
* If the timegroup is already wrapped in a context provider like ef-preview,
|
|
52
62
|
* it should NOT be wrapped in a workbench.
|
|
53
63
|
*/
|
|
54
64
|
shouldWrapWithWorkbench(): boolean;
|
|
55
65
|
wrapWithWorkbench(): void;
|
|
56
66
|
get efElements(): Element[];
|
|
67
|
+
/**
|
|
68
|
+
* Returns media elements for playback audio rendering
|
|
69
|
+
* For standalone media, returns [this]; for timegroups, returns all descendants
|
|
70
|
+
* Used by PlaybackController for audio-driven playback
|
|
71
|
+
*/
|
|
72
|
+
getMediaElements(): EFMedia[];
|
|
73
|
+
/**
|
|
74
|
+
* Render audio buffer for playback
|
|
75
|
+
* Called by PlaybackController during live playback
|
|
76
|
+
* Delegates to shared renderTemporalAudio utility for consistent behavior
|
|
77
|
+
*/
|
|
57
78
|
renderAudio(fromMs: number, toMs: number): Promise<AudioBuffer>;
|
|
58
79
|
/**
|
|
59
80
|
* TEMPORARY TEST METHOD: Renders audio and immediately plays it back
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
2
|
-
import {
|
|
2
|
+
import { EF_RENDERING } from "../EF_RENDERING.js";
|
|
3
|
+
import { parseTimeToMs } from "./parseTimeToMs.js";
|
|
4
|
+
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
|
|
5
|
+
import { EFTemporal, deepGetElementsWithFrameTasks, flushStartTimeMsCache, resetTemporalCache, shallowGetTemporalElements, timegroupContext } from "./EFTemporal.js";
|
|
6
|
+
import { efContext } from "../gui/efContext.js";
|
|
3
7
|
import { isContextMixin } from "../gui/ContextMixin.js";
|
|
8
|
+
import { TWMixin } from "../gui/TWMixin2.js";
|
|
4
9
|
import { isTracingEnabled, withSpan } from "../otel/tracingHelpers.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
10
|
+
import { renderTemporalAudio } from "./renderTemporalAudio.js";
|
|
11
|
+
import { EFTargetable } from "./TargetController.js";
|
|
7
12
|
import { deepGetMediaElements } from "./EFMedia.js";
|
|
8
13
|
import { TimegroupController } from "./TimegroupController.js";
|
|
9
14
|
import { evaluateTemporalStateForAnimation, updateAnimations } from "./updateAnimations.js";
|
|
@@ -23,15 +28,16 @@ const shallowGetTimegroups = (element, groups = []) => {
|
|
|
23
28
|
else shallowGetTimegroups(child, groups);
|
|
24
29
|
return groups;
|
|
25
30
|
};
|
|
26
|
-
var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
31
|
+
var EFTimegroup = class EFTimegroup$1 extends EFTargetable(EFTemporal(TWMixin(LitElement))) {
|
|
27
32
|
static {
|
|
28
33
|
_EFTimegroup = this;
|
|
29
34
|
}
|
|
30
35
|
constructor(..._args) {
|
|
31
36
|
super(..._args);
|
|
32
37
|
this._timeGroupContext = this;
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
38
|
+
this.efContext = this;
|
|
39
|
+
this.mode = "contain";
|
|
40
|
+
this.overlapMs = 0;
|
|
35
41
|
this.fit = "none";
|
|
36
42
|
this.mediaDurationsPromise = void 0;
|
|
37
43
|
this.frameTask = new Task(this, {
|
|
@@ -53,6 +59,10 @@ var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
|
53
59
|
args: () => [this.#pendingSeekTime ?? this.#currentTime],
|
|
54
60
|
onComplete: () => {},
|
|
55
61
|
task: async ([targetTime]) => {
|
|
62
|
+
if (this.playbackController) {
|
|
63
|
+
await this.playbackController.seekTask.taskComplete;
|
|
64
|
+
return this.currentTime;
|
|
65
|
+
}
|
|
56
66
|
if (!this.isRootTimegroup) return;
|
|
57
67
|
return withSpan("timegroup.seekTask", {
|
|
58
68
|
timegroupId: this.id || "unknown",
|
|
@@ -65,71 +75,60 @@ var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
|
65
75
|
this.#currentTime = newTime;
|
|
66
76
|
this.requestUpdate("currentTime");
|
|
67
77
|
await this.runThrottledFrameTask();
|
|
68
|
-
this
|
|
78
|
+
this.saveTimeToLocalStorage(this.#currentTime);
|
|
69
79
|
this.#seekInProgress = false;
|
|
70
80
|
return newTime;
|
|
71
81
|
});
|
|
72
82
|
}
|
|
73
83
|
});
|
|
74
84
|
}
|
|
85
|
+
static get observedAttributes() {
|
|
86
|
+
return [
|
|
87
|
+
...super.observedAttributes || [],
|
|
88
|
+
"mode",
|
|
89
|
+
"overlap",
|
|
90
|
+
"currenttime",
|
|
91
|
+
"fit"
|
|
92
|
+
];
|
|
93
|
+
}
|
|
75
94
|
static {
|
|
76
95
|
this.styles = css`
|
|
77
96
|
:host {
|
|
78
97
|
display: block;
|
|
98
|
+
position: relative;
|
|
99
|
+
overflow: hidden;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
::slotted(ef-timegroup) {
|
|
103
|
+
position: absolute;
|
|
79
104
|
width: 100%;
|
|
80
105
|
height: 100%;
|
|
81
|
-
position: absolute;
|
|
82
106
|
top: 0;
|
|
83
107
|
left: 0;
|
|
108
|
+
overflow: initial;
|
|
84
109
|
}
|
|
85
110
|
`;
|
|
86
111
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
get mode() {
|
|
93
|
-
return this._mode;
|
|
94
|
-
}
|
|
95
|
-
set overlapMs(value) {
|
|
96
|
-
sequenceDurationCache.delete(this);
|
|
97
|
-
this._overlapMs = value;
|
|
98
|
-
}
|
|
99
|
-
get overlapMs() {
|
|
100
|
-
return this._overlapMs;
|
|
112
|
+
attributeChangedCallback(name, old, value) {
|
|
113
|
+
if (name === "mode" && value) this.mode = value;
|
|
114
|
+
if (name === "overlap" && value) this.overlapMs = parseTimeToMs(value);
|
|
115
|
+
super.attributeChangedCallback(name, old, value);
|
|
101
116
|
}
|
|
102
117
|
#resizeObserver;
|
|
118
|
+
#currentTime = void 0;
|
|
103
119
|
#seekInProgress = false;
|
|
104
120
|
#pendingSeekTime;
|
|
105
121
|
#processingPendingSeek = false;
|
|
106
|
-
#frameTaskInProgress = false;
|
|
107
|
-
#pendingFrameTaskRun = false;
|
|
108
|
-
#processingPendingFrameTask = false;
|
|
109
122
|
async runThrottledFrameTask() {
|
|
110
|
-
if (this
|
|
111
|
-
|
|
112
|
-
while (this.#frameTaskInProgress) await this.frameTask.taskComplete;
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
this.#frameTaskInProgress = true;
|
|
116
|
-
try {
|
|
117
|
-
await this.frameTask.run();
|
|
118
|
-
} finally {
|
|
119
|
-
this.#frameTaskInProgress = false;
|
|
120
|
-
if (this.#pendingFrameTaskRun && !this.#processingPendingFrameTask) {
|
|
121
|
-
this.#pendingFrameTaskRun = false;
|
|
122
|
-
this.#processingPendingFrameTask = true;
|
|
123
|
-
try {
|
|
124
|
-
await this.runThrottledFrameTask();
|
|
125
|
-
} finally {
|
|
126
|
-
this.#processingPendingFrameTask = false;
|
|
127
|
-
}
|
|
128
|
-
} else this.#pendingFrameTaskRun = false;
|
|
129
|
-
}
|
|
123
|
+
if (this.playbackController) return this.playbackController.runThrottledFrameTask();
|
|
124
|
+
await this.frameTask.run();
|
|
130
125
|
}
|
|
131
126
|
set currentTime(time) {
|
|
132
|
-
|
|
127
|
+
if (this.playbackController) {
|
|
128
|
+
this.playbackController.currentTime = time;
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
time = Math.max(0, Math.min(this.durationMs / 1e3, time));
|
|
133
132
|
if (!this.isRootTimegroup) return;
|
|
134
133
|
if (Number.isNaN(time)) return;
|
|
135
134
|
if (time === this.#currentTime && !this.#processingPendingSeek) return;
|
|
@@ -155,6 +154,7 @@ var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
|
155
154
|
});
|
|
156
155
|
}
|
|
157
156
|
get currentTime() {
|
|
157
|
+
if (this.playbackController) return this.playbackController.currentTime;
|
|
158
158
|
return this.#currentTime ?? 0;
|
|
159
159
|
}
|
|
160
160
|
set currentTimeMs(ms) {
|
|
@@ -163,10 +163,23 @@ var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
|
163
163
|
get currentTimeMs() {
|
|
164
164
|
return this.currentTime * 1e3;
|
|
165
165
|
}
|
|
166
|
+
async seek(timeMs) {
|
|
167
|
+
this.currentTimeMs = timeMs;
|
|
168
|
+
await this.seekTask.taskComplete;
|
|
169
|
+
if (this.playbackController) this.saveTimeToLocalStorage(this.currentTime);
|
|
170
|
+
await this.frameTask.taskComplete;
|
|
171
|
+
const visibleElements = deepGetElementsWithFrameTasks(this).filter((element) => {
|
|
172
|
+
return evaluateTemporalStateForAnimation(element).isVisible;
|
|
173
|
+
});
|
|
174
|
+
await Promise.all(visibleElements.map(async (element) => {
|
|
175
|
+
if ("waitForFrameReady" in element && typeof element.waitForFrameReady === "function") await element.waitForFrameReady();
|
|
176
|
+
else await element.updateComplete;
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
166
179
|
get isRootTimegroup() {
|
|
167
180
|
return !this.parentTimegroup;
|
|
168
181
|
}
|
|
169
|
-
|
|
182
|
+
saveTimeToLocalStorage(time) {
|
|
170
183
|
try {
|
|
171
184
|
if (this.id && this.isConnected && !Number.isNaN(time)) localStorage.setItem(this.storageKey, time.toString());
|
|
172
185
|
} catch (error) {
|
|
@@ -182,7 +195,7 @@ var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
|
182
195
|
flushStartTimeMsCache();
|
|
183
196
|
this.requestUpdate();
|
|
184
197
|
};
|
|
185
|
-
|
|
198
|
+
loadTimeFromLocalStorage() {
|
|
186
199
|
if (this.id) try {
|
|
187
200
|
const storedValue = localStorage.getItem(this.storageKey);
|
|
188
201
|
if (storedValue === null) return;
|
|
@@ -193,9 +206,9 @@ var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
|
193
206
|
}
|
|
194
207
|
connectedCallback() {
|
|
195
208
|
super.connectedCallback();
|
|
196
|
-
this.waitForMediaDurations().then(() => {
|
|
209
|
+
if (!this.playbackController) this.waitForMediaDurations().then(() => {
|
|
197
210
|
if (this.id) {
|
|
198
|
-
const maybeLoadedTime = this.
|
|
211
|
+
const maybeLoadedTime = this.loadTimeFromLocalStorage();
|
|
199
212
|
if (maybeLoadedTime !== void 0) this.currentTime = maybeLoadedTime;
|
|
200
213
|
}
|
|
201
214
|
if (EF_INTERACTIVE && this.seekTask.status === TaskStatus.INITIAL) this.seekTask.run();
|
|
@@ -204,7 +217,9 @@ var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
|
204
217
|
if (this.shouldWrapWithWorkbench()) this.wrapWithWorkbench();
|
|
205
218
|
}
|
|
206
219
|
#previousDurationMs = 0;
|
|
207
|
-
updated(
|
|
220
|
+
updated(changedProperties) {
|
|
221
|
+
super.updated(changedProperties);
|
|
222
|
+
if (changedProperties.has("mode") || changedProperties.has("overlapMs")) sequenceDurationCache.delete(this);
|
|
208
223
|
if (this.#previousDurationMs !== this.durationMs) {
|
|
209
224
|
this.#previousDurationMs = this.durationMs;
|
|
210
225
|
this.runThrottledFrameTask();
|
|
@@ -338,6 +353,8 @@ var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
|
338
353
|
return null;
|
|
339
354
|
}
|
|
340
355
|
shouldWrapWithWorkbench() {
|
|
356
|
+
if (EF_RENDERING?.() === true) return this.closest("ef-timegroup") === this && this.closest("ef-preview") === null && this.closest("ef-workbench") === null && this.closest("test-context") === null;
|
|
357
|
+
if (!globalThis.EF_DEV_WORKBENCH) return false;
|
|
341
358
|
return EF_INTERACTIVE && this.closest("ef-timegroup") === this && this.closest("ef-preview") === null && this.closest("ef-workbench") === null && this.closest("test-context") === null;
|
|
342
359
|
}
|
|
343
360
|
wrapWithWorkbench() {
|
|
@@ -354,67 +371,11 @@ var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
|
354
371
|
get efElements() {
|
|
355
372
|
return Array.from(this.querySelectorAll("ef-audio, ef-video, ef-image, ef-captions, ef-waveform"));
|
|
356
373
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
const abortController = new AbortController();
|
|
360
|
-
await Promise.all(deepGetMediaElements(this).map(async (mediaElement) => {
|
|
361
|
-
if (mediaElement.mute) return;
|
|
362
|
-
const mediaStartsBeforeEnd = mediaElement.startTimeMs <= toMs;
|
|
363
|
-
const mediaEndsAfterStart = mediaElement.endTimeMs >= fromMs;
|
|
364
|
-
if (!(mediaStartsBeforeEnd && mediaEndsAfterStart)) return;
|
|
365
|
-
const mediaLocalFromMs = Math.max(0, fromMs - mediaElement.startTimeMs);
|
|
366
|
-
const mediaLocalToMs = Math.min(mediaElement.endTimeMs - mediaElement.startTimeMs, toMs - mediaElement.startTimeMs);
|
|
367
|
-
if (mediaLocalFromMs >= mediaLocalToMs) return;
|
|
368
|
-
const sourceInMs = mediaElement.sourceInMs || mediaElement.trimStartMs || 0;
|
|
369
|
-
const mediaSourceFromMs = mediaLocalFromMs + sourceInMs;
|
|
370
|
-
const mediaSourceToMs = mediaLocalToMs + sourceInMs;
|
|
371
|
-
let audio;
|
|
372
|
-
try {
|
|
373
|
-
audio = await mediaElement.fetchAudioSpanningTime(mediaSourceFromMs, mediaSourceToMs, abortController.signal);
|
|
374
|
-
} catch (error) {
|
|
375
|
-
if (error instanceof Error && error.message.includes("No audio track available")) return;
|
|
376
|
-
throw error;
|
|
377
|
-
}
|
|
378
|
-
if (!audio) return;
|
|
379
|
-
const bufferSource = audioContext.createBufferSource();
|
|
380
|
-
bufferSource.buffer = await audioContext.decodeAudioData(await audio.blob.arrayBuffer());
|
|
381
|
-
bufferSource.connect(audioContext.destination);
|
|
382
|
-
const ctxStartMs = Math.max(0, mediaElement.startTimeMs - fromMs);
|
|
383
|
-
const requestedSourceFromMs = mediaSourceFromMs;
|
|
384
|
-
const actualSourceStartMs = audio.startMs;
|
|
385
|
-
const offsetInBufferMs = requestedSourceFromMs - actualSourceStartMs;
|
|
386
|
-
const safeOffsetMs = Math.max(0, offsetInBufferMs);
|
|
387
|
-
const requestedDurationMs = mediaSourceToMs - mediaSourceFromMs;
|
|
388
|
-
const availableAudioMs = audio.endMs - audio.startMs;
|
|
389
|
-
const actualDurationMs = Math.min(requestedDurationMs, availableAudioMs - safeOffsetMs);
|
|
390
|
-
if (actualDurationMs <= 0) return;
|
|
391
|
-
bufferSource.start(ctxStartMs / 1e3, safeOffsetMs / 1e3, actualDurationMs / 1e3);
|
|
392
|
-
}));
|
|
374
|
+
getMediaElements() {
|
|
375
|
+
return deepGetMediaElements(this);
|
|
393
376
|
}
|
|
394
377
|
async renderAudio(fromMs, toMs) {
|
|
395
|
-
return
|
|
396
|
-
timegroupId: this.id || "unknown",
|
|
397
|
-
fromMs,
|
|
398
|
-
toMs,
|
|
399
|
-
durationMs: toMs - fromMs
|
|
400
|
-
}, void 0, async (span) => {
|
|
401
|
-
const aacFrames = 48e3 * ((toMs - fromMs) / 1e3) / 1024;
|
|
402
|
-
const alignedFrames = Math.round(aacFrames);
|
|
403
|
-
const contextSize = alignedFrames * 1024;
|
|
404
|
-
if (isTracingEnabled()) {
|
|
405
|
-
span.setAttribute("contextSize", contextSize);
|
|
406
|
-
span.setAttribute("alignedFrames", alignedFrames);
|
|
407
|
-
}
|
|
408
|
-
if (contextSize <= 0) throw new Error(`Duration must be greater than 0 when rendering audio. ${contextSize}ms`);
|
|
409
|
-
let audioContext;
|
|
410
|
-
try {
|
|
411
|
-
audioContext = new OfflineAudioContext(2, contextSize, 48e3);
|
|
412
|
-
} catch (error) {
|
|
413
|
-
throw new Error(`[EFTimegroup.renderAudio] Failed to create OfflineAudioContext(2, ${contextSize}, 48000) for renderAudio(${fromMs}, ${toMs}) with contextSize=${contextSize}: ${error instanceof Error ? error.message : String(error)}. This typically happens when audio parameters are invalid (e.g., contextSize <= 0).`);
|
|
414
|
-
}
|
|
415
|
-
await this.#addAudioToContext(audioContext, fromMs, toMs);
|
|
416
|
-
return await audioContext.startRendering();
|
|
417
|
-
});
|
|
378
|
+
return renderTemporalAudio(this, fromMs, toMs);
|
|
418
379
|
}
|
|
419
380
|
async testPlayAudio(fromMs, toMs) {
|
|
420
381
|
const renderedBuffer = await this.renderAudio(fromMs, toMs);
|
|
@@ -441,21 +402,13 @@ var EFTimegroup = class EFTimegroup$1 extends EFTemporal(LitElement) {
|
|
|
441
402
|
}
|
|
442
403
|
}
|
|
443
404
|
await Promise.all(loaderTasks);
|
|
444
|
-
efElements.
|
|
405
|
+
efElements.forEach((el) => {
|
|
445
406
|
if ("productionSrc" in el && el.productionSrc instanceof Function) el.setAttribute("src", el.productionSrc());
|
|
446
407
|
});
|
|
447
408
|
}
|
|
448
409
|
};
|
|
449
410
|
__decorate([provide({ context: timegroupContext })], EFTimegroup.prototype, "_timeGroupContext", void 0);
|
|
450
|
-
__decorate([
|
|
451
|
-
type: String,
|
|
452
|
-
attribute: "mode"
|
|
453
|
-
})], EFTimegroup.prototype, "mode", null);
|
|
454
|
-
__decorate([property({
|
|
455
|
-
type: Number,
|
|
456
|
-
converter: durationConverter,
|
|
457
|
-
attribute: "overlap"
|
|
458
|
-
})], EFTimegroup.prototype, "overlapMs", null);
|
|
411
|
+
__decorate([provide({ context: efContext })], EFTimegroup.prototype, "efContext", void 0);
|
|
459
412
|
__decorate([property({ type: String })], EFTimegroup.prototype, "fit", void 0);
|
|
460
413
|
__decorate([property({
|
|
461
414
|
type: Number,
|