@editframe/elements 0.16.7-beta.0 → 0.17.6-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 (101) hide show
  1. package/README.md +30 -0
  2. package/dist/DecoderResetFrequency.test.d.ts +1 -0
  3. package/dist/DecoderResetRecovery.test.d.ts +1 -0
  4. package/dist/DelayedLoadingState.d.ts +48 -0
  5. package/dist/DelayedLoadingState.integration.test.d.ts +1 -0
  6. package/dist/DelayedLoadingState.js +113 -0
  7. package/dist/DelayedLoadingState.test.d.ts +1 -0
  8. package/dist/EF_FRAMEGEN.d.ts +10 -1
  9. package/dist/EF_FRAMEGEN.js +199 -179
  10. package/dist/EF_INTERACTIVE.js +2 -6
  11. package/dist/EF_RENDERING.js +1 -3
  12. package/dist/JitTranscodingClient.browsertest.d.ts +1 -0
  13. package/dist/JitTranscodingClient.d.ts +167 -0
  14. package/dist/JitTranscodingClient.js +373 -0
  15. package/dist/JitTranscodingClient.test.d.ts +1 -0
  16. package/dist/LoadingDebounce.test.d.ts +1 -0
  17. package/dist/LoadingIndicator.browsertest.d.ts +0 -0
  18. package/dist/ManualScrubTest.test.d.ts +1 -0
  19. package/dist/ScrubResolvedFlashing.test.d.ts +1 -0
  20. package/dist/ScrubTrackIntegration.test.d.ts +1 -0
  21. package/dist/ScrubTrackManager.d.ts +96 -0
  22. package/dist/ScrubTrackManager.js +216 -0
  23. package/dist/ScrubTrackManager.test.d.ts +1 -0
  24. package/dist/SegmentSwitchLoading.test.d.ts +1 -0
  25. package/dist/VideoSeekFlashing.browsertest.d.ts +0 -0
  26. package/dist/VideoStuckDiagnostic.test.d.ts +1 -0
  27. package/dist/elements/CrossUpdateController.js +13 -15
  28. package/dist/elements/EFAudio.browsertest.d.ts +0 -0
  29. package/dist/elements/EFAudio.d.ts +1 -1
  30. package/dist/elements/EFAudio.js +30 -43
  31. package/dist/elements/EFCaptions.js +337 -373
  32. package/dist/elements/EFImage.js +64 -90
  33. package/dist/elements/EFMedia.d.ts +98 -33
  34. package/dist/elements/EFMedia.js +1169 -678
  35. package/dist/elements/EFSourceMixin.js +31 -48
  36. package/dist/elements/EFTemporal.d.ts +1 -0
  37. package/dist/elements/EFTemporal.js +266 -360
  38. package/dist/elements/EFTimegroup.d.ts +3 -1
  39. package/dist/elements/EFTimegroup.js +262 -323
  40. package/dist/elements/EFVideo.browsertest.d.ts +0 -0
  41. package/dist/elements/EFVideo.d.ts +90 -2
  42. package/dist/elements/EFVideo.js +408 -111
  43. package/dist/elements/EFWaveform.js +375 -411
  44. package/dist/elements/FetchMixin.js +14 -24
  45. package/dist/elements/MediaController.d.ts +30 -0
  46. package/dist/elements/TargetController.js +130 -156
  47. package/dist/elements/TimegroupController.js +17 -19
  48. package/dist/elements/durationConverter.js +15 -4
  49. package/dist/elements/parseTimeToMs.js +4 -10
  50. package/dist/elements/printTaskStatus.d.ts +2 -0
  51. package/dist/elements/printTaskStatus.js +11 -0
  52. package/dist/elements/updateAnimations.js +39 -59
  53. package/dist/getRenderInfo.js +58 -67
  54. package/dist/gui/ContextMixin.js +203 -288
  55. package/dist/gui/EFConfiguration.js +27 -43
  56. package/dist/gui/EFFilmstrip.js +440 -620
  57. package/dist/gui/EFFitScale.js +112 -135
  58. package/dist/gui/EFFocusOverlay.js +45 -61
  59. package/dist/gui/EFPreview.js +30 -49
  60. package/dist/gui/EFScrubber.js +78 -99
  61. package/dist/gui/EFTimeDisplay.js +49 -70
  62. package/dist/gui/EFToggleLoop.js +17 -34
  63. package/dist/gui/EFTogglePlay.js +37 -58
  64. package/dist/gui/EFWorkbench.js +66 -88
  65. package/dist/gui/TWMixin.js +2 -48
  66. package/dist/gui/TWMixin2.js +31 -0
  67. package/dist/gui/efContext.js +2 -6
  68. package/dist/gui/fetchContext.js +1 -3
  69. package/dist/gui/focusContext.js +1 -3
  70. package/dist/gui/focusedElementContext.js +2 -6
  71. package/dist/gui/playingContext.js +1 -4
  72. package/dist/index.js +5 -30
  73. package/dist/msToTimeCode.js +11 -13
  74. package/dist/style.css +2 -1
  75. package/package.json +3 -3
  76. package/src/elements/EFAudio.browsertest.ts +569 -0
  77. package/src/elements/EFAudio.ts +4 -6
  78. package/src/elements/EFCaptions.browsertest.ts +0 -1
  79. package/src/elements/EFImage.browsertest.ts +0 -1
  80. package/src/elements/EFMedia.browsertest.ts +147 -115
  81. package/src/elements/EFMedia.ts +1339 -307
  82. package/src/elements/EFTemporal.browsertest.ts +0 -1
  83. package/src/elements/EFTemporal.ts +11 -0
  84. package/src/elements/EFTimegroup.ts +73 -10
  85. package/src/elements/EFVideo.browsertest.ts +680 -0
  86. package/src/elements/EFVideo.ts +729 -50
  87. package/src/elements/EFWaveform.ts +4 -4
  88. package/src/elements/MediaController.ts +108 -0
  89. package/src/elements/__screenshots__/EFMedia.browsertest.ts/EFMedia-JIT-audio-playback-audioBufferTask-should-work-in-JIT-mode-without-URL-errors-1.png +0 -0
  90. package/src/elements/printTaskStatus.ts +16 -0
  91. package/src/elements/updateAnimations.ts +6 -0
  92. package/src/gui/TWMixin.ts +10 -3
  93. package/test/EFVideo.frame-tasks.browsertest.ts +524 -0
  94. package/test/EFVideo.framegen.browsertest.ts +118 -0
  95. package/test/createJitTestClips.ts +293 -0
  96. package/test/useAssetMSW.ts +49 -0
  97. package/test/useMSW.ts +31 -0
  98. package/types.json +1 -1
  99. package/dist/gui/TWMixin.css.js +0 -4
  100. /package/dist/elements/{TargetController.test.d.ts → TargetController.browsertest.d.ts} +0 -0
  101. /package/src/elements/{TargetController.test.ts → TargetController.browsertest.ts} +0 -0
