@editframe/elements 0.20.3-beta.0 → 0.21.0-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 (128) hide show
  1. package/dist/DelayedLoadingState.js +0 -27
  2. package/dist/EF_FRAMEGEN.d.ts +5 -3
  3. package/dist/EF_FRAMEGEN.js +51 -29
  4. package/dist/_virtual/_@oxc-project_runtime@0.93.0/helpers/decorate.js +7 -0
  5. package/dist/elements/ContextProxiesController.js +2 -22
  6. package/dist/elements/EFAudio.js +4 -8
  7. package/dist/elements/EFCaptions.js +59 -84
  8. package/dist/elements/EFImage.js +5 -6
  9. package/dist/elements/EFMedia/AssetIdMediaEngine.js +2 -4
  10. package/dist/elements/EFMedia/AssetMediaEngine.d.ts +4 -4
  11. package/dist/elements/EFMedia/AssetMediaEngine.js +41 -32
  12. package/dist/elements/EFMedia/BaseMediaEngine.d.ts +10 -2
  13. package/dist/elements/EFMedia/BaseMediaEngine.js +57 -67
  14. package/dist/elements/EFMedia/BufferedSeekingInput.js +134 -76
  15. package/dist/elements/EFMedia/JitMediaEngine.js +22 -23
  16. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +4 -7
  17. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +1 -3
  18. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +2 -2
  19. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +9 -7
  20. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +1 -3
  21. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +2 -12
  22. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +2 -2
  23. package/dist/elements/EFMedia/audioTasks/makeAudioTasksVideoOnly.browsertest.d.ts +1 -0
  24. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +6 -3
  25. package/dist/elements/EFMedia/shared/AudioSpanUtils.d.ts +1 -1
  26. package/dist/elements/EFMedia/shared/AudioSpanUtils.js +5 -17
  27. package/dist/elements/EFMedia/shared/BufferUtils.d.ts +1 -1
  28. package/dist/elements/EFMedia/shared/BufferUtils.js +2 -13
  29. package/dist/elements/EFMedia/shared/GlobalInputCache.js +0 -24
  30. package/dist/elements/EFMedia/shared/MediaTaskUtils.d.ts +1 -1
  31. package/dist/elements/EFMedia/shared/PrecisionUtils.js +0 -21
  32. package/dist/elements/EFMedia/shared/RenditionHelpers.d.ts +1 -9
  33. package/dist/elements/EFMedia/shared/ThumbnailExtractor.js +0 -17
  34. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.d.ts +1 -2
  35. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +2 -16
  36. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.d.ts +29 -0
  37. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js +32 -0
  38. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +1 -15
  39. package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js +3 -8
  40. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js +0 -2
  41. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js +8 -7
  42. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js +12 -13
  43. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.js +0 -2
  44. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js +1 -3
  45. package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js +134 -71
  46. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +8 -12
  47. package/dist/elements/EFMedia.d.ts +2 -1
  48. package/dist/elements/EFMedia.js +26 -23
  49. package/dist/elements/EFSourceMixin.js +5 -7
  50. package/dist/elements/EFSurface.js +6 -9
  51. package/dist/elements/EFTemporal.js +19 -37
  52. package/dist/elements/EFThumbnailStrip.js +16 -59
  53. package/dist/elements/EFTimegroup.js +96 -91
  54. package/dist/elements/EFVideo.d.ts +6 -2
  55. package/dist/elements/EFVideo.js +142 -107
  56. package/dist/elements/EFWaveform.js +18 -27
  57. package/dist/elements/SampleBuffer.js +2 -5
  58. package/dist/elements/TargetController.js +3 -3
  59. package/dist/elements/durationConverter.js +4 -4
  60. package/dist/elements/updateAnimations.js +14 -35
  61. package/dist/gui/ContextMixin.js +23 -52
  62. package/dist/gui/EFConfiguration.js +7 -7
  63. package/dist/gui/EFControls.js +5 -5
  64. package/dist/gui/EFFilmstrip.js +77 -98
  65. package/dist/gui/EFFitScale.js +5 -6
  66. package/dist/gui/EFFocusOverlay.js +4 -4
  67. package/dist/gui/EFPreview.js +4 -4
  68. package/dist/gui/EFScrubber.js +9 -9
  69. package/dist/gui/EFTimeDisplay.js +5 -5
  70. package/dist/gui/EFToggleLoop.js +4 -4
  71. package/dist/gui/EFTogglePlay.js +5 -5
  72. package/dist/gui/EFWorkbench.js +5 -5
  73. package/dist/gui/TWMixin2.js +1 -1
  74. package/dist/index.d.ts +1 -0
  75. package/dist/otel/BridgeSpanExporter.d.ts +13 -0
  76. package/dist/otel/BridgeSpanExporter.js +87 -0
  77. package/dist/otel/setupBrowserTracing.d.ts +12 -0
  78. package/dist/otel/setupBrowserTracing.js +30 -0
  79. package/dist/otel/tracingHelpers.d.ts +34 -0
  80. package/dist/otel/tracingHelpers.js +113 -0
  81. package/dist/transcoding/cache/RequestDeduplicator.js +0 -21
  82. package/dist/transcoding/cache/URLTokenDeduplicator.js +1 -21
  83. package/dist/transcoding/types/index.d.ts +6 -4
  84. package/dist/transcoding/utils/UrlGenerator.js +2 -19
  85. package/dist/utils/LRUCache.js +6 -53
  86. package/package.json +10 -2
  87. package/src/elements/EFCaptions.browsertest.ts +2 -0
  88. package/src/elements/EFMedia/AssetIdMediaEngine.test.ts +6 -4
  89. package/src/elements/EFMedia/AssetMediaEngine.browsertest.ts +25 -23
  90. package/src/elements/EFMedia/AssetMediaEngine.ts +81 -43
  91. package/src/elements/EFMedia/BaseMediaEngine.browsertest.ts +94 -0
  92. package/src/elements/EFMedia/BaseMediaEngine.ts +120 -60
  93. package/src/elements/EFMedia/BufferedSeekingInput.ts +218 -101
  94. package/src/elements/EFMedia/JitMediaEngine.ts +20 -6
  95. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.ts +5 -2
  96. package/src/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.ts +0 -5
  97. package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.ts +2 -1
  98. package/src/elements/EFMedia/audioTasks/makeAudioInputTask.ts +18 -8
  99. package/src/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.ts +4 -16
  100. package/src/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.ts +4 -2
  101. package/src/elements/EFMedia/audioTasks/makeAudioTasksVideoOnly.browsertest.ts +95 -0
  102. package/src/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.ts +5 -6
  103. package/src/elements/EFMedia/shared/AudioSpanUtils.ts +5 -4
  104. package/src/elements/EFMedia/shared/BufferUtils.ts +7 -3
  105. package/src/elements/EFMedia/shared/MediaTaskUtils.ts +1 -1
  106. package/src/elements/EFMedia/shared/RenditionHelpers.browsertest.ts +41 -42
  107. package/src/elements/EFMedia/shared/RenditionHelpers.ts +0 -23
  108. package/src/elements/EFMedia/tasks/makeMediaEngineTask.ts +1 -9
  109. package/src/elements/EFMedia/videoTasks/MainVideoInputCache.ts +76 -0
  110. package/src/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.ts +3 -2
  111. package/src/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.ts +0 -5
  112. package/src/elements/EFMedia/videoTasks/makeScrubVideoInputTask.ts +17 -15
  113. package/src/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.ts +7 -1
  114. package/src/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.ts +0 -5
  115. package/src/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.ts +0 -5
  116. package/src/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.ts +222 -125
  117. package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.ts +2 -5
  118. package/src/elements/EFMedia.ts +18 -2
  119. package/src/elements/EFThumbnailStrip.media-engine.browsertest.ts +2 -1
  120. package/src/elements/EFTimegroup.browsertest.ts +10 -8
  121. package/src/elements/EFTimegroup.ts +165 -77
  122. package/src/elements/EFVideo.browsertest.ts +19 -27
  123. package/src/elements/EFVideo.ts +203 -101
  124. package/src/otel/BridgeSpanExporter.ts +150 -0
  125. package/src/otel/setupBrowserTracing.ts +68 -0
  126. package/src/otel/tracingHelpers.ts +251 -0
  127. package/src/transcoding/types/index.ts +6 -4
  128. package/types.json +1 -1
