@editframe/elements 0.18.27-beta.0 → 0.19.4-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.
Files changed (73) hide show
  1. package/dist/elements/EFMedia/AssetMediaEngine.d.ts +10 -0
  2. package/dist/elements/EFMedia/AssetMediaEngine.js +13 -1
  3. package/dist/elements/EFMedia/JitMediaEngine.d.ts +10 -0
  4. package/dist/elements/EFMedia/JitMediaEngine.js +12 -0
  5. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +16 -12
  6. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.d.ts +1 -1
  7. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +0 -4
  8. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.d.ts +1 -1
  9. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +0 -4
  10. package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js +1 -1
  11. package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js +3 -2
  12. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +16 -12
  13. package/dist/elements/EFMedia.d.ts +2 -3
  14. package/dist/elements/EFMedia.js +0 -4
  15. package/dist/elements/EFTemporal.d.ts +9 -6
  16. package/dist/elements/EFTemporal.js +15 -12
  17. package/dist/elements/EFTimegroup.browsertest.d.ts +26 -0
  18. package/dist/elements/EFTimegroup.d.ts +13 -15
  19. package/dist/elements/EFTimegroup.js +123 -67
  20. package/dist/elements/EFVideo.d.ts +5 -1
  21. package/dist/elements/EFVideo.js +16 -8
  22. package/dist/elements/EFWaveform.js +2 -3
  23. package/dist/elements/FetchContext.browsertest.d.ts +0 -0
  24. package/dist/elements/FetchMixin.js +14 -9
  25. package/dist/elements/TimegroupController.js +2 -1
  26. package/dist/elements/updateAnimations.browsertest.d.ts +0 -0
  27. package/dist/elements/updateAnimations.d.ts +19 -9
  28. package/dist/elements/updateAnimations.js +64 -25
  29. package/dist/gui/ContextMixin.js +34 -27
  30. package/dist/gui/EFConfiguration.d.ts +1 -1
  31. package/dist/gui/EFConfiguration.js +1 -0
  32. package/dist/gui/EFFilmstrip.d.ts +1 -0
  33. package/dist/gui/EFFilmstrip.js +12 -14
  34. package/dist/gui/TWMixin.js +1 -1
  35. package/dist/style.css +1 -1
  36. package/dist/transcoding/cache/URLTokenDeduplicator.d.ts +38 -0
  37. package/dist/transcoding/cache/URLTokenDeduplicator.js +66 -0
  38. package/dist/transcoding/cache/URLTokenDeduplicator.test.d.ts +1 -0
  39. package/dist/transcoding/types/index.d.ts +10 -0
  40. package/package.json +2 -2
  41. package/src/elements/EFMedia/AssetMediaEngine.ts +16 -2
  42. package/src/elements/EFMedia/JitMediaEngine.ts +14 -0
  43. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.ts +0 -1
  44. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.ts +11 -4
  45. package/src/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.ts +0 -4
  46. package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.ts +4 -1
  47. package/src/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.ts +0 -5
  48. package/src/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.ts +2 -2
  49. package/src/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.ts +7 -3
  50. package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.ts +11 -4
  51. package/src/elements/EFMedia.browsertest.ts +13 -4
  52. package/src/elements/EFMedia.ts +6 -10
  53. package/src/elements/EFTemporal.ts +21 -26
  54. package/src/elements/EFTimegroup.browsertest.ts +186 -2
  55. package/src/elements/EFTimegroup.ts +205 -98
  56. package/src/elements/EFVideo.browsertest.ts +53 -132
  57. package/src/elements/EFVideo.ts +26 -13
  58. package/src/elements/EFWaveform.ts +2 -3
  59. package/src/elements/FetchContext.browsertest.ts +396 -0
  60. package/src/elements/FetchMixin.ts +25 -8
  61. package/src/elements/TimegroupController.ts +2 -1
  62. package/src/elements/updateAnimations.browsertest.ts +586 -0
  63. package/src/elements/updateAnimations.ts +113 -50
  64. package/src/gui/ContextMixin.browsertest.ts +4 -9
  65. package/src/gui/ContextMixin.ts +52 -33
  66. package/src/gui/EFConfiguration.ts +1 -1
  67. package/src/gui/EFFilmstrip.ts +15 -18
  68. package/src/transcoding/cache/URLTokenDeduplicator.test.ts +182 -0
  69. package/src/transcoding/cache/URLTokenDeduplicator.ts +101 -0
  70. package/src/transcoding/types/index.ts +11 -0
  71. package/test/EFVideo.framegen.browsertest.ts +1 -1
  72. package/test/setup.ts +2 -0
  73. package/types.json +1 -1