@@ -1,87 +1,45 @@
1
- import { Task } from "@lit/task";
2
- import { LitElement, html, css } from "lit";
3
- import { property, customElement } from "lit/decorators.js";
4
- import { createRef, ref } from "lit/directives/ref.js";
5
1
  import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
6
2
  import { EFSourceMixin } from "./EFSourceMixin.js";
7
3
  import { EFTemporal } from "./EFTemporal.js";
8
4
  import { FetchMixin } from "./FetchMixin.js";
9
- var __defProp = Object.defineProperty;
10
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
- var __typeError = (msg) => {
12
- throw TypeError(msg);
13
- };
14
- var __decorateClass = (decorators, target, key, kind) => {
15
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
16
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
17
- if (decorator = decorators[i])
18
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
19
- if (kind && result) __defProp(target, key, result);
20
- return result;
21
- };
22
- var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
23
- var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
24
- var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
25
- var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
26
- var _assetId;
27
- let EFImage = class extends EFTemporal(
28
- EFSourceMixin(FetchMixin(LitElement), {
29
- assetType: "image_files"
30
- })
31
- ) {
32
- constructor() {
33
- super(...arguments);
34
- this.imageRef = createRef();
35
- this.canvasRef = createRef();
36
- __privateAdd(this, _assetId, null);
37
- this.fetchImage = new Task(this, {
38
- autoRun: EF_INTERACTIVE,
39
- args: () => [this.assetPath(), this.fetch],
40
- task: async ([assetPath, fetch], { signal }) => {
41
- const response = await fetch(assetPath, { signal });
42
- const image = new Image();
43
- image.src = URL.createObjectURL(await response.blob());
44
- await new Promise((resolve) => {
45
- image.onload = resolve;
46
- });
47
- if (!this.canvasRef.value) throw new Error("Canvas not ready");
48
- const ctx = this.canvasRef.value.getContext("2d");
49
- if (!ctx) throw new Error("Canvas 2d context not ready");
50
- this.canvasRef.value.width = image.width;
51
- this.canvasRef.value.height = image.height;
52
- ctx.drawImage(image, 0, 0);
53
- }
54
- });
55
- this.frameTask = new Task(this, {
56
- autoRun: EF_INTERACTIVE,
57
- args: () => [this.fetchImage.status],
58
- task: async () => {
59
- await this.fetchImage.taskComplete;
60
- }
61
- });
62
- }
63
- set assetId(value) {
64
- __privateSet(this, _assetId, value);
65
- }
66
- get assetId() {
67
- return __privateGet(this, _assetId) ?? this.getAttribute("asset-id");
68
- }
69
- render() {
70
- return html`<canvas ${ref(this.canvasRef)}></canvas>`;
71
- }
72
- assetPath() {
73
- if (this.assetId) {
74
- return `${this.apiHost}/api/v1/image_files/${this.assetId}`;
75
- }
76
- return `/@ef-image/${this.src}`;
77
- }
78
- get hasOwnDuration() {
79
- return this.hasExplicitDuration;
80
- }
81
- };
82
- _assetId = /* @__PURE__ */ new WeakMap();
83
- EFImage.styles = [
84
- css`
5
+ import { Task } from "@lit/task";
6
+ import { LitElement, css, html } from "lit";
7
+ import { customElement, property } from "lit/decorators.js";
8
+ import _decorate from "@oxc-project/runtime/helpers/decorate";
9
+ import { createRef, ref } from "lit/directives/ref.js";
10
+ let EFImage = class EFImage$1 extends EFTemporal(EFSourceMixin(FetchMixin(LitElement), { assetType: "image_files" })) {
11
+ constructor(..._args) {
12
+ super(..._args);
13
+ this.imageRef = createRef();
14
+ this.canvasRef = createRef();
15
+ this.fetchImage = new Task(this, {
16
+ autoRun: EF_INTERACTIVE,
17
+ args: () => [this.assetPath(), this.fetch],
18
+ task: async ([assetPath, fetch], { signal }) => {
19
+ const response = await fetch(assetPath, { signal });
20
+ const image = new Image();
21
+ image.src = URL.createObjectURL(await response.blob());
22
+ await new Promise((resolve) => {
23
+ image.onload = resolve;
24
+ });
25
+ if (!this.canvasRef.value) throw new Error("Canvas not ready");
26
+ const ctx = this.canvasRef.value.getContext("2d");
27
+ if (!ctx) throw new Error("Canvas 2d context not ready");
28
+ this.canvasRef.value.width = image.width;
29
+ this.canvasRef.value.height = image.height;
30
+ ctx.drawImage(image, 0, 0);
31
+ }
32
+ });
33
+ this.frameTask = new Task(this, {
34
+ autoRun: EF_INTERACTIVE,
35
+ args: () => [this.fetchImage.status],
36
+ task: async () => {
37
+ await this.fetchImage.taskComplete;
38
+ }
39
+ });
40
+ }
41
+ static {
42
+ this.styles = [css`
85
43
  :host {
86
44
  display: block;
87
45
  display: flex;
@@ -91,14 +49,30 @@ EFImage.styles = [
91
49
  canvas {
92
50
  all: inherit;
93
51
  }
94
- `
95
- ];
96
- __decorateClass([
97
- property({ type: String, attribute: "asset-id", reflect: true })
98
- ], EFImage.prototype, "assetId", 1);
99
- EFImage = __decorateClass([
100
- customElement("ef-image")
101
- ], EFImage);
102
- export {
103
- EFImage
52
+ `];
53
+ }
54
+ #assetId = null;
55
+ set assetId(value) {
56
+ this.#assetId = value;
57
+ }
58
+ get assetId() {
59
+ return this.#assetId ?? this.getAttribute("asset-id");
60
+ }
61
+ render() {
62
+ return html`<canvas ${ref(this.canvasRef)}></canvas>`;
63
+ }
64
+ assetPath() {
65
+ if (this.assetId) return `${this.apiHost}/api/v1/image_files/${this.assetId}`;
66
+ return `/@ef-image/${this.src}`;
67
+ }
68
+ get hasOwnDuration() {
69
+ return this.hasExplicitDuration;
70
+ }
104
71
  };
