@editframe/elements 0.7.0-beta.8 → 0.8.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/EF_INTERACTIVE.d.ts +1 -0
  2. package/dist/{lib/av → assets/dist}/EncodedAsset.js +1 -1
  3. package/dist/{packages/elements/src/elements → elements}/EFAudio.d.ts +2 -2
  4. package/dist/{packages/elements/src/elements → elements}/EFCaptions.d.ts +5 -5
  5. package/dist/{packages/elements/src/elements → elements}/EFImage.d.ts +3 -3
  6. package/dist/{packages/elements/src/elements → elements}/EFMedia.d.ts +4 -4
  7. package/dist/{packages/elements/src/elements → elements}/EFTemporal.d.ts +1 -1
  8. package/dist/{packages/elements/src/elements → elements}/EFTimegroup.browsertest.d.ts +1 -1
  9. package/dist/{packages/elements/src/elements → elements}/EFTimegroup.d.ts +3 -3
  10. package/dist/{packages/elements/src/elements → elements}/EFVideo.d.ts +3 -3
  11. package/dist/{packages/elements/src/elements → elements}/EFWaveform.d.ts +3 -3
  12. package/dist/{packages/elements/src/elements → elements}/TimegroupController.d.ts +1 -1
  13. package/dist/{packages/elements → elements}/src/EF_FRAMEGEN.js +4 -3
  14. package/dist/elements/src/EF_INTERACTIVE.js +7 -0
  15. package/dist/{packages/elements → elements}/src/elements/EFCaptions.js +5 -5
  16. package/dist/{packages/elements → elements}/src/elements/EFMedia.js +6 -3
  17. package/dist/{packages/elements → elements}/src/elements/EFSourceMixin.js +1 -1
  18. package/dist/{packages/elements → elements}/src/elements/EFTemporal.js +37 -2
  19. package/dist/{packages/elements → elements}/src/elements/EFTimegroup.js +4 -2
  20. package/dist/{packages/elements → elements}/src/elements/FetchMixin.js +1 -1
  21. package/dist/elements/src/gui/ContextMixin.js +234 -0
  22. package/dist/{packages/elements → elements}/src/gui/EFFilmstrip.js +30 -134
  23. package/dist/elements/src/gui/EFPreview.js +45 -0
  24. package/dist/{packages/elements → elements}/src/gui/EFWorkbench.js +6 -93
  25. package/dist/{packages/elements → elements}/src/gui/TWMixin.js +10 -2
  26. package/dist/elements/src/gui/apiHostContext.js +5 -0
  27. package/dist/elements/src/gui/fetchContext.js +5 -0
  28. package/dist/elements/src/gui/focusContext.js +5 -0
  29. package/dist/elements/src/gui/focusedElementContext.js +7 -0
  30. package/dist/elements/src/gui/playingContext.js +5 -0
  31. package/dist/{packages/elements → elements}/src/index.js +5 -1
  32. package/dist/{packages/elements/src/elements → elements}/util.d.ts +1 -1
  33. package/dist/gui/ContextMixin.d.ts +23 -0
  34. package/dist/{packages/elements/src/gui → gui}/EFFilmstrip.d.ts +12 -15
  35. package/dist/gui/EFPreview.d.ts +27 -0
  36. package/dist/gui/EFWorkbench.d.ts +34 -0
  37. package/dist/gui/apiHostContext.d.ts +3 -0
  38. package/dist/gui/fetchContext.d.ts +3 -0
  39. package/dist/gui/focusContext.d.ts +6 -0
  40. package/dist/gui/focusedElementContext.d.ts +3 -0
  41. package/dist/gui/playingContext.d.ts +3 -0
  42. package/dist/index.d.ts +11 -0
  43. package/dist/msToTimeCode.d.ts +1 -0
  44. package/dist/style.css +9 -0
  45. package/package.json +6 -9
  46. package/src/elements/EFAudio.ts +1 -1
  47. package/src/elements/EFCaptions.ts +9 -9
  48. package/src/elements/EFImage.ts +3 -3
  49. package/src/elements/EFMedia.ts +11 -8
  50. package/src/elements/EFSourceMixin.ts +1 -1
  51. package/src/elements/EFTemporal.ts +42 -5
  52. package/src/elements/EFTimegroup.browsertest.ts +3 -3
  53. package/src/elements/EFTimegroup.ts +9 -6
  54. package/src/elements/EFVideo.ts +2 -2
  55. package/src/elements/EFWaveform.ts +6 -6
  56. package/src/elements/FetchMixin.ts +5 -3
  57. package/src/elements/TimegroupController.ts +1 -1
  58. package/src/elements/durationConverter.ts +1 -1
  59. package/src/elements/util.ts +1 -1
  60. package/src/gui/ContextMixin.ts +254 -0
  61. package/src/gui/EFFilmstrip.ts +41 -150
  62. package/src/gui/EFPreview.ts +39 -0
  63. package/src/gui/EFWorkbench.ts +7 -105
  64. package/src/gui/TWMixin.ts +10 -3
  65. package/src/gui/apiHostContext.ts +3 -0
  66. package/src/gui/fetchContext.ts +5 -0
  67. package/src/gui/focusContext.ts +7 -0
  68. package/src/gui/focusedElementContext.ts +5 -0
  69. package/src/gui/playingContext.ts +3 -0
  70. package/dist/lib/av/EncodedAsset.cjs +0 -577
  71. package/dist/lib/av/MP4File.cjs +0 -187
  72. package/dist/lib/av/msToTimeCode.cjs +0 -15
  73. package/dist/lib/util/awaitMicrotask.cjs +0 -4
  74. package/dist/lib/util/awaitMicrotask.js +0 -4
  75. package/dist/lib/util/memoize.cjs +0 -14
  76. package/dist/packages/elements/src/EF_FRAMEGEN.cjs +0 -197
  77. package/dist/packages/elements/src/EF_INTERACTIVE.cjs +0 -4
  78. package/dist/packages/elements/src/EF_INTERACTIVE.d.ts +0 -1
  79. package/dist/packages/elements/src/EF_INTERACTIVE.js +0 -4
  80. package/dist/packages/elements/src/elements/CrossUpdateController.cjs +0 -16
  81. package/dist/packages/elements/src/elements/EFAudio.cjs +0 -53
  82. package/dist/packages/elements/src/elements/EFCaptions.cjs +0 -164
  83. package/dist/packages/elements/src/elements/EFImage.cjs +0 -79
  84. package/dist/packages/elements/src/elements/EFMedia.cjs +0 -336
  85. package/dist/packages/elements/src/elements/EFSourceMixin.cjs +0 -55
  86. package/dist/packages/elements/src/elements/EFTemporal.cjs +0 -199
  87. package/dist/packages/elements/src/elements/EFTimegroup.cjs +0 -352
  88. package/dist/packages/elements/src/elements/EFVideo.cjs +0 -109
  89. package/dist/packages/elements/src/elements/EFWaveform.cjs +0 -242
  90. package/dist/packages/elements/src/elements/FetchMixin.cjs +0 -28
  91. package/dist/packages/elements/src/elements/TimegroupController.cjs +0 -20
  92. package/dist/packages/elements/src/elements/durationConverter.cjs +0 -8
  93. package/dist/packages/elements/src/elements/parseTimeToMs.cjs +0 -12
  94. package/dist/packages/elements/src/elements/util.cjs +0 -11
  95. package/dist/packages/elements/src/gui/EFFilmstrip.cjs +0 -825
  96. package/dist/packages/elements/src/gui/EFWorkbench.cjs +0 -214
  97. package/dist/packages/elements/src/gui/EFWorkbench.d.ts +0 -45
  98. package/dist/packages/elements/src/gui/TWMixin.cjs +0 -28
  99. package/dist/packages/elements/src/gui/TWMixin.css.cjs +0 -3
  100. package/dist/packages/elements/src/index.cjs +0 -50
  101. package/dist/packages/elements/src/index.d.ts +0 -10
  102. /package/dist/{packages/elements/src/EF_FRAMEGEN.d.ts → EF_FRAMEGEN.d.ts} +0 -0
  103. /package/dist/{lib/av → assets/dist}/MP4File.js +0 -0
  104. /package/dist/{lib/util → assets/dist}/memoize.js +0 -0
  105. /package/dist/{packages/elements/src/elements → elements}/CrossUpdateController.d.ts +0 -0
  106. /package/dist/{packages/elements/src/elements → elements}/EFSourceMixin.d.ts +0 -0
  107. /package/dist/{packages/elements/src/elements → elements}/FetchMixin.d.ts +0 -0
  108. /package/dist/{packages/elements/src/elements → elements}/durationConverter.d.ts +0 -0
  109. /package/dist/{packages/elements/src/elements → elements}/parseTimeToMs.d.ts +0 -0
  110. /package/dist/{packages/elements → elements}/src/elements/CrossUpdateController.js +0 -0
  111. /package/dist/{packages/elements → elements}/src/elements/EFAudio.js +0 -0
  112. /package/dist/{packages/elements → elements}/src/elements/EFImage.js +0 -0
  113. /package/dist/{packages/elements → elements}/src/elements/EFVideo.js +0 -0
  114. /package/dist/{packages/elements → elements}/src/elements/EFWaveform.js +0 -0
  115. /package/dist/{packages/elements → elements}/src/elements/TimegroupController.js +0 -0
  116. /package/dist/{packages/elements → elements}/src/elements/durationConverter.js +0 -0
  117. /package/dist/{packages/elements → elements}/src/elements/parseTimeToMs.js +0 -0
  118. /package/dist/{packages/elements → elements}/src/elements/util.js +0 -0
  119. /package/dist/{packages/elements → elements}/src/gui/TWMixin.css.js +0 -0
  120. /package/dist/{lib/av → elements/src}/msToTimeCode.js +0 -0
  121. /package/dist/{packages/elements/src/gui → gui}/TWMixin.d.ts +0 -0
