@editframe/elements 0.15.0-beta.17 → 0.15.0-beta.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@editframe/elements",
3
- "version": "0.15.0-beta.17",
3
+ "version": "0.15.0-beta.5",
4
4
  "description": "",
5
5
  "exports": {
6
6
  ".": {
@@ -10,31 +10,26 @@
10
10
  }
11
11
  },
12
12
  "./styles.css": "./dist/style.css",
13
- "./types.json": {
14
- "import": {
15
- "default": "./types.json"
16
- }
17
- }
13
+ "./types.json": "./dist/types.json"
18
14
  },
19
15
  "type": "module",
20
16
  "scripts": {
21
17
  "typecheck": "tsc --noEmit --emitDeclarationOnly false",
22
18
  "build": "vite build",
23
19
  "build:watch": "vite build --watch",
24
- "typedoc": "typedoc --json ./types.json --plugin typedoc-plugin-zod --excludeExternals ./src && jq -c . ./types.json > ./types.tmp.json && mv ./types.tmp.json ./types.json"
20
+ "typedoc": "typedoc --json ./dist/types.json --plugin typedoc-plugin-zod --excludeExternals ./src && jq -c . ./dist/types.json > ./dist/types.tmp.json && mv ./dist/types.tmp.json ./dist/types.json"
25
21
  },
26
22
  "author": "",
27
23
  "license": "UNLICENSED",
28
24
  "dependencies": {
29
25
  "@bramus/style-observer": "^1.3.0",
30
- "@editframe/assets": "0.15.0-beta.17",
26
+ "@editframe/assets": "0.15.0-beta.5",
31
27
  "@lit/context": "^1.1.2",
32
28
  "@lit/task": "^1.0.1",
33
29
  "d3": "^7.9.0",
34
30
  "debug": "^4.3.5",
35
31
  "lit": "^3.1.4",
36
- "mp4box": "^0.5.2",
37
- "zod": "^3.24.1"
32
+ "mp4box": "^0.5.2"
38
33
  },