@@ -42,4 +42,14 @@ export declare class AssetMediaEngine extends BaseMediaEngine implements MediaEn
42
42
  calculateAudioSegmentRange(fromMs: number, toMs: number, rendition: AudioRendition, _durationMs: number): SegmentTimeRange[];
43
43
  computeSegmentId(seekTimeMs: number, rendition: MediaRendition): number;
44
44
  getScrubVideoRendition(): VideoRendition | undefined;
45
+ /**
46
+ * Get preferred buffer configuration for this media engine
47
+ * AssetMediaEngine uses lower buffering since segments are already optimized
48
+ */
49
+ getBufferConfig(): {
50
+ videoBufferDurationMs: number;
51
+ audioBufferDurationMs: number;
52
+ maxVideoBufferFetches: number;
53
+ maxAudioBufferFetches: number;
54
+ };
45
55
  }
@@ -143,7 +143,19 @@ var AssetMediaEngine = class AssetMediaEngine extends BaseMediaEngine {
143
143
  return nearestSegmentIndex;
144
144
  }
145
145
  getScrubVideoRendition() {
146
- return this.videoRendition;
146
+ return void 0;
147
+ }
148
+ /**
149
+ * Get preferred buffer configuration for this media engine
150
+ * AssetMediaEngine uses lower buffering since segments are already optimized
151
+ */
152
+ getBufferConfig() {
153
+ return {
154
+ videoBufferDurationMs: 2e3,
155
+ audioBufferDurationMs: 2e3,
156
+ maxVideoBufferFetches: 1,
157
+ maxAudioBufferFetches: 1
158
+ };
147
159
  }
148
160
  };
149
161
  export { AssetMediaEngine };
@@ -27,4 +27,14 @@ export declare class JitMediaEngine extends BaseMediaEngine implements MediaEngi
27
27
  }): Promise<ArrayBuffer>;
28
28
  computeSegmentId(desiredSeekTimeMs: number, rendition: VideoRendition | AudioRendition): number | undefined;
29
29
  getScrubVideoRendition(): VideoRendition | undefined;
30
+ /**
31
+ * Get preferred buffer configuration for JIT transcoding
32
+ * Uses higher buffering since transcoding introduces latency
33
+ */
34
+ getBufferConfig(): {
35
+ videoBufferDurationMs: number;
36
+ audioBufferDurationMs: number;
37
+ maxVideoBufferFetches: number;
38
+ maxAudioBufferFetches: number;
39
+ };
30
40
  }
@@ -89,5 +89,17 @@ var JitMediaEngine = class JitMediaEngine extends BaseMediaEngine {
89
89
  segmentDurationsMs: scrubManifestRendition.segmentDurationsMs
90
90
  };
91
91
  }
92
+ /**
93
+ * Get preferred buffer configuration for JIT transcoding
94
+ * Uses higher buffering since transcoding introduces latency
95
+ */
96
+ getBufferConfig() {
97
+ return {
98
+ videoBufferDurationMs: 8e3,
99
+ audioBufferDurationMs: 8e3,
100
+ maxVideoBufferFetches: 3,
101
+ maxAudioBufferFetches: 3
102
+ };
103
+ }
92
104
  };
93
105
  export { JitMediaEngine };
@@ -11,7 +11,7 @@ const makeAudioBufferTask = (host) => {
11
11
  requestQueue: []
12
12
  };