@@ -0,0 +1 @@
1
+ export declare let EF_INTERACTIVE: boolean;
@@ -1,6 +1,6 @@
1
1
  import * as MP4Box from "mp4box";
2
2
  import debug from "debug";
3
- import { memoize } from "../util/memoize.js";
3
+ import { memoize } from "./memoize.js";
4
4
  import { MP4File } from "./MP4File.js";
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1,8 +1,8 @@
1
- import { EFMedia } from './EFMedia';
1
+ import { EFMedia } from './EFMedia.ts';
2
2
  import { Task } from '@lit/task';
3
3
 
4
4
  export declare class EFAudio extends EFMedia {
5
- audioElementRef: import('lit-html/directives/ref').Ref<HTMLAudioElement>;
5
+ audioElementRef: import('lit-html/directives/ref.js').Ref<HTMLAudioElement>;
6
6
  src: string;
7
7
  render(): import('lit-html').TemplateResult<1>;
8
8
  get audioElement(): HTMLAudioElement | undefined;
@@ -1,9 +1,9 @@
1
- import { EFAudio } from './EFAudio';
2
1
  import { LitElement, PropertyValueMap } from 'lit';
3
2
  import { Task } from '@lit/task';
4
- import { EFVideo } from './EFVideo';
3
+ import { EFVideo } from './EFVideo.ts';
4
+ import { EFAudio } from './EFAudio.ts';
5
5
 
6
- declare const EFCaptionsActiveWord_base: (new (...args: any[]) => import('./EFTemporal').TemporalMixinInterface) & typeof LitElement;
6
+ declare const EFCaptionsActiveWord_base: (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & typeof LitElement;
7
7
  export declare class EFCaptionsActiveWord extends EFCaptionsActiveWord_base {
8
8
  static styles: import('lit').CSSResult[];
9
9
  render(): import('lit-html').TemplateResult<1>;
@@ -13,14 +13,14 @@ export declare class EFCaptionsActiveWord extends EFCaptionsActiveWord_base {
13
13
  get startTimeMs(): number;
14
14
  get durationMs(): number;
15
15
  }
16
- declare const EFCaptions_base: (new (...args: any[]) => import('./EFSourceMixin').EFSourceMixinInterface) & (new (...args: any[]) => import('./EFTemporal').TemporalMixinInterface) & (new (...args: any[]) => import('./FetchMixin').FetchMixinInterface) & typeof LitElement;
16
+ declare const EFCaptions_base: (new (...args: any[]) => import('./EFSourceMixin.ts').EFSourceMixinInterface) & (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & (new (...args: any[]) => import('./FetchMixin.ts').FetchMixinInterface) & typeof LitElement;
17
17
  export declare class EFCaptions extends EFCaptions_base {
18
18
  static styles: import('lit').CSSResult[];
19
19
  target: null;
20
20
  wordStyle: string;
21
21
  activeWordContainers: HTMLCollectionOf<EFCaptionsActiveWord>;
22
22
  captionsPath(): string;
23
- protected md5SumLoader: Task<readonly [null], string | undefined>;
23
+ protected md5SumLoader: Task<readonly [null, typeof fetch], string | undefined>;
24
24
  private captionsDataTask;
25
25
  frameTask: Task<import('@lit/task').TaskStatus[], void>;
26
26
  connectedCallback(): void;
@@ -1,11 +1,11 @@
1
1
  import { Task } from '@lit/task';
2
2
  import { LitElement } from 'lit';
3
3
 
4
- declare const EFImage_base: (new (...args: any[]) => import('./EFSourceMixin').EFSourceMixinInterface) & (new (...args: any[]) => import('./FetchMixin').FetchMixinInterface) & typeof LitElement;
4
+ declare const EFImage_base: (new (...args: any[]) => import('./EFSourceMixin.ts').EFSourceMixinInterface) & (new (...args: any[]) => import('./FetchMixin.ts').FetchMixinInterface) & typeof LitElement;
5
5
  export declare class EFImage extends EFImage_base {
6
6
  static styles: import('lit').CSSResult[];
7
- imageRef: import('lit-html/directives/ref').Ref<HTMLImageElement>;
8
- canvasRef: import('lit-html/directives/ref').Ref<HTMLCanvasElement>;
7
+ imageRef: import('lit-html/directives/ref.js').Ref<HTMLImageElement>;
8
+ canvasRef: import('lit-html/directives/ref.js').Ref<HTMLCanvasElement>;
9
9
  render(): import('lit-html').TemplateResult<1>;
10
10
  assetPath(): string;
11
11
  fetchImage: Task<readonly [string, typeof fetch], void>;
@@ -1,12 +1,12 @@
1
1
  import { LitElement, PropertyValueMap } from 'lit';
2
2
  import { Task } from '@lit/task';
3
3
  import { TrackFragmentIndex, TrackSegment } from '../../../assets/src';
4
- import { MP4File } from '../../../../lib/av/MP4File';
5
- import { VideoAsset } from '../../../../lib/av/EncodedAsset';
4
+ import { MP4File } from '../../../assets/MP4File.js/src';
5
+ import { VideoAsset } from '../../../assets/EncodedAsset.js/src';
6
6
 
7
7
  import type * as MP4Box from "mp4box";
8
8
  export declare const deepGetMediaElements: (element: Element, medias?: EFMedia[]) => EFMedia[];
9
- declare const EFMedia_base: (new (...args: any[]) => import('./EFSourceMixin').EFSourceMixinInterface) & (new (...args: any[]) => import('./EFTemporal').TemporalMixinInterface) & (new (...args: any[]) => import('./FetchMixin').FetchMixinInterface) & typeof LitElement;
9
+ declare const EFMedia_base: (new (...args: any[]) => import('./EFSourceMixin.ts').EFSourceMixinInterface) & (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & (new (...args: any[]) => import('./FetchMixin.ts').FetchMixinInterface) & typeof LitElement;
10
10
  export declare class EFMedia extends EFMedia_base {
11
11
  #private;
12
12
  static styles: import('lit').CSSResult[];
@@ -14,7 +14,7 @@ export declare class EFMedia extends EFMedia_base {
14
14
  efHost?: string;
15
15
  fragmentIndexPath(): string;
16
16
  fragmentTrackPath(trackId: string): string;
17
- trackFragmentIndexLoader: Task<readonly [string, typeof fetch], Record<number, TrackFragmentIndex>>;
17
+ trackFragmentIndexLoader: Task<readonly [string, typeof fetch], Record<number, TrackFragmentIndex> | undefined>;
18
18
  protected initSegmentsLoader: Task<readonly [Record<number, TrackFragmentIndex> | undefined, string, typeof fetch], {
19
19
  trackId: string;
20
20
  buffer: MP4Box.MP4ArrayBuffer;
@@ -1,5 +1,5 @@
1
1
  import { LitElement, ReactiveController } from 'lit';
2
- import { EFTimegroup } from './EFTimegroup';
2
+ import { EFTimegroup } from './EFTimegroup.ts';
3
3
  import { Task } from '@lit/task';
4
4
 
5
5
  export declare const timegroupContext: {
@@ -1,6 +1,6 @@
1
1
  import { LitElement } from 'lit';
2
2
 
3
- declare const TestTemporal_base: (new (...args: any[]) => import('./EFTemporal').TemporalMixinInterface) & typeof LitElement;
3
+ declare const TestTemporal_base: (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & typeof LitElement;
4
4
  declare class TestTemporal extends TestTemporal_base {
5
5
  get hasOwnDuration(): boolean;
6
6
  }
@@ -2,7 +2,7 @@ import { LitElement, PropertyValueMap } from 'lit';
2
2
  import { Task } from '@lit/task';
3
3
 
4
4
  export declare const shallowGetTimegroups: (element: Element, groups?: EFTimegroup[]) => EFTimegroup[];
5
- declare const EFTimegroup_base: (new (...args: any[]) => import('./EFTemporal').TemporalMixinInterface) & typeof LitElement;
5
+ declare const EFTimegroup_base: (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & typeof LitElement;
6
6
  export declare class EFTimegroup extends EFTimegroup_base {
7
7
  #private;
8
8
  static styles: import('lit').CSSResult;
@@ -20,8 +20,8 @@ export declare class EFTimegroup extends EFTimegroup_base {
20
20
  get crossoverStartMs(): number;
21
21
  get crossoverEndMs(): number;
22
22
  get durationMs(): number;
23
- waitForMediaDurations(): Promise<Record<number, import('../../../assets/src').TrackFragmentIndex>[]>;
24
- get childTemporals(): import('./EFTemporal').TemporalMixinInterface[];
23
+ waitForMediaDurations(): Promise<(Record<number, import('packages/assets/dist/Probe.js').TrackFragmentIndex> | undefined)[]>;
24
+ get childTemporals(): import('./EFTemporal.ts').TemporalMixinInterface[];
25
25
  protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
26
26
  shouldWrapWithWorkbench(): boolean;
27
27
  wrapWithWorkbench(): void;
@@ -1,14 +1,14 @@
1
1
  import { Task } from '@lit/task';
2
- import { EFMedia } from './EFMedia';
2
+ import { EFMedia } from './EFMedia.ts';
3
3
 
4
4
  declare const EFVideo_base: typeof EFMedia;
5
5
  export declare class EFVideo extends EFVideo_base {
6
6
  #private;
7
7
  static styles: import('lit').CSSResult[];
8
- canvasRef: import('lit-html/directives/ref').Ref<HTMLCanvasElement>;
8
+ canvasRef: import('lit-html/directives/ref.js').Ref<HTMLCanvasElement>;
9
9
  render(): import('lit-html').TemplateResult<1>;
10
10
  get canvasElement(): HTMLCanvasElement | undefined;
11
11
  frameTask: Task<readonly [import('@lit/task').TaskStatus, import('@lit/task').TaskStatus, import('@lit/task').TaskStatus, import('@lit/task').TaskStatus, import('@lit/task').TaskStatus, import('@lit/task').TaskStatus], void>;
12
- paintTask: Task<readonly [import('../../../../lib/av/EncodedAsset').VideoAsset | undefined, number], number | undefined>;
12
+ paintTask: Task<readonly [import('packages/assets/dist/EncodedAsset.js').VideoAsset | undefined, number], number | undefined>;
13
13
  }
14
14
  export {};
@@ -1,10 +1,10 @@
1
- import { EFAudio } from './EFAudio';
1
+ import { EFAudio } from './EFAudio.ts';
2
2
  import { LitElement } from 'lit';
3
- import { EFVideo } from './EFVideo';
3
+ import { EFVideo } from './EFVideo.ts';
4
4
  import { Task } from '@lit/task';
5
5
  import { Ref } from 'lit/directives/ref.js';
6
6
 
7
- declare const EFWaveform_base: (new (...args: any[]) => import('./EFTemporal').TemporalMixinInterface) & typeof LitElement;
7
+ declare const EFWaveform_base: (new (...args: any[]) => import('./EFTemporal.ts').TemporalMixinInterface) & typeof LitElement;
8
8
  export declare class EFWaveform extends EFWaveform_base {
9
9
  static styles: never[];
10
10
  svgRef: Ref<SVGElement>;
@@ -1,5 +1,5 @@
1
1
  import { ReactiveController, LitElement } from 'lit';
2
- import { EFTimegroup } from './EFTimegroup';
2
+ import { EFTimegroup } from './EFTimegroup.ts';
3
3
 
4
4
  export declare class TimegroupController implements ReactiveController {
5
5
  private host;
@@ -1,6 +1,5 @@
1
1
  import debug from "debug";
2
2
  import { TaskStatus } from "@lit/task";
3
- import { awaitMicrotask } from "../../../lib/util/awaitMicrotask.js";
4
3
  import { deepGetElementsWithFrameTasks } from "./elements/EFTemporal.js";
5
4
  import { shallowGetTimegroups } from "./elements/EFTimegroup.js";
6
5
  const log = debug("ef:elements:EF_FRAMEGEN");
@@ -136,7 +135,7 @@ class EfFramegen {
136
135
  log("Awaiting initialBusyTasks");
137
136
  await this.initialBusyTasks;
138
137
  log("Awaiting microtask");
139
- await awaitMicrotask();
138
+ await new Promise(queueMicrotask);
140
139
  log("Awaiting frame tasks");
141
140
  const now = performance.now();
142
141
  await Promise.all(
@@ -191,7 +190,9 @@ class EfFramegen {
191
190
  }
192
191
  }
193
192
  }
194
- window.EF_FRAMEGEN = new EfFramegen();
193
+ if (typeof window !== "undefined") {
194
+ window.EF_FRAMEGEN = new EfFramegen();
195
+ }
195
196
  export {
196
197
  EfFramegen
197
198
  };
@@ -0,0 +1,7 @@
1
+ let EF_INTERACTIVE = false;
2
+ if (typeof window !== "undefined") {
3
+ EF_INTERACTIVE = !window.location?.search.includes("EF_NONINTERACTIVE");
4
+ }
5
+ export {
6
+ EF_INTERACTIVE
7
+ };
@@ -1,8 +1,8 @@
1
- import { EFAudio } from "./EFAudio.js";
2
1
  import { html, css, LitElement } from "lit";
3
2
  import { Task } from "@lit/task";
4
3
  import { property, customElement } from "lit/decorators.js";
5
4
  import { EFVideo } from "./EFVideo.js";
5
+ import { EFAudio } from "./EFAudio.js";
6
6
  import { EFTemporal } from "./EFTemporal.js";
7
7
  import { CrossUpdateController } from "./CrossUpdateController.js";
8
8
  import { FetchMixin } from "./FetchMixin.js";
@@ -65,8 +65,8 @@ let EFCaptions = class extends EFSourceMixin(
65
65
  this.activeWordContainers = this.getElementsByTagName("ef-captions-active-word");
66
66
  this.md5SumLoader = new Task(this, {
67
67
  autoRun: false,
68
- args: () => [this.target],
69
- task: async ([], { signal }) => {
68
+ args: () => [this.target, this.fetch],
69
+ task: async ([_target, fetch], { signal }) => {
70
70
  const md5Path = `/@ef-asset/${this.targetElement.src ?? ""}`;
71
71
  const response = await fetch(md5Path, { method: "HEAD", signal });
72
72
  return response.headers.get("etag") ?? void 0;
@@ -75,8 +75,8 @@ let EFCaptions = class extends EFSourceMixin(
75
75
  this.captionsDataTask = new Task(this, {
76
76
  autoRun: EF_INTERACTIVE,
77
77
  args: () => [this.captionsPath(), this.fetch],
78
- task: async ([captionsPath, fetch2], { signal }) => {
79
- const response = await fetch2(captionsPath, { signal });
78
+ task: async ([captionsPath, fetch], { signal }) => {
79
+ const response = await fetch(captionsPath, { signal });
80
80
  return response.json();
81
81
  }
82
82
  });
@@ -4,14 +4,14 @@ import { deepArrayEquals } from "@lit/task/deep-equals.js";
4
4
  import { Task } from "@lit/task";
5
5
  import { consume } from "@lit/context";
6
6
  import debug from "debug";
7
- import { MP4File } from "../../../../lib/av/MP4File.js";
7
+ import { MP4File } from "../../../assets/dist/MP4File.js";
8
+ import { VideoAsset } from "../../../assets/dist/EncodedAsset.js";
8
9
  import { EFTemporal } from "./EFTemporal.js";
9
- import { VideoAsset } from "../../../../lib/av/EncodedAsset.js";
10
10
  import { FetchMixin } from "./FetchMixin.js";
11
- import { apiHostContext } from "../gui/EFWorkbench.js";
12
11
  import { EFSourceMixin } from "./EFSourceMixin.js";
13
12
  import { getStartTimeMs } from "./util.js";
14
13
  import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
14
+ import { apiHostContext } from "../gui/apiHostContext.js";
15
15
  var __defProp = Object.defineProperty;
16
16
  var __decorateClass = (decorators, target, key, kind) => {
17
17
  var result = void 0;
@@ -41,6 +41,9 @@ class EFMedia extends EFSourceMixin(EFTemporal(FetchMixin(LitElement)), {
41
41
  this.trackFragmentIndexLoader = new Task(this, {
42
42
  args: () => [this.fragmentIndexPath(), this.fetch],
43
43
  task: async ([fragmentIndexPath, fetch], { signal }) => {
44
+ if (this.src === "") {
45
+ return;
46
+ }
44
47
  const response = await fetch(fragmentIndexPath, { signal });
45
48
  return await response.json();
46
49
  },
@@ -1,8 +1,8 @@
1
1
  import { consume } from "@lit/context";
2
- import { apiHostContext } from "../gui/EFWorkbench.js";
3
2
  import { state } from "lit/decorators/state.js";
4
3
  import { Task } from "@lit/task";
5
4
  import { property } from "lit/decorators/property.js";
5
+ import { apiHostContext } from "../gui/apiHostContext.js";
6
6
  var __defProp = Object.defineProperty;
7
7
  var __decorateClass = (decorators, target, key, kind) => {
8
8
  var result = void 0;
@@ -36,7 +36,19 @@ const deepGetElementsWithFrameTasks = (element, elements = []) => {
36
36
  }
37
37
  return elements;
38
38
  };
39
+ let temporalCache;
40
+ const resetTemporalCache = () => {
41
+ temporalCache = /* @__PURE__ */ new Map();
42
+ if (typeof requestAnimationFrame !== "undefined") {
43
+ requestAnimationFrame(resetTemporalCache);
44
+ }
45
+ };
46
+ resetTemporalCache();
39
47
  const shallowGetTemporalElements = (element, temporals = []) => {
48
+ const cachedResult = temporalCache.get(element);
49
+ if (cachedResult) {
50
+ return cachedResult;
51
+ }
40
52
  for (const child of element.children) {
41
53
  if (isEFTemporal(child)) {
42
54
  temporals.push(child);
@@ -44,6 +56,7 @@ const shallowGetTemporalElements = (element, temporals = []) => {
44
56
  shallowGetTemporalElements(child, temporals);
45
57
  }
46
58
  }
59
+ temporalCache.set(element, temporals);
47
60
  return temporals;
48
61
  };
49
62
  class OwnCurrentTimeController {
@@ -59,6 +72,14 @@ class OwnCurrentTimeController {
59
72
  this.host.removeController(this);
60
73
  }
61
74
  }
75
+ let startTimeMsCache = /* @__PURE__ */ new WeakMap();
76
+ const resetStartTimeMsCache = () => {
77
+ startTimeMsCache = /* @__PURE__ */ new WeakMap();
78
+ if (typeof requestAnimationFrame !== "undefined") {
79
+ requestAnimationFrame(resetStartTimeMsCache);
80
+ }
81
+ };
82
+ resetStartTimeMsCache();
62
83
  const EFTemporal = (superClass) => {
63
84
  class TemporalMixinClass extends superClass {
64
85
  constructor() {
@@ -123,27 +144,41 @@ const EFTemporal = (superClass) => {
123
144
  return this.startTimeMs - this.parentTemporal.startTimeMs;
124
145
  }
125
146
  get startTimeMs() {
147
+ const cachedStartTime = startTimeMsCache.get(this);
148
+ if (cachedStartTime !== void 0) {
149
+ return cachedStartTime;
150
+ }
126
151
  const parentTimegroup = this.parentTimegroup;
127
152
  if (!parentTimegroup) {
153
+ startTimeMsCache.set(this, 0);
128
154
  return 0;
129
155
  }
130
156
  switch (parentTimegroup.mode) {
131
157
  case "sequence": {
132
158
  const siblingTemorals = shallowGetTemporalElements(parentTimegroup);
133
- const ownIndex = siblingTemorals.indexOf(
159
+ const ownIndex = siblingTemorals?.indexOf(
134
160
  this
135
161
  );
136
162
  if (ownIndex === 0) {
163
+ startTimeMsCache.set(this, parentTimegroup.startTimeMs);
137
164
  return parentTimegroup.startTimeMs;
138
165
  }
139
- const previous = siblingTemorals[ownIndex - 1];
166
+ const previous = siblingTemorals?.[(ownIndex ?? 0) - 1];
140
167
  if (!previous) {
141
168
  throw new Error("Previous temporal element not found");
142
169
  }
170
+ startTimeMsCache.set(
171
+ this,
172
+ previous.startTimeMs + previous.durationMs
173
+ );
143
174
  return previous.startTimeMs + previous.durationMs;
144
175
  }
145
176
  case "contain":
146
177
  case "fixed":
178
+ startTimeMsCache.set(
179
+ this,
180
+ parentTimegroup.startTimeMs + this.offsetMs
181
+ );
147
182
  return parentTimegroup.startTimeMs + this.offsetMs;
148
183
  default:
149
184
  throw new Error(`Invalid time mode: ${parentTimegroup.mode}`);
@@ -93,7 +93,9 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
93
93
  connectedCallback() {
94
94
  super.connectedCallback();
95
95
  if (this.id) {
96
- __privateSet(this, _currentTime, this.maybeLoadTimeFromLocalStorage());
96
+ this.waitForMediaDurations().then(() => {
97
+ __privateSet(this, _currentTime, this.maybeLoadTimeFromLocalStorage());
98
+ });
97
99
  }
98
100
  if (this.parentTimegroup) {
99
101
  new TimegroupController(this.parentTimegroup, this);
@@ -216,7 +218,7 @@ let EFTimegroup = class extends EFTemporal(LitElement) {
216
218
  }
217
219
  }
218
220
  shouldWrapWithWorkbench() {
219
- return EF_INTERACTIVE && this.closest("ef-timegroup") === this && this.closest("ef-workbench") === null;
221
+ return EF_INTERACTIVE && this.closest("ef-timegroup") === this && this.closest("ef-workbench") === null && this.closest("ef-preview") === null;
220
222
  }
221
223
  wrapWithWorkbench() {
222
224
  const workbench = document.createElement("ef-workbench");
@@ -1,6 +1,6 @@
1
1
  import { consume } from "@lit/context";
2
- import { fetchContext } from "../gui/EFWorkbench.js";
3
2
  import { state } from "lit/decorators/state.js";
3
+ import { fetchContext } from "../gui/fetchContext.js";
4
4
  var __defProp = Object.defineProperty;
5
5
  var __decorateClass = (decorators, target, key, kind) => {
6
6
  var result = void 0;
@@ -0,0 +1,234 @@
1
+ import { provide } from "@lit/context";
2
+ import { state, property } from "lit/decorators.js";
3
+ import { focusContext } from "./focusContext.js";
4
+ import { focusedElementContext } from "./focusedElementContext.js";
5
+ import { fetchContext } from "./fetchContext.js";
6
+ import { apiHostContext } from "./apiHostContext.js";
7
+ import { createRef } from "lit/directives/ref.js";
8
+ import { playingContext } from "./playingContext.js";
9
+ var __defProp = Object.defineProperty;
10
+ var __decorateClass = (decorators, target, key, kind) => {
11
+ var result = void 0;
12
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
13
+ if (decorator = decorators[i])
14
+ result = decorator(target, key, result) || result;
15
+ if (result) __defProp(target, key, result);
16
+ return result;
17
+ };
18
+ function ContextMixin(superClass) {
19
+ class ContextElement extends superClass {
20
+ constructor() {
21
+ super(...arguments);
22
+ this.focusContext = this;
23
+ this.fetch = async (url, init = {}) => {
24
+ init.headers ||= {};
25
+ Object.assign(init.headers, {
26
+ "Content-Type": "application/json"
27
+ });
28
+ const bearerToken = this.apiToken;
29
+ if (bearerToken) {
30
+ Object.assign(init.headers, {
31
+ Authorization: `Bearer ${bearerToken}`
32
+ });
33
+ }
34
+ if (this.signingURL) {
35
+ if (!this.#signedURLs[url]) {
36
+ this.#signedURLs[url] = fetch(this.signingURL, {
37
+ method: "POST",
38
+ body: JSON.stringify({ url })
39
+ }).then(async (response) => {
40
+ if (response.ok) {
41
+ return (await response.json()).url;
42
+ }
43
+ throw new Error(
44
+ `Failed to sign URL: ${url}. SigningURL: ${this.signingURL} ${response.status} ${response.statusText}`
45
+ );
46
+ });
47
+ }
48
+ const signedURL = await this.#signedURLs[url];
49
+ return fetch(signedURL, init);
50
+ }
51
+ return fetch(url, init);
52
+ };
53
+ this.#signedURLs = {};
54
+ this.apiHost = "";
55
+ this.playing = false;
56
+ this.loop = false;
57
+ this.stageScale = 1;
58
+ this.rendering = false;
59
+ this.currentTimeMs = 0;
60
+ this.stageRef = createRef();
61
+ this.canvasRef = createRef();
62
+ this.setStageScale = () => {
63
+ if (this.isConnected && !this.rendering) {
64
+ const canvasElement = this.canvasRef.value;
65
+ const stageElement = this.stageRef.value;
66
+ if (stageElement && canvasElement) {
67
+ const stageWidth = stageElement.clientWidth;
68
+ const stageHeight = stageElement.clientHeight;
69
+ const canvasWidth = canvasElement.clientWidth;
70
+ const canvasHeight = canvasElement.clientHeight;
71
+ const stageRatio = stageWidth / stageHeight;
72
+ const canvasRatio = canvasWidth / canvasHeight;
73
+ if (stageRatio > canvasRatio) {
74
+ const scale = stageHeight / canvasHeight;
75
+ if (this.stageScale !== scale) {
76
+ canvasElement.style.transform = `scale(${scale})`;
77
+ }
78
+ this.stageScale = scale;
79
+ } else {
80
+ const scale = stageWidth / canvasWidth;
81
+ if (this.stageScale !== scale) {
82
+ canvasElement.style.transform = `scale(${scale})`;
83
+ }
84
+ this.stageScale = scale;
85
+ }
86
+ }
87
+ }
88
+ if (this.isConnected) {
89
+ requestAnimationFrame(this.setStageScale);
90
+ }
91
+ };
92
+ this.#playbackAudioContext = null;
93
+ this.#playbackAnimationFrameRequest = null;
94
+ this.#AUDIO_PLAYBACK_SLICE_MS = 1e3;
95
+ }
96
+ #signedURLs;
97
+ connectedCallback() {
98
+ super.connectedCallback();
99
+ requestAnimationFrame(this.setStageScale);
100
+ }
101
+ update(changedProperties) {
102
+ if (changedProperties.has("playing")) {
103
+ if (this.playing) {
104
+ this.#startPlayback();
105
+ } else {
106
+ this.#stopPlayback();
107
+ }
108
+ }
109
+ if (changedProperties.has("currentTimeMs") && this.targetTimegroup) {
110
+ if (this.targetTimegroup.currentTimeMs !== this.currentTimeMs) {
111
+ this.targetTimegroup.currentTimeMs = this.currentTimeMs;
112
+ }
113
+ }
114
+ super.update(changedProperties);
115
+ }
116
+ get targetTimegroup() {
117
+ return this.querySelector("ef-timegroup");
118
+ }
119
+ #playbackAudioContext;
120
+ #playbackAnimationFrameRequest;
121
+ #AUDIO_PLAYBACK_SLICE_MS;
122
+ #syncPlayheadToAudioContext(target, startMs) {
123
+ this.currentTimeMs = startMs + (this.#playbackAudioContext?.currentTime ?? 0) * 1e3;
124
+ this.#playbackAnimationFrameRequest = requestAnimationFrame(() => {
125
+ this.#syncPlayheadToAudioContext(target, startMs);
126
+ });
127
+ }
128
+ async #stopPlayback() {
129
+ if (this.#playbackAudioContext) {
130
+ if (this.#playbackAudioContext.state !== "closed") {
131
+ await this.#playbackAudioContext.close();
132
+ }
133
+ }
134
+ if (this.#playbackAnimationFrameRequest) {
135
+ cancelAnimationFrame(this.#playbackAnimationFrameRequest);
136
+ }
137
+ this.#playbackAudioContext = null;
138
+ }
139
+ async #startPlayback() {
140
+ await this.#stopPlayback();
141
+ const timegroup = this.targetTimegroup;
142
+ if (!timegroup) {
143
+ return;
144
+ }
145
+ let currentMs = timegroup.currentTimeMs;
146
+ let bufferCount = 0;
147
+ this.#playbackAudioContext = new AudioContext({
148
+ latencyHint: "playback"
149
+ });
150
+ if (this.#playbackAnimationFrameRequest) {
151
+ cancelAnimationFrame(this.#playbackAnimationFrameRequest);
152
+ }
153
+ this.#syncPlayheadToAudioContext(timegroup, currentMs);
154
+ const playbackContext = this.#playbackAudioContext;
155
+ await playbackContext.suspend();
156
+ const fillBuffer = async () => {
157
+ if (bufferCount > 1) {
158
+ return;
159
+ }
160
+ const canFillBuffer = await queueBufferSource();
161
+ if (canFillBuffer) {
162
+ fillBuffer();
163
+ }
164
+ };
165
+ const fromMs = currentMs;
166
+ const toMs = timegroup.endTimeMs;
167
+ const queueBufferSource = async () => {
168
+ if (currentMs >= toMs) {
169
+ return false;
170
+ }
171
+ const startMs = currentMs;
172
+ const endMs = currentMs + this.#AUDIO_PLAYBACK_SLICE_MS;
173
+ currentMs += this.#AUDIO_PLAYBACK_SLICE_MS;
174
+ const audioBuffer = await timegroup.renderAudio(startMs, endMs);
175
+ bufferCount++;
176
+ const source = playbackContext.createBufferSource();
177
+ source.buffer = audioBuffer;
178
+ source.connect(playbackContext.destination);
179
+ source.start((startMs - fromMs) / 1e3);
180
+ source.onended = () => {
181
+ bufferCount--;
182
+ if (endMs >= toMs) {
183
+ this.playing = false;
184
+ } else {
185
+ fillBuffer();
186
+ }
187
+ };
188
+ return true;
189
+ };
190
+ await fillBuffer();
191
+ await playbackContext.resume();
192
+ }
193
+ }
194
+ __decorateClass([
195
+ provide({ context: focusContext })
196
+ ], ContextElement.prototype, "focusContext");
197
+ __decorateClass([
198
+ provide({ context: focusedElementContext }),
199
+ state()
200
+ ], ContextElement.prototype, "focusedElement");
201
+ __decorateClass([
202
+ provide({ context: fetchContext })
203
+ ], ContextElement.prototype, "fetch");
204
+ __decorateClass([
205
+ property({ type: String })
206
+ ], ContextElement.prototype, "signingURL");
207
+ __decorateClass([
208
+ property({ type: String })
209
+ ], ContextElement.prototype, "apiToken");
210
+ __decorateClass([
211
+ provide({ context: apiHostContext }),
212
+ property({ type: String })
213
+ ], ContextElement.prototype, "apiHost");
214
+ __decorateClass([
215
+ provide({ context: playingContext }),
216
+ property({ type: Boolean, reflect: true })
217
+ ], ContextElement.prototype, "playing");
218
+ __decorateClass([
219
+ property({ type: Boolean, reflect: true })
220
+ ], ContextElement.prototype, "loop");
221
+ __decorateClass([
222
+ state()
223
+ ], ContextElement.prototype, "stageScale");
224
+ __decorateClass([
225
+ property({ type: Boolean })
226
+ ], ContextElement.prototype, "rendering");
227
+ __decorateClass([
228
+ state()
229
+ ], ContextElement.prototype, "currentTimeMs");
230
+ return ContextElement;
231
+ }
232
+ export {
233
+ ContextMixin
234
+ };