39
34
  "devDependencies": {
40
35
  "@types/d3": "^7.4.3",
@@ -126,14 +126,8 @@ export class EFMedia extends EFTargetable(
126
126
  public trackFragmentIndexLoader = new Task(this, {
127
127
  args: () => [this.fragmentIndexPath(), this.fetch] as const,
128
128
  task: async ([fragmentIndexPath, fetch], { signal }) => {
129
- try {
130
- const response = await fetch(fragmentIndexPath, { signal });
131
-
132
- return (await response.json()) as Record<number, TrackFragmentIndex>;
133
- } catch (error) {
134
- log("Failed to load track fragment index", error);
135
- return undefined;
136
- }
129
+ const response = await fetch(fragmentIndexPath, { signal });
130
+ return (await response.json()) as Record<number, TrackFragmentIndex>;
137
131
  },
138
132
  onComplete: () => {
139
133
  this.requestUpdate("ownCurrentTimeMs");
@@ -590,33 +584,14 @@ export class EFMedia extends EFTargetable(
590
584
  };
591
585
  }
592
586
 
593
- set fftSize(value: number) {
594
- const oldValue = this.fftSize;
595
- this.setAttribute("fft-size", String(value));
596
- this.requestUpdate("fft-size", oldValue);
597
- }
598
-
599
- set fftDecay(value: number) {
600
- const oldValue = this.fftDecay;
601
- this.setAttribute("fft-decay", String(value));
602
- this.requestUpdate("fft-decay", oldValue);
603
- }
604
-
605
- get fftSize() {
606
- return Number.parseInt(this.getAttribute("fft-size") ?? "128", 10);
607
- }
608
-
609
- get fftDecay() {
610
- return Number.parseInt(this.getAttribute("fft-decay") ?? "8", 10);
611
- }
587
+ @property({ type: Number })
588
+ fftSize = 512; // Default FFT size
612
589
 
613
- get shouldInterpolateFrequencies() {
614
- if (this.hasAttribute("interpolate-frequencies")) {
615
- return this.getAttribute("interpolate-frequencies") !== "false";
616
- }
617
- return false;
618
- }
590
+ @property({ type: Number })
591
+ fftDecay = 8; // Default number of frames to analyze
619
592
 
593
+ private static readonly MIN_DB = -90;
594
+ private static readonly MAX_DB = -20;
620
595
  private static readonly DECAY_WEIGHT = 0.7;
621
596
 
622
597
  // Update FREQ_WEIGHTS to use the instance fftSize instead of a static value
@@ -641,130 +616,6 @@ export class EFMedia extends EFTargetable(
641
616
  return weights;
642
617
  }
643
618
 
644
- #byteTimeDomainCache = new LRUCache<string, Uint8Array>(100);
645
-
646
- byteTimeDomainTask = new Task(this, {
647
- autoRun: EF_INTERACTIVE,
648
- args: () =>
649
- [
650
- this.audioBufferTask.status,
651
- this.currentSourceTimeMs,
652
- this.fftSize,
653
- this.fftDecay,
654
- ] as const,
655
- task: async () => {
656
- await this.audioBufferTask.taskComplete;
657
- if (!this.audioBufferTask.value) return null;
658
- if (this.currentSourceTimeMs <= 0) return null;
659
-
660
- const currentTimeMs = this.currentSourceTimeMs;
661
- const startOffsetMs = this.audioBufferTask.value.startOffsetMs;
662
- const audioBuffer = this.audioBufferTask.value.buffer;
663
-
664
- const smoothedKey = `${this.fftSize}:${this.fftDecay}:${startOffsetMs}:${currentTimeMs}`;
665
- const cachedData = this.#byteTimeDomainCache.get(smoothedKey);
666
- if (cachedData) return cachedData;
667
-
668
- // Process multiple frames with decay, similar to the reference code
669
- const framesData = await Promise.all(
670
- Array.from({ length: this.fftDecay }, async (_, frameIndex) => {
671
- const frameOffset = frameIndex * (1000 / 30);
672
- const startTime = Math.max(
673
- 0,
674
- (currentTimeMs - frameOffset - startOffsetMs) / 1000,
675
- );
676
-
677
- const cacheKey = `${this.fftSize}:${startOffsetMs}:${startTime}`;
678
- const cachedFrame = this.#byteTimeDomainCache.get(cacheKey);
679
- if (cachedFrame) return cachedFrame;
680
-
681
- const audioContext = new OfflineAudioContext(
682
- 2,
683
- 48000 * (1 / 30),
684
- 48000,
685
- );
686
-
687
- const source = audioContext.createBufferSource();
688
- source.buffer = audioBuffer;
689
-
690
- // Create analyzer for PCM data
691
- const analyser = audioContext.createAnalyser();
692
- analyser.fftSize = this.fftSize; // Ensure enough samples
693
- analyser.minDecibels = -90;
694
- analyser.maxDecibels = -20;
695
-
696
- const gainNode = audioContext.createGain();
697
- gainNode.gain.value = 2.0; // Amplify the signal
698
-
699
- source.connect(gainNode);
700
- gainNode.connect(analyser);
701
- analyser.connect(audioContext.destination);
702
-
703
- source.start(0, startTime, 1 / 30);
704
-
705
- const dataLength = analyser.fftSize / 2;
706
- try {
707
- await audioContext.startRendering();
708
- const frameData = new Uint8Array(dataLength);
709
- analyser.getByteTimeDomainData(frameData);
710
-
711
- // const points = frameData;
712
- // Calculate RMS and midpoint values
713
- const points = new Uint8Array(dataLength);
714
- for (let i = 0; i < dataLength; i++) {
715
- const pointSamples = frameData.slice(
716
- i * (frameData.length / dataLength),
717
- (i + 1) * (frameData.length / dataLength),
718
- );
719
-
720
- // Calculate RMS while preserving sign
721
- const rms = Math.sqrt(
722
- pointSamples.reduce((sum, sample) => {
723
- const normalized = (sample - 128) / 128;
724
- return sum + normalized * normalized;
725
- }, 0) / pointSamples.length,
726
- );
727
-
728
- // Get average sign of the samples to determine direction
729
- const avgSign = Math.sign(
730
- pointSamples.reduce((sum, sample) => sum + (sample - 128), 0),
731
- );
732
-
733
- // Convert RMS back to byte range, preserving direction
734
- points[i] = Math.min(255, Math.round(128 + avgSign * rms * 128));
735
- }
736
-
737
- this.#byteTimeDomainCache.set(cacheKey, points);
738
- return points;
739
- } finally {
740
- source.disconnect();
741
- analyser.disconnect();
742
- }
743
- }),
744
- );
745
-
746
- // Combine frames with decay weighting
747
- const frameLength = framesData[0]?.length ?? 0;
748
- const smoothedData = new Uint8Array(frameLength);
749
-
750
- for (let i = 0; i < frameLength; i++) {
751
- let weightedSum = 0;
752
- let weightSum = 0;
753
-
754
- framesData.forEach((frame, frameIndex) => {
755
- const decayWeight = EFMedia.DECAY_WEIGHT ** frameIndex;
756
- weightedSum += (frame[i] ?? 0) * decayWeight;
757
- weightSum += decayWeight;
758
- });
759
-
760
- smoothedData[i] = Math.min(255, Math.round(weightedSum / weightSum));
761
- }
762
-
763
- this.#byteTimeDomainCache.set(smoothedKey, smoothedData);
764
- return smoothedData;
765
- },
766
- });
767
-
768
619
  #frequencyDataCache = new LRUCache<string, Uint8Array>(100);
769
620
 
770
621
  frequencyDataTask = new Task(this, {
@@ -815,23 +666,13 @@ export class EFMedia extends EFTargetable(
815
666
  );
816
667
  const analyser = audioContext.createAnalyser();
817
668
  analyser.fftSize = this.fftSize;
818
- analyser.minDecibels = -90;
819
- analyser.maxDecibels = -10;
820
-
821
- const gainNode = audioContext.createGain();
822
- gainNode.gain.value = 3.0;
823
-
824
- const filter = audioContext.createBiquadFilter();
825
- filter.type = "bandpass";
826
- filter.frequency.value = 15000;
827
- filter.Q.value = 0.05;
669
+ analyser.minDecibels = EFMedia.MIN_DB;
670
+ analyser.maxDecibels = EFMedia.MAX_DB;
828
671
 
829
672
  const audioBufferSource = audioContext.createBufferSource();
830
673
  audioBufferSource.buffer = audioBuffer;
831
674
 
832
- audioBufferSource.connect(filter);
833
- filter.connect(gainNode);
834
- gainNode.connect(analyser);
675
+ audioBufferSource.connect(analyser);
835
676
  analyser.connect(audioContext.destination);
836
677
 
837
678
  audioBufferSource.start(0, startTime, 1 / 30);
@@ -861,7 +702,7 @@ export class EFMedia extends EFTargetable(
861
702
 
862
703
  framesData.forEach((frame, frameIndex) => {
863
704
  const decayWeight = EFMedia.DECAY_WEIGHT ** frameIndex;
864
- // biome-ignore lint/style/noNonNullAssertion: Manual bounds check
705
+ // biome-ignore lint/style/noNonNullAssertion: Will exist due to forEach
865
706
  weightedSum += frame[i]! * decayWeight;
866
707
  weightSum += decayWeight;
867
708
  });
@@ -871,7 +712,7 @@ export class EFMedia extends EFTargetable(
871
712
 
872
713
  // Apply frequency weights using instance FREQ_WEIGHTS
873
714
  smoothedData.forEach((value, i) => {
874
- // biome-ignore lint/style/noNonNullAssertion: Manual bounds check
715
+ // biome-ignore lint/style/noNonNullAssertion: Will exist due to forEach
875
716
  const freqWeight = this.FREQ_WEIGHTS[i]!;
876
717
  smoothedData[i] = Math.min(255, Math.round(value * freqWeight));
877
718
  });
@@ -882,70 +723,8 @@ export class EFMedia extends EFTargetable(
882
723
  0,
883
724
  Math.floor(smoothedData.length / 2),
884
725
  );
885
- const processedData = this.shouldInterpolateFrequencies
886
- ? processFFTData(slicedData)
887
- : slicedData;
888
- this.#frequencyDataCache.set(smoothedKey, processedData);
889
- return processedData;
726
+ this.#frequencyDataCache.set(smoothedKey, slicedData);
727
+ return slicedData;
890
728
  },
891
729
  });
892
730
  }
893
-
894
- function processFFTData(fftData: Uint8Array, zeroThresholdPercent = 0.1) {
895
- // Step 1: Determine the threshold for zeros
896
- const totalBins = fftData.length;
897
- const zeroThresholdCount = Math.floor(totalBins * zeroThresholdPercent);
898
-
899
- // Step 2: Interrogate the FFT output to find the cutoff point
900
- let zeroCount = 0;
901
- let cutoffIndex = totalBins; // Default to the end of the array
902
-
903
- for (let i = totalBins - 1; i >= 0; i--) {
904
- // biome-ignore lint/style/noNonNullAssertion: Manual bounds check
905
- if (fftData[i]! < 10) {
906
- zeroCount++;
907
- } else {
908
- // If we encounter a non-zero value, we can stop
909
- if (zeroCount >= zeroThresholdCount) {
910
- cutoffIndex = i + 1; // Include this index
911
- break;
912
- }
913
- }
914
- }
915
-
916
- if (cutoffIndex < zeroThresholdCount) {
917
- return fftData;
918
- }
919
-
920
- // Step 3: Resample the "good" portion of the data
921
- const goodData = fftData.slice(0, cutoffIndex);
922
- const resampledData = interpolateData(goodData, fftData.length);
923
-
924
- return resampledData;
925
- }
926
-
927
- function interpolateData(data: Uint8Array, targetSize: number) {
928
- const resampled = new Uint8Array(targetSize);
929
- const dataLength = data.length;
930
-
931
- for (let i = 0; i < targetSize; i++) {
932
- // Calculate the corresponding index in the original data
933
- const ratio = (i / (targetSize - 1)) * (dataLength - 1);
934
- const index = Math.floor(ratio);
935
- const fraction = ratio - index;
936
-
937
- // Handle edge cases
938
- if (index >= dataLength - 1) {
939
- // biome-ignore lint/style/noNonNullAssertion: Manual bounds check
940
- resampled[i] = data[dataLength - 1]!; // Last value
941
- } else {
942
- // Linear interpolation
943
- resampled[i] = Math.round(
944
- // biome-ignore lint/style/noNonNullAssertion: Manual bounds check
945
- data[index]! * (1 - fraction) + data[index + 1]! * fraction,
946
- );
947
- }
948
- }
949
-
950
- return resampled;
951
- }
@@ -45,15 +45,8 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
45
45
  type: String,
46
46
  attribute: "mode",
47
47
  })
48
- mode:
49
- | "roundBars"
50
- | "bars"
51
- | "bricks"
52
- | "line"
53
- | "curve"
54
- | "pixel"
55
- | "wave"
56
- | "spikes" = "bars";
48
+ mode: "roundBars" | "bars" | "bricks" | "line" | "pixel" | "wave" | "spikes" =
49
+ "bars";
57
50
 
58
51
  @property({ type: String })
59
52
  color = "currentColor";
@@ -164,7 +157,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
164
157
  const path = new Path2D();
165
158
 
166
159
  frequencyData.forEach((value, i) => {
167
- const normalizedValue = value / 255;
160
+ const normalizedValue = Math.min((value / 255) * 2, 1);
168
161
  const barHeight = normalizedValue * waveHeight;
169
162
  const y = (waveHeight - barHeight) / 2;
170
163
  const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));
@@ -190,7 +183,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
190
183
  const maxBricks = Math.floor(waveHeight / (boxSize + verticalGap)); // Account for gaps in height calculation
191
184
 
192
185
  frequencyData.forEach((value, i) => {
193
- const normalizedValue = value / 255;
186
+ const normalizedValue = Math.min((value / 255) * 2, 1);
194
187
  const brickCount = Math.floor(normalizedValue * maxBricks);
195
188
 
196
189
  for (let j = 0; j < brickCount; j++) {
@@ -225,7 +218,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
225
218
  const path = new Path2D();
226
219
 
227
220
  frequencyData.forEach((value, i) => {
228
- const normalizedValue = value / 255;
221
+ const normalizedValue = Math.min((value / 255) * 2, 1);
229
222
  const height = normalizedValue * waveHeight; // Use full wave height like in drawBars
230
223
  const x = waveWidth * paddingOuter + i * (barWidth * (1 + paddingInner));
231
224
  const y = (waveHeight - height) / 2; // Center vertically
@@ -238,49 +231,52 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
238
231
  ctx.fill(path);
239
232
  }
240
233
 
241
- protected drawLine(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array) {
234
+ protected drawEqualizer(
235
+ ctx: CanvasRenderingContext2D,
236
+ frequencyData: Uint8Array,
237
+ ) {
242
238
  const canvas = ctx.canvas;
243
239
  const waveWidth = canvas.width;
244
240
  const waveHeight = canvas.height;
241
+ const baseline = waveHeight / 2;
242
+ const barWidth = (waveWidth / frequencyData.length) * 0.8;
245
243
 
246
244
  ctx.clearRect(0, 0, waveWidth, waveHeight);
247
- const path = new Path2D();
248
245
 
249
- // Sample fewer points to make sharp angles more visible
250
- const sampleRate = 1; // Only use every 4th point
246
+ // Create paths for baseline and bars
247
+ const baselinePath = new Path2D();
248
+ const barsPath = new Path2D();
251
249
 
252
- for (let i = 0; i < frequencyData.length; i += sampleRate) {
253
- const x = (i / frequencyData.length) * waveWidth;
254
- const y = (1 - (frequencyData[i] ?? 0) / 255) * waveHeight;
250
+ // Draw baseline
251
+ baselinePath.moveTo(0, baseline);
252
+ baselinePath.lineTo(waveWidth, baseline);
255
253
 
256
- if (i === 0) {
257
- path.moveTo(x, y);
258
- } else {
259
- path.lineTo(x, y);
260
- }
261
- }
262
- // Ensure we draw to the end
263
- const lastX = waveWidth;
264
- const lastY =
265
- (1 - (frequencyData[frequencyData.length - 1] ?? 0) / 255) * waveHeight;
266
- path.lineTo(lastX, lastY);
254
+ // Draw bars
255
+ frequencyData.forEach((value, i) => {
256
+ const height = (value / 255) * (waveHeight / 2);
257
+ const x = i * (waveWidth / frequencyData.length);
258
+ const y = baseline - height;
259
+ barsPath.rect(x, y, barWidth, Math.max(height * 2, 1));
260
+ });
267
261
 
268
- ctx.lineWidth = this.lineWidth;
269
- ctx.stroke(path);
262
+ // Render baseline
263
+ ctx.lineWidth = 2;
264
+ ctx.stroke(baselinePath);
265
+
266
+ // Render bars
267
+ ctx.fill(barsPath);
270
268
  }
271
269
 
272
- protected drawCurve(
273
- ctx: CanvasRenderingContext2D,
274
- frequencyData: Uint8Array,
275
- ) {
270
+ protected drawLine(ctx: CanvasRenderingContext2D, frequencyData: Uint8Array) {
276
271
  const canvas = ctx.canvas;
277
272
  const waveWidth = canvas.width;
278
273
  const waveHeight = canvas.height;
279
274
 
280
275
  ctx.clearRect(0, 0, waveWidth, waveHeight);
276
+
277
+ // Create a single Path2D object for the curve
281
278
  const path = new Path2D();
282
279
 
283
- // Draw smooth curves between points using quadratic curves
284
280
  frequencyData.forEach((value, i) => {
285
281
  const x = (i / frequencyData.length) * waveWidth;
286
282
  const y = (1 - value / 255) * waveHeight;
@@ -288,11 +284,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
288
284
  if (i === 0) {
289
285
  path.moveTo(x, y);
290
286
  } else {
291
- const prevX = ((i - 1) / frequencyData.length) * waveWidth;
292
- const prevY = (1 - (frequencyData[i - 1] ?? 0) / 255) * waveHeight;
293
- const xc = (prevX + x) / 2;
294
- const yc = (prevY + y) / 2;
295
- path.quadraticCurveTo(prevX, prevY, xc, yc);
287
+ path.lineTo(x, y);
296
288
  }
297
289
  });
298
290
 
@@ -314,7 +306,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
314
306
  const path = new Path2D();
315
307
 
316
308
  frequencyData.forEach((value, i) => {
317
- const normalizedValue = value / 255;
309
+ const normalizedValue = Math.min((value / 255) * 2, 1); // Updated normalization
318
310
  const x = i * (waveWidth / frequencyData.length);
319
311
  const barHeight = normalizedValue * (waveHeight / 2); // Half height since we extend both ways
320
312
  const y = baseline - barHeight;
@@ -477,8 +469,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
477
469
  if (!ctx) return;
478
470
 
479
471
  const frequencyData = this.targetElement.frequencyDataTask.value;
480
- const byteTimeData = this.targetElement.byteTimeDomainTask.value;
481
- if (!frequencyData || !byteTimeData) return;
472
+ if (!frequencyData) return;
482
473
 
483
474
  ctx.save();
484
475
  if (this.color === "currentColor") {
@@ -499,10 +490,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
499
490
  this.drawBricks(ctx, frequencyData);
500
491
  break;
501
492
  case "line":
502
- this.drawLine(ctx, byteTimeData);
503
- break;
504
- case "curve":
505
- this.drawCurve(ctx, byteTimeData);
493
+ this.drawLine(ctx, frequencyData);
506
494
  break;
507
495
  case "pixel":
508
496
  this.drawPixel(ctx, frequencyData);
@@ -1,4 +1,4 @@
1
- import type { CSSResult, LitElement } from "lit";
1
+ import type { LitElement } from "lit";
2
2
  // @ts-expect-error cannot figure out how to declare this module as a string
3
3
  import twStyle from "./TWMixin.css?inline";
4
4
 
@@ -21,30 +21,13 @@ export function TWMixin<T extends new (...args: any[]) => LitElement>(Base: T) {
21
21
  "twSheet not found. Probable cause: CSSStyleSheet not supported in this environment",
22
22
  );
23
23
  }
24
-
25
- const constructorStylesheets: CSSStyleSheet[] = [];
26
- const constructorStyles = (("styles" in this.constructor &&
27
- this.constructor.styles) ||
28
- []) as CSSResult | CSSResult[];
29
-
30
- if (Array.isArray(constructorStyles)) {
31
- for (const item of constructorStyles) {
32
- if (item.styleSheet) {
33
- constructorStylesheets.push(item.styleSheet);
34
- }
35
- }
36
- } else if (constructorStyles.styleSheet) {
37
- constructorStylesheets.push(constructorStyles.styleSheet);
38
- }
39
-
40
24
  if (renderRoot?.adoptedStyleSheets) {
41
25
  renderRoot.adoptedStyleSheets = [
42
26
  twSheet,
43
27
  ...renderRoot.adoptedStyleSheets,
44
- ...constructorStylesheets,
45
28
  ];
46
29
  } else {
47
- renderRoot.adoptedStyleSheets = [twSheet, ...constructorStylesheets];
30
+ renderRoot.adoptedStyleSheets = [twSheet];
48
31
  }
49
32
  return renderRoot;
50
33
  }
@@ -1,51 +0,0 @@
1
- import { z } from 'zod';
2
- export declare const RenderInfo: z.ZodObject<{
3
- width: z.ZodNumber;
4
- height: z.ZodNumber;
5
- fps: z.ZodNumber;
6
- durationMs: z.ZodNumber;
7
- assets: z.ZodObject<{
8
- efMedia: z.ZodRecord<z.ZodString, z.ZodAny>;
9
- efCaptions: z.ZodArray<z.ZodString, "many">;
10
- efImage: z.ZodArray<z.ZodString, "many">;
11
- }, "strip", z.ZodTypeAny, {
12
- efMedia: Record<string, any>;
13
- efCaptions: string[];
14
- efImage: string[];
15
- }, {
16
- efMedia: Record<string, any>;
17
- efCaptions: string[];
18
- efImage: string[];
19
- }>;
20
- }, "strip", z.ZodTypeAny, {
21
- width: number;
22
- height: number;
23
- fps: number;
24
- durationMs: number;
25
- assets: {
26
- efMedia: Record<string, any>;
27
- efCaptions: string[];
28
- efImage: string[];
29
- };
30
- }, {
31
- width: number;
32
- height: number;
33
- fps: number;
34
- durationMs: number;
35
- assets: {
36
- efMedia: Record<string, any>;
37
- efCaptions: string[];
38
- efImage: string[];
39
- };
40
- }>;
41
- export declare const getRenderInfo: () => Promise<{
42
- width: number;
43
- height: number;
44
- fps: number;
45
- durationMs: number;
46
- assets: {
47
- efMedia: Record<string, any>;
48
- efCaptions: string[];
49
- efImage: string[];
50
- };
51
- }>;
@@ -1,72 +0,0 @@
1
- import { z } from "zod";
2
- const RenderInfo = z.object({
3
- width: z.number().positive(),
4
- height: z.number().positive(),
5
- fps: z.number().positive(),
6
- durationMs: z.number().positive(),
7
- assets: z.object({
8
- efMedia: z.record(z.any()),
9
- efCaptions: z.array(z.string()),
10
- efImage: z.array(z.string())
11
- })
12
- });
13
- const getRenderInfo = async () => {
14
- const rootTimeGroup = document.querySelector("ef-timegroup");
15
- if (!rootTimeGroup) {
16
- throw new Error("No ef-timegroup found");
17
- }
18
- console.error("Waiting for media durations", rootTimeGroup);
19
- await rootTimeGroup.waitForMediaDurations();
20
- const width = rootTimeGroup.clientWidth;
21
- const height = rootTimeGroup.clientHeight;
22
- const fps = 30;
23
- const durationMs = Math.round(rootTimeGroup.durationMs);
24
- const elements = document.querySelectorAll(
25
- "ef-audio, ef-video, ef-image, ef-captions"
26
- );
27
- const assets = {
28
- efMedia: {},
29
- efCaptions: /* @__PURE__ */ new Set(),
30
- efImage: /* @__PURE__ */ new Set()
31
- };
32
- for (const element of elements) {
33
- switch (element.tagName) {
34
- case "EF-AUDIO":
35
- case "EF-VIDEO": {
36
- const src = element.src;
37
- console.error("Processing element", element.tagName, src);
38
- assets.efMedia[src] = element.trackFragmentIndexLoader.value;
39
- break;
40
- }
41
- case "EF-IMAGE": {
42
- const src = element.src;
43
- console.error("Processing element", element.tagName, src);
44
- assets.efImage.add(src);
45
- break;
46
- }
47
- case "EF-CAPTIONS": {
48
- const src = element.targetElement?.src;
49
- console.error("Processing element", element.tagName, src);
50
- assets.efCaptions.add(src);
51
- break;
52
- }
53
- }
54
- }
55
- const renderInfo = {
56
- width,
57
- height,
58
- fps,
59
- durationMs,
60
- assets: {
61
- efMedia: assets.efMedia,
62
- efCaptions: Array.from(assets.efCaptions),
63
- efImage: Array.from(assets.efImage)
64
- }
65
- };
66
- console.error("Render info", renderInfo);
67
- return renderInfo;
68
- };
69
- export {
70
- RenderInfo,
71
- getRenderInfo
72
- };