@@ -1,50 +1,26 @@
1
1
  import { LRUCache } from "../../../utils/LRUCache.js";
2
- /**
3
- * Global cache for MediaBunny Input instances
4
- * Shared across all MediaEngine instances to prevent duplicate decoding
5
- * of the same segment data
6
- */
7
2
  var GlobalInputCache = class {
8
3
  constructor() {
9
4
  this.cache = new LRUCache(50);
10
5
  }
11
- /**
12
- * Generate standardized cache key for Input objects
13
- * Format: "input:{src}:{segmentId}:{renditionId}"
14
- */
15
6
  generateKey(src, segmentId, renditionId) {
16
7
  return `input:${src}:${segmentId}:${renditionId || "default"}`;
17
8
  }
18
- /**
19
- * Get cached Input object
20
- */
21
9
  get(src, segmentId, renditionId) {
22
10
  const key = this.generateKey(src, segmentId, renditionId);
23
11
  return this.cache.get(key);
24
12
  }
25
- /**
26
- * Cache Input object
27
- */
28
13
  set(src, segmentId, input, renditionId) {
29
14
  const key = this.generateKey(src, segmentId, renditionId);
30
15
  this.cache.set(key, input);
31
16
  }
32
- /**
33
- * Check if Input is cached
34
- */
35
17
  has(src, segmentId, renditionId) {
36
18
  const key = this.generateKey(src, segmentId, renditionId);
37
19
  return this.cache.has(key);
38
20
  }
39
- /**
40
- * Clear all cached Input objects
41
- */
42
21
  clear() {
43
22
  this.cache.clear();
44
23
  }
45
- /**
46
- * Get cache statistics for debugging
47
- */
48
24
  getStats() {
49
25
  return {
50
26
  size: this.cache.size,
@@ -20,4 +20,4 @@ export type SegmentFetchTask = Task<readonly [MediaEngine | undefined, number |
20
20
  /**
21
21
  * Generic task type for input creation
22
22
  */
23
- export type InputTask = Task<readonly [ArrayBuffer, ArrayBuffer], BufferedSeekingInput>;
23
+ export type InputTask = Task<readonly [ArrayBuffer, ArrayBuffer], BufferedSeekingInput | undefined>;
@@ -1,27 +1,6 @@
1
- /**
2
- * Centralized precision utilities for consistent timing calculations across the media pipeline.
3
- *
4
- * The key insight is that floating-point precision errors can cause inconsistencies between:
5
- * 1. Segment selection logic (in AssetMediaEngine.computeSegmentId)
6
- * 2. Sample finding logic (in SampleBuffer.find)
7
- * 3. Timeline mapping (in BufferedSeekingInput.seek)
8
- *
9
- * All timing calculations must use the same rounding strategy to ensure consistency.
10
- */
11
- /**
12
- * Round time to millisecond precision to handle floating-point precision issues.
13
- * Uses Math.round for consistent behavior across the entire pipeline.
14
- *
15
- * This function should be used for ALL time-related calculations that need to be
16
- * compared between different parts of the system.
17
- */
18
1
  const roundToMilliseconds = (timeMs) => {
19
2
  return Math.round(timeMs * 1e3) / 1e3;
20
3
  };
21
- /**
22
- * Convert media time (in seconds) to scaled time units using consistent rounding.
23
- * This is used in segment selection to convert from milliseconds to timescale units.
24
- */
25
4
  const convertToScaledTime = (timeMs, timescale) => {
26
5
  const scaledTime = timeMs / 1e3 * timescale;
27
6
  return Math.round(scaledTime);
@@ -1,12 +1,4 @@
1
- import { AudioRendition, MediaEngine, VideoRendition } from '../../../transcoding/types';
2
- /**
3
- * Get audio rendition from media engine, throwing if not available
4
- */
5
- export declare const getAudioRendition: (mediaEngine: MediaEngine) => AudioRendition;
6
- /**
7
- * Get video rendition from media engine, throwing if not available
8
- */
9
- export declare const getVideoRendition: (mediaEngine: MediaEngine) => VideoRendition;
1
+ import { AudioRendition, VideoRendition } from '../../../transcoding/types';
10
2
  /**
11
3
  * Calculate which segment contains a given timestamp
12
4
  * Returns 1-based segment ID, or undefined if segmentDurationMs is not available
@@ -1,16 +1,9 @@
1
1
  import { globalInputCache } from "./GlobalInputCache.js";
2
2
  import { ALL_FORMATS, BlobSource, CanvasSink, Input } from "mediabunny";
3
- /**
4
- * Shared thumbnail extraction logic for all MediaEngine implementations
5
- * Eliminates code duplication and provides consistent behavior
6
- */
7
3
  var ThumbnailExtractor = class {
8
4
  constructor(mediaEngine) {
9
5
  this.mediaEngine = mediaEngine;
10
6
  }
11
- /**
12
- * Extract thumbnails at multiple timestamps efficiently using segment batching
13
- */
14
7
  async extractThumbnails(timestamps, rendition, durationMs) {
15
8
  if (timestamps.length === 0) return [];
16
9
  const validTimestamps = timestamps.filter((timeMs) => timeMs >= 0 && timeMs <= durationMs);
@@ -32,9 +25,6 @@ var ThumbnailExtractor = class {
32
25
  return results.get(t) || null;
33
26
  });
34
27
  }
35
- /**
36
- * Group timestamps by segment ID for efficient batch processing
37
- */
38
28
  groupTimestampsBySegment(timestamps, rendition) {
39
29
  const segmentGroups = /* @__PURE__ */ new Map();
40
30
  for (const timeMs of timestamps) try {
@@ -50,9 +40,6 @@ var ThumbnailExtractor = class {
50
40
  }
51
41
  return segmentGroups;
52
42
  }
53
- /**
54
- * Extract thumbnails for a specific segment using CanvasSink
55
- */
56
43
  async extractSegmentThumbnails(segmentId, timestamps, rendition) {
57
44
  const results = /* @__PURE__ */ new Map();
58
45
  try {
@@ -95,10 +82,6 @@ var ThumbnailExtractor = class {
95
82
  }
96
83
  return results;
97
84
  }
98
- /**
99
- * Convert global timestamps to segment-relative timestamps for mediabunny
100
- * This is where the main difference between JIT and Asset engines lies
101
- */
102
85
  convertToSegmentRelativeTimestamps(globalTimestamps, segmentId, rendition) {
103
86
  return this.mediaEngine.convertToSegmentRelativeTimestamps(globalTimestamps, segmentId, rendition);
104
87
  }
@@ -1,8 +1,7 @@
1
1
  import { Task } from '@lit/task';
2
- import { MediaEngine, VideoRendition } from '../../../transcoding/types';
2
+ import { MediaEngine } from '../../../transcoding/types';
3
3
  import { EFMedia } from '../../EFMedia';
4
4
  export declare const getLatestMediaEngine: (host: EFMedia, signal: AbortSignal) => Promise<MediaEngine>;
5
- export declare const getVideoRendition: (mediaEngine: MediaEngine) => VideoRendition;
6
5
  /**
7
6
  * Core logic for creating a MediaEngine with explicit dependencies.
8
7
  * Pure function that requires all dependencies to be provided.
@@ -9,15 +9,6 @@ const getLatestMediaEngine = async (host, signal) => {
9
9
  if (!mediaEngine) throw new Error("Media engine is not available");
10
10
  return mediaEngine;
11
11
  };
12
- const getVideoRendition = (mediaEngine) => {
13
- const videoRendition = mediaEngine.videoRendition;
14
- if (!videoRendition) throw new Error("No video track available in source");
15
- return videoRendition;
16
- };
17
- /**
18
- * Core logic for creating a MediaEngine with explicit dependencies.
19
- * Pure function that requires all dependencies to be provided.
20
- */
21
12
  const createMediaEngine = (host) => {
22
13
  const { src, assetId, urlGenerator, apiHost } = host;
23
14
  if (assetId !== null && assetId !== void 0 && assetId.trim() !== "") {
@@ -30,15 +21,10 @@ const createMediaEngine = (host) => {
30
21
  }
31
22
  const lowerSrc = src.toLowerCase();
32
23
  if (!lowerSrc.startsWith("http://") && !lowerSrc.startsWith("https://")) return AssetMediaEngine.fetch(host, urlGenerator, src);
33
- const configuration = host.closest("ef-configuration");
34
- if (configuration?.mediaEngine === "local") return AssetMediaEngine.fetch(host, urlGenerator, src);
24
+ if (host.closest("ef-configuration")?.mediaEngine === "local") return AssetMediaEngine.fetch(host, urlGenerator, src);
35
25
  const url = urlGenerator.generateManifestUrl(src);
36
26
  return JitMediaEngine.fetch(host, urlGenerator, url);
37
27
  };
38
- /**
39
- * Handle completion of media engine task - triggers necessary updates.
40
- * Extracted for testability.
41
- */
42
28
  const handleMediaEngineComplete = (host) => {
43
29
  host.requestUpdate("intrinsicDurationMs");
44
30
  host.requestUpdate("ownCurrentTimeMs");
@@ -57,4 +43,4 @@ const makeMediaEngineTask = (host) => {
57
43
  }
58
44
  });
59
45
  };
60
- export { getLatestMediaEngine, getVideoRendition, makeMediaEngineTask };
46
+ export { getLatestMediaEngine, makeMediaEngineTask };
@@ -0,0 +1,29 @@
1
+ import { BufferedSeekingInput } from '../BufferedSeekingInput';
2
+ /**
3
+ * Cache for main video BufferedSeekingInput instances
4
+ * Main video segments are typically 2s long, so we can reuse the same input
5
+ * for multiple frames within that segment (e.g., 60 frames at 30fps)
6
+ */
7
+ export declare class MainVideoInputCache {
8
+ private cache;
9
+ private maxCacheSize;
10
+ /**
11
+ * Create a cache key that uniquely identifies a segment
12
+ */
13
+ private getCacheKey;
14
+ /**
15
+ * Get or create BufferedSeekingInput for a main video segment
16
+ */
17
+ getOrCreateInput(src: string, segmentId: number, renditionId: string | undefined, createInputFn: () => Promise<BufferedSeekingInput | undefined>): Promise<BufferedSeekingInput | undefined>;
18
+ /**
19
+ * Clear the entire cache (called when video changes)
20
+ */
21
+ clear(): void;
22
+ /**
23
+ * Get cache statistics
24
+ */
25
+ getStats(): {
26
+ size: number;
27
+ cacheKeys: string[];
28
+ };
29
+ }
@@ -0,0 +1,32 @@
1
+ var MainVideoInputCache = class {
2
+ constructor() {
3
+ this.cache = /* @__PURE__ */ new Map();
4
+ this.maxCacheSize = 10;
5
+ }
6
+ getCacheKey(src, segmentId, renditionId) {
7
+ return `${src}:${renditionId || "default"}:${segmentId}`;
8
+ }
9
+ async getOrCreateInput(src, segmentId, renditionId, createInputFn) {
10
+ const cacheKey = this.getCacheKey(src, segmentId, renditionId);
11
+ const cached = this.cache.get(cacheKey);
12
+ if (cached) return cached;
13
+ const input = await createInputFn();
14
+ if (!input) return;
15
+ this.cache.set(cacheKey, input);
16
+ if (this.cache.size > this.maxCacheSize) {
17
+ const oldestKey = this.cache.keys().next().value;
18
+ if (oldestKey !== void 0) this.cache.delete(oldestKey);
19
+ }
20
+ return input;
21
+ }
22
+ clear() {
23
+ this.cache.clear();
24
+ }
25
+ getStats() {
26
+ return {
27
+ size: this.cache.size,
28
+ cacheKeys: Array.from(this.cache.keys())
29
+ };
30
+ }
31
+ };
32
+ export { MainVideoInputCache };
@@ -1,21 +1,13 @@
1
- /**
2
- * Cache for scrub BufferedSeekingInput instances
3
- * Since scrub segments are 30s long, we can reuse the same input for many seeks
4
- * within that time range, making scrub seeking very efficient
5
- */
6
1
  var ScrubInputCache = class {
7
2
  constructor() {
8
3
  this.cache = /* @__PURE__ */ new Map();
9
4
  this.maxCacheSize = 5;
10
5
  }
11
- /**
12
- * Get or create BufferedSeekingInput for a scrub segment
13
- */
14
6
  async getOrCreateInput(segmentId, createInputFn) {
15
7
  const cached = this.cache.get(segmentId);
16
8
  if (cached) return cached;
17
9
  const input = await createInputFn();
18
- if (!input) return void 0;
10
+ if (!input) return;
19
11
  this.cache.set(segmentId, input);
20
12
  if (this.cache.size > this.maxCacheSize) {
21
13
  const oldestKey = this.cache.keys().next().value;
@@ -23,15 +15,9 @@ var ScrubInputCache = class {
23
15
  }
24
16
  return input;
25
17
  }
26
- /**
27
- * Clear the entire cache (called when video changes)
28
- */
29
18
  clear() {
30
19
  this.cache.clear();
31
20
  }
32
- /**
33
- * Get cache statistics
34
- */
35
21
  getStats() {
36
22
  return {
37
23
  size: this.cache.size,
@@ -1,11 +1,7 @@
1
+ import { EF_INTERACTIVE } from "../../../EF_INTERACTIVE.js";
1
2
  import { EF_RENDERING } from "../../../EF_RENDERING.js";
2
3
  import { manageMediaBuffer } from "../shared/BufferUtils.js";
3
4
  import { Task } from "@lit/task";
4
- /**
5
- * Scrub video buffer task - aggressively preloads the ENTIRE scrub track
6
- * Unlike main video buffering, this loads the full duration with higher concurrency
7
- * for instant visual feedback during seeking
8
- */
9
5
  const makeScrubVideoBufferTask = (host) => {
10
6
  let currentState = {
11
7
  currentSeekTimeMs: 0,
@@ -14,7 +10,7 @@ const makeScrubVideoBufferTask = (host) => {
14
10
  requestQueue: []
15
11
  };
16
12
  return new Task(host, {
17
- autoRun: false,
13
+ autoRun: EF_INTERACTIVE,
18
14
  args: () => [host.mediaEngineTask.value],
19
15
  onError: (error) => {
20
16
  console.error("scrubVideoBufferTask error", error);
@@ -38,7 +34,7 @@ const makeScrubVideoBufferTask = (host) => {
38
34
  } catch (error) {
39
35
  console.warn("ScrubBuffer: Failed to cache scrub init segment:", error);
40
36
  }
41
- const newState = await manageMediaBuffer(0, {
37
+ return await manageMediaBuffer(0, {
42
38
  bufferDurationMs: mediaEngine.durationMs,
43
39
  maxParallelFetches: 10,
44
40
  enableBuffering: true,
@@ -58,7 +54,6 @@ const makeScrubVideoBufferTask = (host) => {
58
54
  console.warn(`ScrubBuffer: ${message}`, error);
59
55
  }
60
56
  });
61
- return newState;
62
57
  } catch (error) {
63
58
  if (signal.aborted) return currentState;
64
59
  console.warn("ScrubBuffer failed:", error);
@@ -1,4 +1,3 @@
1
- import { EF_RENDERING } from "../../../EF_RENDERING.js";
2
1
  import { getLatestMediaEngine } from "../tasks/makeMediaEngineTask.js";
3
2
  import { Task } from "@lit/task";
4
3
  const makeScrubVideoInitSegmentFetchTask = (host) => {
@@ -9,7 +8,6 @@ const makeScrubVideoInitSegmentFetchTask = (host) => {
9
8
  },
10
9
  onComplete: (_value) => {},
11
10
  task: async ([_mediaEngine], { signal }) => {
12
- if (EF_RENDERING()) return /* @__PURE__ */ new ArrayBuffer(0);
13
11
  const mediaEngine = await getLatestMediaEngine(host, signal);
14
12
  const scrubRendition = mediaEngine.getScrubVideoRendition();
15
13
  if (!scrubRendition) throw new Error("No scrub rendition available");
@@ -1,4 +1,3 @@
1
- import { EF_RENDERING } from "../../../EF_RENDERING.js";
2
1
  import { BufferedSeekingInput } from "../BufferedSeekingInput.js";
3
2
  import { EFMedia } from "../../EFMedia.js";
4
3
  import { Task } from "@lit/task";
@@ -9,20 +8,22 @@ const makeScrubVideoInputTask = (host) => {
9
8
  console.error("scrubVideoInputTask error", error);
10
9
  },
11
10
  onComplete: (_value) => {},
12
- task: async () => {
13
- if (EF_RENDERING()) console.info("Scrub not available in rendering mode");
11
+ task: async (_, { signal }) => {
14
12
  const initSegment = await host.scrubVideoInitSegmentFetchTask.taskComplete;
13
+ if (signal.aborted) return void 0;
15
14
  const segment = await host.scrubVideoSegmentFetchTask.taskComplete;
15
+ if (signal.aborted) return void 0;
16
16
  if (!initSegment || !segment) throw new Error("Scrub init segment or segment is not available");
17
17
  const mediaEngine = await host.mediaEngineTask.taskComplete;
18
- const scrubRendition = mediaEngine.getScrubVideoRendition();
19
- const startTimeOffsetMs = scrubRendition?.startTimeOffsetMs;
20
- const input = new BufferedSeekingInput(await new Blob([initSegment, segment]).arrayBuffer(), {
18
+ if (signal.aborted) return void 0;
19
+ const startTimeOffsetMs = mediaEngine.getScrubVideoRendition()?.startTimeOffsetMs;
20
+ const arrayBuffer = await new Blob([initSegment, segment]).arrayBuffer();
21
+ if (signal.aborted) return void 0;
22
+ return new BufferedSeekingInput(arrayBuffer, {
21
23
  videoBufferSize: EFMedia.VIDEO_SAMPLE_BUFFER_SIZE,
22
24
  audioBufferSize: EFMedia.AUDIO_SAMPLE_BUFFER_SIZE,
23
25
  startTimeOffsetMs
24
26
  });
25
- return input;
26
27
  }
27
28
  });
28
29
  };
@@ -1,6 +1,6 @@
1
1
  import { ScrubInputCache } from "./ScrubInputCache.js";
2
2
  import { Task } from "@lit/task";
3
- const scrubInputCache = new ScrubInputCache();
3
+ var scrubInputCache = new ScrubInputCache();
4
4
  const makeScrubVideoSeekTask = (host) => {
5
5
  return new Task(host, {
6
6
  args: () => [host.desiredSeekTimeMs],
@@ -11,22 +11,21 @@ const makeScrubVideoSeekTask = (host) => {
11
11
  task: async ([desiredSeekTimeMs], { signal }) => {
12
12
  signal.throwIfAborted();
13
13
  const mediaEngine = host.mediaEngineTask.value;
14
- if (!mediaEngine) return void 0;
14
+ if (!mediaEngine) return;
15
15
  const scrubRendition = mediaEngine.getScrubVideoRendition();
16
- if (!scrubRendition) return void 0;
16
+ if (!scrubRendition) return;
17
17
  const scrubRenditionWithSrc = {
18
18
  ...scrubRendition,
19
19
  src: mediaEngine.src
20
20
  };
21
21
  const segmentId = mediaEngine.computeSegmentId(desiredSeekTimeMs, scrubRenditionWithSrc);
22
- if (segmentId === void 0) return void 0;
23
- const isCached = mediaEngine.isSegmentCached(segmentId, scrubRenditionWithSrc);
24
- if (!isCached) return void 0;
22
+ if (segmentId === void 0) return;
23
+ if (!mediaEngine.isSegmentCached(segmentId, scrubRenditionWithSrc)) return;
25
24
  signal.throwIfAborted();
26
25
  try {
27
26
  const scrubInput = await scrubInputCache.getOrCreateInput(segmentId, async () => {
28
27
  const [initSegment, mediaSegment] = await Promise.all([mediaEngine.fetchInitSegment(scrubRenditionWithSrc, signal), mediaEngine.fetchMediaSegment(segmentId, scrubRenditionWithSrc)]);
29
- if (!initSegment || !mediaSegment || signal.aborted) return void 0;
28
+ if (!initSegment || !mediaSegment || signal.aborted) return;
30
29
  const { BufferedSeekingInput } = await import("../BufferedSeekingInput.js");
31
30
  const { EFMedia } = await import("../../EFMedia.js");
32
31
  return new BufferedSeekingInput(await new Blob([initSegment, mediaSegment]).arrayBuffer(), {
@@ -35,16 +34,16 @@ const makeScrubVideoSeekTask = (host) => {
35
34
  startTimeOffsetMs: scrubRendition.startTimeOffsetMs
36
35
  });
37
36
  });
38
- if (!scrubInput) return void 0;
37
+ if (!scrubInput) return;
38
+ if (signal.aborted) return;
39
39
  const videoTrack = await scrubInput.getFirstVideoTrack();
40
- if (!videoTrack) return void 0;
41
- signal.throwIfAborted();
42
- const sample = await scrubInput.seek(videoTrack.id, desiredSeekTimeMs);
43
- return sample;
40
+ if (!videoTrack) return;
41
+ if (signal.aborted) return;
42
+ return await scrubInput.seek(videoTrack.id, desiredSeekTimeMs);
44
43
  } catch (error) {
45
44
  if (signal.aborted) return void 0;
46
45
  console.warn("Failed to get scrub video sample:", error);
47
- return void 0;
46
+ return;
48
47
  }
49
48
  }
50
49
  });
@@ -1,4 +1,3 @@
1
- import { EF_RENDERING } from "../../../EF_RENDERING.js";
2
1
  import { getLatestMediaEngine } from "../tasks/makeMediaEngineTask.js";
3
2
  import { Task } from "@lit/task";
4
3
  const makeScrubVideoSegmentFetchTask = (host) => {
@@ -9,7 +8,6 @@ const makeScrubVideoSegmentFetchTask = (host) => {
9
8
  },
10
9
  onComplete: (_value) => {},
11
10
  task: async (_, { signal }) => {
12
- if (EF_RENDERING()) return /* @__PURE__ */ new ArrayBuffer(0);
13
11
  const mediaEngine = await getLatestMediaEngine(host, signal);
14
12
  const segmentId = await host.scrubVideoSegmentIdTask.taskComplete;
15
13
  if (segmentId === void 0) throw new Error("Scrub segment ID is not available for video");
@@ -1,4 +1,3 @@
1
- import { EF_RENDERING } from "../../../EF_RENDERING.js";
2
1
  import { getLatestMediaEngine } from "../tasks/makeMediaEngineTask.js";
3
2
  import { Task } from "@lit/task";
4
3
  const makeScrubVideoSegmentIdTask = (host) => {
@@ -9,11 +8,10 @@ const makeScrubVideoSegmentIdTask = (host) => {
9
8
  },
10
9
  onComplete: (_value) => {},
11
10
  task: async ([, targetSeekTimeMs], { signal }) => {
12
- if (EF_RENDERING()) return void 0;
13
11
  const mediaEngine = await getLatestMediaEngine(host, signal);
14
12
  signal.throwIfAborted();
15
13
  const scrubRendition = mediaEngine.getScrubVideoRendition();
16
- if (!scrubRendition) return void 0;
14
+ if (!scrubRendition) return;
17
15
  return mediaEngine.computeSegmentId(targetSeekTimeMs, {
18
16
  ...scrubRendition,
19
17
  src: mediaEngine.src