72
+ _decorate([property({
73
+ type: String,
74
+ attribute: "asset-id",
75
+ reflect: true
76
+ })], EFImage.prototype, "assetId", null);
77
+ EFImage = _decorate([customElement("ef-image")], EFImage);
78
+ export { EFImage };
@@ -1,15 +1,58 @@
1
- import { Task } from '@lit/task';
2
- import { LitElement, PropertyValueMap } from 'lit';
3
1
  import { TrackFragmentIndex, TrackSegment } from '../../../assets/src/index.ts';
4
2
  import { VideoAsset } from '../../../assets/src/EncodedAsset.ts';
5
3
  import { MP4File } from '../../../assets/src/MP4File.ts';
4
+ import { Task } from '@lit/task';
5
+ import { LitElement, PropertyValueMap } from 'lit';
6
+ import { JitTranscodingClient } from '../JitTranscodingClient.js';
6
7
  import type * as MP4Box from "mp4box";
8
+ declare global {
9
+ var EF_FRAMEGEN: import("../EF_FRAMEGEN.js").EFFramegen;
10
+ }
7
11
  export declare const deepGetMediaElements: (element: Element, medias?: EFMedia[]) => EFMedia[];
8
12
  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
13
  export declare class EFMedia extends EFMedia_base {
10
14
  #private;
11
15
  static styles: import('lit').CSSResult[];
12
16
  currentTimeMs: number;
17
+ /**
18
+ * Media loading mode - determines how content is loaded and processed
19
+ * - "asset": Use existing asset-based loading (assetId or fragment-based URLs)
20
+ * - "jit-transcode": Use JIT transcoding for remote URLs
21
+ * - "auto": Automatically detect based on URL patterns (default)
22
+ */
23
+ private _mode;
24
+ /**
25
+ * Get the mode, prioritizing attribute values over property values
26
+ */
27
+ get mode(): "asset" | "jit-transcode" | "auto";
28
+ set mode(value: "asset" | "jit-transcode" | "auto");
29
+ connectedCallback(): void;
30
+ /**
31
+ * Configuration for JIT transcoding performance optimizations
32
+ */
33
+ prefetchSegments: number;
34
+ cacheSize: number;
35
+ enablePrefetch: boolean;
36
+ /**
37
+ * Loading states for JIT transcoding
38
+ */
39
+ jitLoadingState: "idle" | "metadata" | "segments" | "error";
40
+ jitErrorMessage: string | null;
41
+ jitCacheStats: {
42
+ size: number;
43
+ hitRate: number;
44
+ efficiency: number;
45
+ } | null;
46
+ /**
47
+ * Detected loading mode based on URL patterns and manual override
48
+ */
49
+ get effectiveMode(): "asset" | "jit-transcode";
50
+ jitClientTask: Task<readonly [string | undefined, number, boolean, number], JitTranscodingClient>;
51
+ /**
52
+ * JIT transcoding metadata loader
53
+ * Loads video metadata for JIT transcoded content
54
+ */
55
+ jitMetadataLoader: Task<readonly [string, JitTranscodingClient | undefined], import('../JitTranscodingClient.js').VideoMetadata | null>;
13
56
  /**
14
57
  * The unique identifier for the media asset.
15
58
  * This property can be set programmatically or via the "asset-id" attribute.
@@ -19,43 +62,15 @@ export declare class EFMedia extends EFMedia_base {
19
62
  get assetId(): string | null;
20
63
  fragmentIndexPath(): string;
21
64
  fragmentTrackPath(trackId: string): string;
22
- trackFragmentIndexLoader: Task<readonly [string, typeof fetch], Record<number, TrackFragmentIndex> | undefined>;
23
- initSegmentsLoader: Task<readonly [Record<number, TrackFragmentIndex> | undefined, string, typeof fetch], {
24
- trackId: string;
25
- buffer: MP4Box.MP4ArrayBuffer;
26
- mp4File: MP4File;
27
- }[] | undefined>;
65
+ get mediaDurationTask(): Task<readonly [Record<number, TrackFragmentIndex> | null | undefined, import('../JitTranscodingClient.js').VideoMetadata | null | undefined], Record<number, TrackFragmentIndex> | null>;
28
66
  get defaultVideoTrackId(): number | undefined;
29
67
  get defaultAudioTrackId(): number | undefined;
30
- seekTask: Task<readonly [number, Record<number, TrackFragmentIndex> | undefined, {
31
- trackId: string;
32
- buffer: MP4Box.MP4ArrayBuffer;
33
- mp4File: MP4File;
34
- }[] | undefined], Record<string, {
35
- segment: TrackSegment;
36
- track: MP4Box.TrackInfo;
37
- nextSegment?: TrackSegment;
38
- }> | undefined>;
39
- fetchSeekTask: Task<readonly [{
40
- trackId: string;
41
- buffer: MP4Box.MP4ArrayBuffer;
42
- mp4File: MP4File;
43
- }[] | undefined, Record<string, {
44
- segment: TrackSegment;
45
- track: MP4Box.TrackInfo;
46
- nextSegment?: TrackSegment;
47
- }> | undefined, typeof fetch], Record<string, File> | undefined>;
48
- videoAssetTask: Task<readonly [Record<string, File> | undefined], VideoAsset | undefined>;
49
- desiredSeekTimeMs: number;
50
- protected executeSeek(seekToMs: number): Promise<void>;
51
- protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
52
- get hasOwnDuration(): boolean;
53
68
  get intrinsicDurationMs(): number;
54
- audioBufferTask: Task<readonly [Record<string, File> | undefined, Record<string, {
69
+ audioBufferTask: Task<readonly [Record<string, File> | null | undefined, Record<string, {
55
70
  segment: TrackSegment;
56
71
  track: MP4Box.TrackInfo;
57
72
  nextSegment?: TrackSegment;
58
- }> | undefined], {
73
+ }> | null | undefined], {
59
74
  buffer: AudioBuffer;
60
75
  startOffsetMs: number;
61
76
  } | undefined>;
@@ -64,6 +79,10 @@ export declare class EFMedia extends EFMedia_base {
64
79
  startMs: number;
65
80
  endMs: number;
66
81
  } | undefined>;
82
+ /**
83
+ * Encode an AudioBuffer to a WAV blob
84
+ */
85
+ private encodeWAVBuffer;
67
86
  set fftSize(value: number);
68
87
  set fftDecay(value: number);
69
88
  get fftSize(): number;
@@ -77,5 +96,51 @@ export declare class EFMedia extends EFMedia_base {
77
96
  frequencyDataTask: Task<readonly [import('@lit/task').TaskStatus, number, number, number, number, boolean], Uint8Array | null>;
78
97
  set fftGain(value: number);
79
98
  get fftGain(): number;
99
+ private synthesizeFragmentIndex;
100
+ private calculateAssetSegmentKeys;
101
+ private calculateJitSegmentKeys;
102
+ private calculateAssetSeekResult;
103
+ private calculateJitSeekResult;
104
+ private createTrackInfo;
105
+ protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
106
+ get hasOwnDuration(): boolean;
107
+ videoAssetTask: Task<readonly ["asset" | "jit-transcode", Record<string, File> | null | undefined], VideoAsset | undefined>;
108
+ private _desiredSeekTimeMs;
109
+ get desiredSeekTimeMs(): number;
110
+ set desiredSeekTimeMs(value: number);
111
+ protected executeSeek(seekToMs: number): Promise<void>;
112
+ assetIndexLoader: Task<readonly [string | null, typeof fetch], Record<number, TrackFragmentIndex> | null>;
113
+ assetSegmentKeysTask: Task<readonly [Record<number, TrackFragmentIndex> | null | undefined, number], Record<string, {
114
+ startTimeMs: number;
115
+ trackId: string;
116
+ }> | null>;
117
+ assetInitSegmentsTask: Task<readonly [Record<number, TrackFragmentIndex> | null | undefined, typeof fetch], {
118
+ trackId: string;
119
+ buffer: MP4Box.MP4ArrayBuffer;
120
+ mp4File: MP4File;
121
+ }[] | null>;
122
+ assetSegmentLoader: Task<readonly [Record<number, TrackFragmentIndex> | null | undefined, Record<string, {
123
+ startTimeMs: number;
124
+ trackId: string;
125
+ }> | null | undefined, {
126
+ trackId: string;
127
+ buffer: MP4Box.MP4ArrayBuffer;
128
+ mp4File: MP4File;
129
+ }[] | null | undefined, typeof fetch], Record<string, File> | null>;
130
+ jitSegmentKeysTask: Task<readonly [import('../JitTranscodingClient.js').VideoMetadata | null | undefined, number], Record<string, {
131
+ startTimeMs: number;
132
+ trackId: string;
133
+ }> | null>;
134
+ jitSegmentLoader: Task<readonly [string, Record<string, {
135
+ startTimeMs: number;
136
+ trackId: string;
137
+ }> | null | undefined, import('../JitTranscodingClient.js').VideoMetadata | null | undefined], Record<string, File> | null>;
138
+ fragmentIndexTask: Task<readonly [Record<number, TrackFragmentIndex> | null | undefined, import('../JitTranscodingClient.js').VideoMetadata | null | undefined], Record<number, TrackFragmentIndex> | null>;
139
+ mediaSegmentsTask: Task<readonly [Record<string, File> | null | undefined, Record<string, File> | null | undefined], Record<string, File> | null>;
140
+ seekTask: Task<readonly [Record<number, TrackFragmentIndex> | null | undefined, Record<string, File> | null | undefined, number], Record<string, {
141
+ segment: TrackSegment;
142
+ track: MP4Box.TrackInfo;
143
+ nextSegment?: TrackSegment;
144
+ }> | null>;
80
145
  }
81
146
  export {};