13
13
  return new Task(host, {
14
- autoRun: EF_INTERACTIVE && !EF_RENDERING(),
14
+ autoRun: EF_INTERACTIVE,
15
15
  args: () => [host.desiredSeekTimeMs],
16
16
  onError: (error) => {
17
17
  console.error("audioBufferTask error", error);
@@ -21,28 +21,32 @@ const makeAudioBufferTask = (host) => {
21
21
  },
22
22
  task: async ([seekTimeMs], { signal }) => {
23
23
  if (EF_RENDERING()) return currentState;
24
+ const mediaEngine = await getLatestMediaEngine(host, signal);
25
+ const engineConfig = mediaEngine.getBufferConfig();
26
+ const bufferDurationMs = engineConfig.audioBufferDurationMs;
27
+ const maxParallelFetches = engineConfig.maxAudioBufferFetches;
24
28
  const currentConfig = {
25
- bufferDurationMs: host.audioBufferDurationMs,
26
- maxParallelFetches: host.maxAudioBufferFetches,
29
+ bufferDurationMs,
30
+ maxParallelFetches,
27
31
  enableBuffering: host.enableAudioBuffering
28
32
  };
29
33
  return manageMediaBuffer(seekTimeMs, currentConfig, currentState, host.intrinsicDurationMs || 1e4, signal, {
30
34
  computeSegmentId: async (timeMs, rendition) => {
31
- const mediaEngine = await getLatestMediaEngine(host, signal);
32
- return mediaEngine.computeSegmentId(timeMs, rendition);
35
+ const mediaEngine$1 = await getLatestMediaEngine(host, signal);
36
+ return mediaEngine$1.computeSegmentId(timeMs, rendition);
33
37
  },
34
38
  prefetchSegment: async (segmentId, rendition) => {
35
- const mediaEngine = await getLatestMediaEngine(host, signal);
36
- await mediaEngine.fetchMediaSegment(segmentId, rendition);
39
+ const mediaEngine$1 = await getLatestMediaEngine(host, signal);
40
+ await mediaEngine$1.fetchMediaSegment(segmentId, rendition);
37
41
  },
38
42
  isSegmentCached: (segmentId, rendition) => {
39
- const mediaEngine = host.mediaEngineTask.value;
40
- if (!mediaEngine) return false;
41
- return mediaEngine.isSegmentCached(segmentId, rendition);
43
+ const mediaEngine$1 = host.mediaEngineTask.value;
44
+ if (!mediaEngine$1) return false;
45
+ return mediaEngine$1.isSegmentCached(segmentId, rendition);
42
46
  },
43
47
  getRendition: async () => {
44
- const mediaEngine = await getLatestMediaEngine(host, signal);
45
- const audioRendition = mediaEngine.audioRendition;
48
+ const mediaEngine$1 = await getLatestMediaEngine(host, signal);
49
+ const audioRendition = mediaEngine$1.audioRendition;
46
50
  if (!audioRendition) throw new Error("Audio rendition not available");
47
51
  return audioRendition;
48
52
  },
@@ -1,3 +1,3 @@
1
1
  import { Task } from '@lit/task';
2
2
  import { EFMedia } from '../../EFMedia.js';
3
- export declare function makeAudioFrequencyAnalysisTask(element: EFMedia): Task<readonly [import('@lit/task').TaskStatus, number, number, number, number, boolean], Uint8Array | null>;
3
+ export declare function makeAudioFrequencyAnalysisTask(element: EFMedia): Task<readonly [number, number, number, number, boolean], Uint8Array | null>;
@@ -43,7 +43,6 @@ function makeAudioFrequencyAnalysisTask(element) {
43
43
  console.error("frequencyDataTask error", error);
44
44
  },
45
45
  args: () => [
46
- element.audioBufferTask.status,
47
46
  element.currentSourceTimeMs,
48
47
  element.fftSize,
49
48
  element.fftDecay,
@@ -51,9 +50,6 @@ function makeAudioFrequencyAnalysisTask(element) {
51
50
  element.shouldInterpolateFrequencies
52
51
  ],
53
52
  task: async (_, { signal }) => {
54
- await element.audioBufferTask.taskComplete;
55
- signal.throwIfAborted();
56
- if (!element.audioBufferTask.value) return null;
57
53
  if (element.currentSourceTimeMs < 0) return null;
58
54
  const currentTimeMs = element.currentSourceTimeMs;
59
55
  const frameIntervalMs = 1e3 / 30;
@@ -1,3 +1,3 @@
1
1
  import { Task } from '@lit/task';
2
2
  import { EFMedia } from '../../EFMedia.js';
3
- export declare function makeAudioTimeDomainAnalysisTask(element: EFMedia): Task<readonly [import('@lit/task').TaskStatus, number, number, number, number, boolean], Uint8Array | null>;
3
+ export declare function makeAudioTimeDomainAnalysisTask(element: EFMedia): Task<readonly [number, number, number, number, boolean], Uint8Array | null>;
@@ -10,7 +10,6 @@ function makeAudioTimeDomainAnalysisTask(element) {
10
10
  console.error("byteTimeDomainTask error", error);
11
11
  },
12
12
  args: () => [
13
- element.audioBufferTask.status,
14
13
  element.currentSourceTimeMs,
15
14
  element.fftSize,
16
15
  element.fftDecay,
@@ -18,9 +17,6 @@ function makeAudioTimeDomainAnalysisTask(element) {
18
17
  element.shouldInterpolateFrequencies
19
18
  ],
20
19
  task: async (_, { signal }) => {
21
- await element.audioBufferTask.taskComplete;
22
- signal.throwIfAborted();
23
- if (!element.audioBufferTask.value) return null;
24
20
  if (element.currentSourceTimeMs < 0) return null;
25
21
  const currentTimeMs = element.currentSourceTimeMs;
26
22
  const frameIntervalMs = 1e3 / 30;
@@ -14,7 +14,7 @@ const makeScrubVideoBufferTask = (host) => {
14
14
  requestQueue: []
15
15
  };
16
16
  return new Task(host, {
17
- autoRun: !EF_RENDERING(),
17
+ autoRun: false,
18
18
  args: () => [host.mediaEngineTask.value],
19
19
  onError: (error) => {
20
20
  console.error("scrubVideoBufferTask error", error);
@@ -4,13 +4,13 @@ import { Task } from "@lit/task";
4
4
  const scrubInputCache = new ScrubInputCache();
5
5
  const makeUnifiedVideoSeekTask = (host) => {
6
6
  return new Task(host, {
7
+ autoRun: false,
7
8
  args: () => [host.desiredSeekTimeMs],
8
9
  onError: (error) => {
9
10
  console.error("unifiedVideoSeekTask error", error);
10
11
  },
11
12
  onComplete: (_value) => {},
12
13
  task: async ([desiredSeekTimeMs], { signal }) => {
13
- signal.throwIfAborted();
14
14
  const mediaEngine = await getLatestMediaEngine(host, signal);
15
15
  if (!mediaEngine) return void 0;
16
16
  const mainRendition = mediaEngine.videoRendition;
@@ -33,7 +33,8 @@ const makeUnifiedVideoSeekTask = (host) => {
33
33
  async function tryGetScrubSample(mediaEngine, desiredSeekTimeMs, signal) {
34
34
  try {
35
35
  let scrubRendition;
36
- if ("data" in mediaEngine && mediaEngine.data?.videoRenditions) scrubRendition = mediaEngine.data.videoRenditions.find((r) => r.id === "scrub");
36
+ if (typeof mediaEngine.getScrubVideoRendition === "function") scrubRendition = mediaEngine.getScrubVideoRendition();
37
+ else if ("data" in mediaEngine && mediaEngine.data?.videoRenditions) scrubRendition = mediaEngine.data.videoRenditions.find((r) => r.id === "scrub");
37
38
  if (!scrubRendition) return void 0;
38
39
  const scrubRenditionWithSrc = {
39
40
  ...scrubRendition,
@@ -11,7 +11,7 @@ const makeVideoBufferTask = (host) => {
11
11
  requestQueue: []
12
12
  };
13
13
  return new Task(host, {
14
- autoRun: EF_INTERACTIVE && !EF_RENDERING(),
14
+ autoRun: EF_INTERACTIVE,
15
15
  args: () => [host.desiredSeekTimeMs],
16
16
  onError: (error) => {
17
17
  console.error("videoBufferTask error", error);
@@ -21,28 +21,32 @@ const makeVideoBufferTask = (host) => {
21
21
  },
22
22
  task: async ([seekTimeMs], { signal }) => {
23
23
  if (EF_RENDERING()) return currentState;
24
+ const mediaEngine = await getLatestMediaEngine(host, signal);
25
+ const engineConfig = mediaEngine.getBufferConfig();
26
+ const bufferDurationMs = engineConfig.videoBufferDurationMs;
27
+ const maxParallelFetches = engineConfig.maxVideoBufferFetches;
24
28
  const currentConfig = {
25
- bufferDurationMs: host.videoBufferDurationMs,
26
- maxParallelFetches: host.maxVideoBufferFetches,
29
+ bufferDurationMs,
30
+ maxParallelFetches,
27
31
  enableBuffering: host.enableVideoBuffering
28
32
  };
29
33
  return manageMediaBuffer(seekTimeMs, currentConfig, currentState, host.intrinsicDurationMs || 1e4, signal, {
30
34
  computeSegmentId: async (timeMs, rendition) => {
31
- const mediaEngine = await getLatestMediaEngine(host, signal);
32
- return mediaEngine.computeSegmentId(timeMs, rendition);
35
+ const mediaEngine$1 = await getLatestMediaEngine(host, signal);
36
+ return mediaEngine$1.computeSegmentId(timeMs, rendition);
33
37
  },
34
38
  prefetchSegment: async (segmentId, rendition) => {
35
- const mediaEngine = await getLatestMediaEngine(host, signal);
36
- await mediaEngine.fetchMediaSegment(segmentId, rendition);
39
+ const mediaEngine$1 = await getLatestMediaEngine(host, signal);
40
+ await mediaEngine$1.fetchMediaSegment(segmentId, rendition);
37
41
  },
38
42
  isSegmentCached: (segmentId, rendition) => {
39
- const mediaEngine = host.mediaEngineTask.value;
40
- if (!mediaEngine) return false;
41
- return mediaEngine.isSegmentCached(segmentId, rendition);
43
+ const mediaEngine$1 = host.mediaEngineTask.value;
44
+ if (!mediaEngine$1) return false;
45
+ return mediaEngine$1.isSegmentCached(segmentId, rendition);
42
46
  },
43
47
  getRendition: async () => {
44
- const mediaEngine = await getLatestMediaEngine(host, signal);
45
- return getVideoRendition(mediaEngine);
48
+ const mediaEngine$1 = await getLatestMediaEngine(host, signal);
49
+ return getVideoRendition(mediaEngine$1);
46
50
  },
47
51
  logError: console.error
48
52
  });
@@ -13,7 +13,6 @@ export declare class EFMedia extends EFMedia_base {
13
13
  static readonly AUDIO_SAMPLE_BUFFER_SIZE = 120;
14
14
  static get observedAttributes(): string[];
15
15
  static styles: import('lit').CSSResult[];
16
- currentTimeMs: number;
17
16
  /**
18
17
  * Duration in milliseconds for audio buffering ahead of current time
19
18
  * @domAttribute "audio-buffer-duration"
@@ -64,8 +63,8 @@ export declare class EFMedia extends EFMedia_base {
64
63
  audioInputTask: import('./EFMedia/shared/MediaTaskUtils.ts').InputTask;
65
64
  audioSeekTask: import('@lit/task').Task<readonly [number, import('./EFMedia/BufferedSeekingInput.ts').BufferedSeekingInput | undefined], import('mediabunny').VideoSample | undefined>;
66
65
  audioBufferTask: import('@lit/task').Task<readonly [number], import('./EFMedia/audioTasks/makeAudioBufferTask.ts').AudioBufferState>;
67
- byteTimeDomainTask: import('@lit/task').Task<readonly [import('@lit/task').TaskStatus, number, number, number, number, boolean], Uint8Array | null>;
68
- frequencyDataTask: import('@lit/task').Task<readonly [import('@lit/task').TaskStatus, number, number, number, number, boolean], Uint8Array | null>;
66
+ byteTimeDomainTask: import('@lit/task').Task<readonly [number, number, number, number, boolean], Uint8Array | null>;
67
+ frequencyDataTask: import('@lit/task').Task<readonly [number, number, number, number, boolean], Uint8Array | null>;
69
68
  /**
70
69
  * The unique identifier for the media asset.
71
70
  * This property can be set programmatically or via the "asset-id" attribute.
@@ -13,7 +13,6 @@ import { EFSourceMixin } from "./EFSourceMixin.js";
13
13
  import { EFTemporal } from "./EFTemporal.js";
14
14
  import { FetchMixin } from "./FetchMixin.js";
15
15
  import { EFTargetable } from "./TargetController.js";
16
- import { updateAnimations } from "./updateAnimations.js";
17
16
  import { LitElement, css } from "lit";
18
17
  import { property, state } from "lit/decorators.js";
19
18
  import _decorate from "@oxc-project/runtime/helpers/decorate";
@@ -27,7 +26,6 @@ const deepGetMediaElements = (element, medias = []) => {
27
26
  var EFMedia = class extends EFTargetable(EFSourceMixin(EFTemporal(FetchMixin(LitElement)), { assetType: "isobmff_files" })) {
28
27
  constructor(..._args) {
29
28
  super(..._args);
30
- this.currentTimeMs = 0;
31
29
  this.audioBufferDurationMs = 1e4;
32
30
  this.maxAudioBufferFetches = 2;
33
31
  this.enableAudioBuffering = true;
@@ -107,7 +105,6 @@ var EFMedia = class extends EFTargetable(EFSourceMixin(EFTemporal(FetchMixin(Lit
107
105
  const newCurrentSourceTimeMs = this.currentSourceTimeMs;
108
106
  if (newCurrentSourceTimeMs !== this.desiredSeekTimeMs) this.executeSeek(newCurrentSourceTimeMs);
109
107
  if (changedProperties.has("ownCurrentTimeMs")) this.executeSeek(this.currentSourceTimeMs);
110
- if (changedProperties.has("currentTime") || changedProperties.has("ownCurrentTimeMs")) updateAnimations(this);
111
108
  }
112
109
  get hasOwnDuration() {
113
110
  return true;
@@ -129,7 +126,6 @@ var EFMedia = class extends EFTargetable(EFSourceMixin(EFTemporal(FetchMixin(Lit
129
126
  return fetchAudioSpanningTime(this, fromMs, toMs, signal);
130
127
  }
131
128
  };
132
- _decorate([property({ type: Number })], EFMedia.prototype, "currentTimeMs", void 0);
133
129
  _decorate([property({
134
130
  type: Number,
135
131
  attribute: "audio-buffer-duration"
@@ -131,6 +131,12 @@ export declare class TemporalMixinInterface {
131
131
  * played.
132
132
  */
133
133
  get ownCurrentTimeMs(): number;
134
+ /**
135
+ * Element's current time for progress calculation.
136
+ * For timegroups: their timeline currentTimeMs
137
+ * For other temporal elements: their ownCurrentTimeMs
138
+ */
139
+ get currentTimeMs(): number;
134
140
  /**
135
141
  * The current time of the element in milliseconds, adjusted for trimming.
136
142
  *
@@ -181,12 +187,9 @@ export declare class TemporalMixinInterface {
181
187
  frameTask: Task<readonly unknown[], unknown>;
182
188
  }
183
189
  export declare const isEFTemporal: (obj: any) => obj is TemporalMixinInterface;
184
- export declare const deepGetTemporalElements: (element: Element, temporals?: TemporalMixinInterface[]) => TemporalMixinInterface[];
185
- export declare const deepGetElementsWithFrameTasks: (element: Element, elements?: Array<HTMLElement & {
186
- frameTask: Task;
187
- }>) => (HTMLElement & {
188
- frameTask: Task;
189
- })[];
190
+ export declare const deepGetTemporalElements: (element: Element, temporals?: Array<TemporalMixinInterface & HTMLElement>) => (TemporalMixinInterface & HTMLElement)[];
191
+ export declare const deepGetElementsWithFrameTasks: (element: Element, elements?: Array<TemporalMixinInterface & HTMLElement>) => (TemporalMixinInterface & HTMLElement)[];
192
+ export declare const resetTemporalCache: () => void;
190
193
  export declare const shallowGetTemporalElements: (element: Element, temporals?: TemporalMixinInterface[]) => TemporalMixinInterface[];
191
194
  export declare class OwnCurrentTimeController implements ReactiveController {
192
195
  private host;
@@ -7,6 +7,13 @@ import _decorate from "@oxc-project/runtime/helpers/decorate";
7
7
  const timegroupContext = createContext(Symbol("timeGroupContext"));
8
8
  const isEFTemporal = (obj) => obj[EF_TEMPORAL];
9
9
  const EF_TEMPORAL = Symbol("EF_TEMPORAL");
10
+ const deepGetTemporalElements = (element, temporals = []) => {
11
+ for (const child of element.children) {
12
+ if (isEFTemporal(child)) temporals.push(child);
13
+ deepGetTemporalElements(child, temporals);
14
+ }
15
+ return temporals;
16
+ };
10
17
  const deepGetElementsWithFrameTasks = (element, elements = []) => {
11
18
  for (const child of element.children) {
12
19
  if ("frameTask" in child && child.frameTask instanceof Task) elements.push(child);
@@ -219,6 +226,13 @@ const EFTemporal = (superClass) => {
219
226
  return 0;
220
227
  }
221
228
  /**
229
+ * Element's current time for progress calculation.
230
+ * Non-timegroup temporal elements use their local time (ownCurrentTimeMs)
231
+ */
232
+ get currentTimeMs() {
233
+ return this.ownCurrentTimeMs;
234
+ }
235
+ /**
222
236
  * Used to calculate the internal currentTimeMs of the element. This is useful
223
237
  * for mapping to internal media time codes for audio/video elements.
224
238
  */
@@ -226,17 +240,6 @@ const EFTemporal = (superClass) => {
226
240
  const leadingTrimMs = this.sourceInMs || this.trimStartMs || 0;
227
241
  return this.ownCurrentTimeMs + leadingTrimMs;
228
242
  }
229
- updated(changedProperties) {
230
- super.updated(changedProperties);
231
- if (changedProperties.has("currentTime") || changedProperties.has("ownCurrentTimeMs")) {
232
- const timelineTimeMs = (this.rootTimegroup ?? this).ownCurrentTimeMs;
233
- if (this.startTimeMs > timelineTimeMs || this.endTimeMs < timelineTimeMs) {
234
- this.style.display = "none";
235
- return;
236
- }
237
- this.style.display = "";
238
- }
239
- }
240
243
  }
241
244
  _decorate([consume({
242
245
  context: timegroupContext,
@@ -281,4 +284,4 @@ const EFTemporal = (superClass) => {
281
284
  Object.defineProperty(TemporalMixinClass.prototype, EF_TEMPORAL, { value: true });
282
285
  return TemporalMixinClass;
283
286
  };
284
- export { EFTemporal, deepGetElementsWithFrameTasks, flushStartTimeMsCache, isEFTemporal, shallowGetTemporalElements, timegroupContext };
287
+ export { EFTemporal, deepGetElementsWithFrameTasks, deepGetTemporalElements, flushStartTimeMsCache, isEFTemporal, resetTemporalCache, shallowGetTemporalElements, timegroupContext };
@@ -1,7 +1,29 @@
1
1
  import { LitElement } from 'lit';
2
+ import { Task } from '@lit/task';
3
+ import { MediaEngine } from '../transcoding/types/index.js';
4
+ import { EFMedia } from './EFMedia.js';
2
5
  declare const TestContext_base: (new (...args: any[]) => import('../gui/ContextMixin.js').ContextMixinInterface) & typeof LitElement;
3
6
  declare class TestContext extends TestContext_base {
4
7
  }
8
+ declare class TimegroupTestMedia extends EFMedia {
9
+ mediaEngineTaskCount: number;
10
+ mediaEngineTask: Task<readonly ["source", null], MediaEngine>;
11
+ }
12
+ declare const TestFrameTaskA_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
13
+ declare class TestFrameTaskA extends TestFrameTaskA_base {
14
+ frameTaskCount: number;
15
+ frameTask: Task<never[], void>;
16
+ }
17
+ declare const TestFrameTaskB_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
18
+ declare class TestFrameTaskB extends TestFrameTaskB_base {
19
+ frameTaskCount: number;
20
+ frameTask: Task<never[], void>;
21
+ }
22
+ declare const TestFrameTaskC_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
23
+ declare class TestFrameTaskC extends TestFrameTaskC_base {
24
+ frameTaskCount: number;
25
+ frameTask: Task<never[], void>;
26
+ }
5
27
  declare const TestTemporal_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
6
28
  declare class TestTemporal extends TestTemporal_base {
7
29
  get hasOwnDuration(): boolean;
@@ -10,6 +32,10 @@ declare global {
10
32
  interface HTMLElementTagNameMap {
11
33
  "test-temporal": TestTemporal;
12
34
  "test-context": TestContext;
35
+ "timegroup-test-media": TimegroupTestMedia;
36
+ "test-frame-task-a": TestFrameTaskA;
37
+ "test-frame-task-b": TestFrameTaskB;
38
+ "test-frame-task-c": TestFrameTaskC;
13
39
  }
14
40
  }
15
41
  export {};
@@ -1,24 +1,29 @@
1
1
  import { Task } from '@lit/task';
2
- import { LitElement, PropertyValueMap } from 'lit';
2
+ import { LitElement } from 'lit';
3
+ export declare const flushSequenceDurationCache: () => void;
3
4
  export declare const shallowGetTimegroups: (element: Element, groups?: EFTimegroup[]) => EFTimegroup[];
4
5
  declare const EFTimegroup_base: (new (...args: any[]) => import('./EFTemporal.js').TemporalMixinInterface) & typeof LitElement;
5
6
  export declare class EFTimegroup extends EFTimegroup_base {
6
7
  #private;
7
8
  static styles: import('lit').CSSResult;
8
9
  _timeGroupContext: this;
9
- mode: "fit" | "fixed" | "sequence" | "contain";
10
- overlapMs: number;
10
+ set mode(value: "fit" | "fixed" | "sequence" | "contain");
11
+ get mode(): "fit" | "fixed" | "sequence" | "contain";
12
+ private _mode;
13
+ set overlapMs(value: number);
14
+ get overlapMs(): number;
15
+ private _overlapMs;
11
16
  fit: "none" | "contain" | "cover";
12
17
  set currentTime(time: number);
13
18
  get currentTime(): number;
14
- get currentTimeMs(): number;
15
19
  set currentTimeMs(ms: number);
20
+ get currentTimeMs(): number;
16
21
  /**
17
22
  * Determines if this is a root timegroup (no parent timegroups)
18
23
  */
19
24
  get isRootTimegroup(): boolean;
20
25
  render(): import('lit-html').TemplateResult<1>;
21
- maybeLoadTimeFromLocalStorage(): number;
26
+ maybeLoadTimeFromLocalStorage(): number | undefined;
22
27
  connectedCallback(): void;
23
28
  disconnectedCallback(): void;
24
29
  get storageKey(): string;
@@ -27,17 +32,10 @@ export declare class EFTimegroup extends EFTimegroup_base {
27
32
  get durationMs(): number;
28
33
  getPendingFrameTasks(signal?: AbortSignal): Promise<Task<readonly unknown[], unknown>[]>;
29
34
  waitForNestedUpdates(signal?: AbortSignal): Promise<void>;
30
- waitForFrameTasks(signal?: AbortSignal): Promise<void>;
31
- /**
32
- * Wait for all media elements to load their initial segments.
33
- * Ideally we would only need the extracted index json data, but
34
- * that caused issues with constructing audio data. We had negative durations
35
- * in calculations and it was not clear why.
36
- */
35
+ waitForFrameTasks(): Promise<void>;
36
+ mediaDurationsPromise: Promise<void> | undefined;
37
37
  waitForMediaDurations(): Promise<void>;
38
38
  get childTemporals(): import('./EFTemporal.js').TemporalMixinInterface[];
39
- protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
40
- private updateAnimations;
41
39
  get contextProvider(): import('../gui/ContextMixin.js').ContextMixinInterface | null;
42
40
  /**
43
41
  * Returns true if the timegroup should be wrapped with a workbench.
@@ -59,7 +57,7 @@ export declare class EFTimegroup extends EFTimegroup_base {
59
57
  testPlayAudio(fromMs: number, toMs: number): Promise<void>;
60
58
  loadMd5Sums(): Promise<void>;
61
59
  frameTask: Task<readonly [number, number], void>;
62
- seekTask: Task<readonly [number], void>;
60
+ seekTask: Task<readonly [number | undefined], number | undefined>;
63
61
  }
64
62
  declare global {
65
63
  interface HTMLElementTagNameMap {