@editframe/elements 0.26.2-beta.0 → 0.26.4-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/elements/EFTimegroup.js +7 -2
  2. package/dist/elements/EFTimegroup.js.map +1 -1
  3. package/package.json +2 -2
  4. package/scripts/build-css.js +3 -3
  5. package/tsdown.config.ts +1 -1
  6. package/types.json +1 -1
  7. package/src/elements/ContextProxiesController.ts +0 -124
  8. package/src/elements/CrossUpdateController.ts +0 -22
  9. package/src/elements/EFAudio.browsertest.ts +0 -706
  10. package/src/elements/EFAudio.ts +0 -56
  11. package/src/elements/EFCaptions.browsertest.ts +0 -1960
  12. package/src/elements/EFCaptions.ts +0 -823
  13. package/src/elements/EFImage.browsertest.ts +0 -120
  14. package/src/elements/EFImage.ts +0 -113
  15. package/src/elements/EFMedia/AssetIdMediaEngine.test.ts +0 -224
  16. package/src/elements/EFMedia/AssetIdMediaEngine.ts +0 -110
  17. package/src/elements/EFMedia/AssetMediaEngine.browsertest.ts +0 -140
  18. package/src/elements/EFMedia/AssetMediaEngine.ts +0 -385
  19. package/src/elements/EFMedia/BaseMediaEngine.browsertest.ts +0 -400
  20. package/src/elements/EFMedia/BaseMediaEngine.ts +0 -505
  21. package/src/elements/EFMedia/BufferedSeekingInput.browsertest.ts +0 -386
  22. package/src/elements/EFMedia/BufferedSeekingInput.ts +0 -430
  23. package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +0 -226
  24. package/src/elements/EFMedia/JitMediaEngine.ts +0 -256
  25. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.ts +0 -679
  26. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.ts +0 -117
  27. package/src/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.ts +0 -246
  28. package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.ts +0 -59
  29. package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.ts +0 -27
  30. package/src/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.ts +0 -55
  31. package/src/elements/EFMedia/audioTasks/makeAudioInputTask.ts +0 -53
  32. package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.ts +0 -207
  33. package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.ts +0 -72
  34. package/src/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.ts +0 -32
  35. package/src/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.ts +0 -29
  36. package/src/elements/EFMedia/audioTasks/makeAudioTasksVideoOnly.browsertest.ts +0 -95
  37. package/src/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.ts +0 -184
  38. package/src/elements/EFMedia/shared/AudioSpanUtils.ts +0 -129
  39. package/src/elements/EFMedia/shared/BufferUtils.ts +0 -342
  40. package/src/elements/EFMedia/shared/GlobalInputCache.ts +0 -77
  41. package/src/elements/EFMedia/shared/MediaTaskUtils.ts +0 -44
  42. package/src/elements/EFMedia/shared/PrecisionUtils.ts +0 -46
  43. package/src/elements/EFMedia/shared/RenditionHelpers.browsertest.ts +0 -246
  44. package/src/elements/EFMedia/shared/RenditionHelpers.ts +0 -56
  45. package/src/elements/EFMedia/shared/ThumbnailExtractor.ts +0 -227
  46. package/src/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.ts +0 -167
  47. package/src/elements/EFMedia/tasks/makeMediaEngineTask.ts +0 -88
  48. package/src/elements/EFMedia/videoTasks/MainVideoInputCache.ts +0 -76
  49. package/src/elements/EFMedia/videoTasks/ScrubInputCache.ts +0 -61
  50. package/src/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.ts +0 -114
  51. package/src/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.ts +0 -35
  52. package/src/elements/EFMedia/videoTasks/makeScrubVideoInputTask.ts +0 -52
  53. package/src/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.ts +0 -124
  54. package/src/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.ts +0 -44
  55. package/src/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.ts +0 -32
  56. package/src/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.ts +0 -370
  57. package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.ts +0 -109
  58. package/src/elements/EFMedia.browsertest.ts +0 -872
  59. package/src/elements/EFMedia.ts +0 -341
  60. package/src/elements/EFSourceMixin.ts +0 -60
  61. package/src/elements/EFSurface.browsertest.ts +0 -151
  62. package/src/elements/EFSurface.ts +0 -142
  63. package/src/elements/EFTemporal.browsertest.ts +0 -215
  64. package/src/elements/EFTemporal.ts +0 -800
  65. package/src/elements/EFThumbnailStrip.browsertest.ts +0 -585
  66. package/src/elements/EFThumbnailStrip.media-engine.browsertest.ts +0 -714
  67. package/src/elements/EFThumbnailStrip.ts +0 -906
  68. package/src/elements/EFTimegroup.browsertest.ts +0 -870
  69. package/src/elements/EFTimegroup.ts +0 -878
  70. package/src/elements/EFVideo.browsertest.ts +0 -1482
  71. package/src/elements/EFVideo.ts +0 -564
  72. package/src/elements/EFWaveform.ts +0 -547
  73. package/src/elements/FetchContext.browsertest.ts +0 -401
  74. package/src/elements/FetchMixin.ts +0 -38
  75. package/src/elements/SampleBuffer.ts +0 -94
  76. package/src/elements/TargetController.browsertest.ts +0 -230
  77. package/src/elements/TargetController.ts +0 -224
  78. package/src/elements/TimegroupController.ts +0 -26
  79. package/src/elements/durationConverter.ts +0 -35
  80. package/src/elements/parseTimeToMs.ts +0 -9
  81. package/src/elements/printTaskStatus.ts +0 -16
  82. package/src/elements/renderTemporalAudio.ts +0 -108
  83. package/src/elements/updateAnimations.browsertest.ts +0 -1884
  84. package/src/elements/updateAnimations.ts +0 -217
  85. package/src/elements/util.ts +0 -24
  86. package/src/gui/ContextMixin.browsertest.ts +0 -860
  87. package/src/gui/ContextMixin.ts +0 -562
  88. package/src/gui/Controllable.browsertest.ts +0 -258
  89. package/src/gui/Controllable.ts +0 -41
  90. package/src/gui/EFConfiguration.ts +0 -40
  91. package/src/gui/EFControls.browsertest.ts +0 -389
  92. package/src/gui/EFControls.ts +0 -195
  93. package/src/gui/EFDial.browsertest.ts +0 -84
  94. package/src/gui/EFDial.ts +0 -172
  95. package/src/gui/EFFilmstrip.browsertest.ts +0 -712
  96. package/src/gui/EFFilmstrip.ts +0 -1349
  97. package/src/gui/EFFitScale.ts +0 -152
  98. package/src/gui/EFFocusOverlay.ts +0 -79
  99. package/src/gui/EFPause.browsertest.ts +0 -202
  100. package/src/gui/EFPause.ts +0 -73
  101. package/src/gui/EFPlay.browsertest.ts +0 -202
  102. package/src/gui/EFPlay.ts +0 -73
  103. package/src/gui/EFPreview.ts +0 -74
  104. package/src/gui/EFResizableBox.browsertest.ts +0 -79
  105. package/src/gui/EFResizableBox.ts +0 -898
  106. package/src/gui/EFScrubber.ts +0 -151
  107. package/src/gui/EFTimeDisplay.browsertest.ts +0 -237
  108. package/src/gui/EFTimeDisplay.ts +0 -55
  109. package/src/gui/EFToggleLoop.ts +0 -35
  110. package/src/gui/EFTogglePlay.ts +0 -70
  111. package/src/gui/EFWorkbench.ts +0 -115
  112. package/src/gui/PlaybackController.ts +0 -527
  113. package/src/gui/TWMixin.css +0 -6
  114. package/src/gui/TWMixin.ts +0 -61
  115. package/src/gui/TargetOrContextMixin.ts +0 -185
  116. package/src/gui/currentTimeContext.ts +0 -5
  117. package/src/gui/durationContext.ts +0 -3
  118. package/src/gui/efContext.ts +0 -6
  119. package/src/gui/fetchContext.ts +0 -5
  120. package/src/gui/focusContext.ts +0 -7
  121. package/src/gui/focusedElementContext.ts +0 -5
  122. package/src/gui/playingContext.ts +0 -5
  123. package/src/otel/BridgeSpanExporter.ts +0 -150
  124. package/src/otel/setupBrowserTracing.ts +0 -73
  125. package/src/otel/tracingHelpers.ts +0 -251
  126. package/src/transcoding/cache/RequestDeduplicator.test.ts +0 -170
  127. package/src/transcoding/cache/RequestDeduplicator.ts +0 -65
  128. package/src/transcoding/cache/URLTokenDeduplicator.test.ts +0 -182
  129. package/src/transcoding/cache/URLTokenDeduplicator.ts +0 -101
  130. package/src/transcoding/types/index.ts +0 -312
  131. package/src/transcoding/utils/MediaUtils.ts +0 -63
  132. package/src/transcoding/utils/UrlGenerator.ts +0 -68
  133. package/src/transcoding/utils/constants.ts +0 -36
  134. package/src/utils/LRUCache.test.ts +0 -274
  135. package/src/utils/LRUCache.ts +0 -696
@@ -1,370 +0,0 @@
1
- import { Task } from "@lit/task";
2
- import type { VideoSample } from "mediabunny";
3
- import { withSpan } from "../../../otel/tracingHelpers.js";
4
- import type { VideoRendition } from "../../../transcoding/types";
5
- import { EFMedia } from "../../EFMedia.js";
6
- import type { EFVideo } from "../../EFVideo";
7
- import { BufferedSeekingInput } from "../BufferedSeekingInput.js";
8
- import { getLatestMediaEngine } from "../tasks/makeMediaEngineTask";
9
- import { MainVideoInputCache } from "./MainVideoInputCache";
10
- import { ScrubInputCache } from "./ScrubInputCache";
11
-
12
- type UnifiedVideoSeekTask = Task<readonly [number], VideoSample | undefined>;
13
-
14
- // Shared cache for scrub inputs
15
- const scrubInputCache = new ScrubInputCache();
16
-
17
- // Shared cache for main video inputs
18
- const mainVideoInputCache = new MainVideoInputCache();
19
-
20
- export const makeUnifiedVideoSeekTask = (
21
- host: EFVideo,
22
- ): UnifiedVideoSeekTask => {
23
- return new Task(host, {
24
- autoRun: false,
25
- args: () => [host.desiredSeekTimeMs] as const,
26
- onError: (error) => {
27
- console.error("unifiedVideoSeekTask error", error);
28
- },
29
- onComplete: (_value) => {},
30
- task: async ([desiredSeekTimeMs], { signal }) => {
31
- const mediaEngine = await getLatestMediaEngine(host, signal);
32
- if (!mediaEngine || signal.aborted) return undefined;
33
-
34
- // FIRST: Check if main quality content is already cached
35
- const mainRendition = mediaEngine.videoRendition;
36
- if (mainRendition) {
37
- const mainSegmentId = mediaEngine.computeSegmentId(
38
- desiredSeekTimeMs,
39
- mainRendition,
40
- );
41
- if (
42
- mainSegmentId !== undefined &&
43
- mediaEngine.isSegmentCached(mainSegmentId, mainRendition)
44
- ) {
45
- const result = await getMainVideoSample(
46
- host,
47
- mediaEngine,
48
- desiredSeekTimeMs,
49
- signal,
50
- );
51
-
52
- if (signal.aborted) {
53
- return undefined;
54
- }
55
-
56
- return result;
57
- }
58
- }
59
-
60
- // SECOND: Main not cached, try scrub path (instant if cached)
61
- const scrubSample = await tryGetScrubSample(
62
- mediaEngine,
63
- desiredSeekTimeMs,
64
- signal,
65
- );
66
-
67
- if (scrubSample || signal.aborted) {
68
- if (signal.aborted) {
69
- return undefined;
70
- }
71
-
72
- // If scrub succeeded, start background main quality upgrade (non-blocking)
73
- if (scrubSample) {
74
- startMainQualityUpgrade(
75
- host,
76
- mediaEngine,
77
- desiredSeekTimeMs,
78
- signal,
79
- ).catch(() => {
80
- // Main upgrade failed - scrub already succeeded, that's fine
81
- });
82
- }
83
-
84
- return scrubSample;
85
- }
86
-
87
- // THIRD: Neither are cached, fetch main video path as final fallback
88
- const result = await getMainVideoSample(
89
- host,
90
- mediaEngine,
91
- desiredSeekTimeMs,
92
- signal,
93
- );
94
-
95
- if (signal.aborted) {
96
- return undefined;
97
- }
98
-
99
- return result;
100
- },
101
- });
102
- };
103
-
104
- /**
105
- * Try to get scrub sample from cache (instant if available)
106
- */
107
- async function tryGetScrubSample(
108
- mediaEngine: any,
109
- desiredSeekTimeMs: number,
110
- signal: AbortSignal,
111
- ): Promise<VideoSample | undefined> {
112
- return withSpan(
113
- "video.tryGetScrubSample",
114
- {
115
- desiredSeekTimeMs,
116
- src: mediaEngine.src || "unknown",
117
- },
118
- undefined,
119
- async (span) => {
120
- try {
121
- // Get scrub rendition
122
- let scrubRendition: VideoRendition | undefined;
123
-
124
- // Check if media engine has a getScrubVideoRendition method (AssetMediaEngine, etc.)
125
- if (typeof mediaEngine.getScrubVideoRendition === "function") {
126
- scrubRendition = mediaEngine.getScrubVideoRendition();
127
- } else if ("data" in mediaEngine && mediaEngine.data?.videoRenditions) {
128
- // Fallback to data structure for other engines
129
- scrubRendition = mediaEngine.data.videoRenditions.find(
130
- (r: any) => r.id === "scrub",
131
- );
132
- }
133
-
134
- if (!scrubRendition) {
135
- span.setAttribute("result", "no-scrub-rendition");
136
- return undefined;
137
- }
138
-
139
- const scrubRenditionWithSrc = {
140
- ...scrubRendition,
141
- src: mediaEngine.src,
142
- };
143
-
144
- // Check if scrub segment is cached
145
- const segmentId = mediaEngine.computeSegmentId(
146
- desiredSeekTimeMs,
147
- scrubRenditionWithSrc,
148
- );
149
- if (segmentId === undefined) {
150
- span.setAttribute("result", "no-segment-id");
151
- return undefined;
152
- }
153
-
154
- const isCached = mediaEngine.isSegmentCached(
155
- segmentId,
156
- scrubRenditionWithSrc,
157
- );
158
- span.setAttribute("isCached", isCached);
159
- if (!isCached) {
160
- span.setAttribute("result", "not-cached");
161
- return undefined; // Not cached - let main video handle it
162
- }
163
-
164
- // Get cached scrub input and seek within it
165
- const scrubInput = await scrubInputCache.getOrCreateInput(
166
- segmentId,
167
- async () => {
168
- const [initSegment, mediaSegment] = await Promise.all([
169
- mediaEngine.fetchInitSegment(scrubRenditionWithSrc, signal),
170
- mediaEngine.fetchMediaSegment(segmentId, scrubRenditionWithSrc),
171
- ]);
172
-
173
- if (!initSegment || !mediaSegment || signal.aborted)
174
- return undefined;
175
-
176
- const { BufferedSeekingInput } = await import(
177
- "../BufferedSeekingInput.js"
178
- );
179
- const { EFMedia } = await import("../../EFMedia.js");
180
-
181
- return new BufferedSeekingInput(
182
- await new Blob([initSegment, mediaSegment]).arrayBuffer(),
183
- {
184
- videoBufferSize: EFMedia.VIDEO_SAMPLE_BUFFER_SIZE,
185
- audioBufferSize: EFMedia.AUDIO_SAMPLE_BUFFER_SIZE,
186
- startTimeOffsetMs: scrubRendition.startTimeOffsetMs,
187
- },
188
- );
189
- },
190
- );
191
-
192
- if (!scrubInput) {
193
- span.setAttribute("result", "no-scrub-input");
194
- return undefined;
195
- }
196
-
197
- if (signal.aborted) {
198
- span.setAttribute("result", "aborted-after-scrub-input");
199
- return undefined;
200
- }
201
-
202
- const videoTrack = await scrubInput.getFirstVideoTrack();
203
- if (!videoTrack) {
204
- span.setAttribute("result", "no-video-track");
205
- return undefined;
206
- }
207
-
208
- if (signal.aborted) {
209
- span.setAttribute("result", "aborted-after-scrub-track");
210
- return undefined;
211
- }
212
-
213
- const sample = (await scrubInput.seek(
214
- videoTrack.id,
215
- desiredSeekTimeMs,
216
- )) as unknown as VideoSample | undefined;
217
-
218
- span.setAttribute("result", sample ? "success" : "no-sample");
219
- return sample;
220
- } catch (_error) {
221
- if (signal.aborted) {
222
- span.setAttribute("result", "aborted");
223
- return undefined;
224
- }
225
- span.setAttribute("result", "error");
226
- return undefined; // Scrub failed - let main video handle it
227
- }
228
- },
229
- );
230
- }
231
-
232
- /**
233
- * Get main video sample (slower path with fetching)
234
- */
235
- async function getMainVideoSample(
236
- _host: EFVideo,
237
- mediaEngine: any,
238
- desiredSeekTimeMs: number,
239
- signal: AbortSignal,
240
- ): Promise<VideoSample | undefined> {
241
- return withSpan(
242
- "video.getMainVideoSample",
243
- {
244
- desiredSeekTimeMs,
245
- src: mediaEngine.src || "unknown",
246
- },
247
- undefined,
248
- async (span) => {
249
- try {
250
- // Use existing main video task chain
251
- const videoRendition = mediaEngine.getVideoRendition();
252
- if (!videoRendition) {
253
- throw new Error(
254
- "Video rendition unavailable after checking videoRendition exists",
255
- );
256
- }
257
-
258
- const segmentId = mediaEngine.computeSegmentId(
259
- desiredSeekTimeMs,
260
- videoRendition,
261
- );
262
- if (segmentId === undefined) {
263
- span.setAttribute("result", "no-segment-id");
264
- return undefined;
265
- }
266
-
267
- span.setAttribute("segmentId", segmentId);
268
-
269
- // Get cached main video input or create new one
270
- const mainInput = await mainVideoInputCache.getOrCreateInput(
271
- mediaEngine.src,
272
- segmentId,
273
- videoRendition.id,
274
- async () => {
275
- // Fetch main video segment (will be cached at mediaEngine level)
276
- const [initSegment, mediaSegment] = await Promise.all([
277
- mediaEngine.fetchInitSegment(videoRendition, signal),
278
- mediaEngine.fetchMediaSegment(segmentId, videoRendition, signal),
279
- ]);
280
-
281
- if (!initSegment || !mediaSegment) {
282
- return undefined;
283
- }
284
- signal.throwIfAborted();
285
-
286
- const startTimeOffsetMs = videoRendition?.startTimeOffsetMs;
287
-
288
- return new BufferedSeekingInput(
289
- await new Blob([initSegment, mediaSegment]).arrayBuffer(),
290
- {
291
- videoBufferSize: EFMedia.VIDEO_SAMPLE_BUFFER_SIZE,
292
- audioBufferSize: EFMedia.AUDIO_SAMPLE_BUFFER_SIZE,
293
- startTimeOffsetMs,
294
- },
295
- );
296
- },
297
- );
298
-
299
- if (!mainInput) {
300
- span.setAttribute("result", "no-segments");
301
- return undefined;
302
- }
303
-
304
- if (signal.aborted) {
305
- span.setAttribute("result", "aborted-after-input");
306
- return undefined;
307
- }
308
-
309
- const videoTrack = await mainInput.getFirstVideoTrack();
310
- if (!videoTrack) {
311
- span.setAttribute("result", "no-video-track");
312
- return undefined;
313
- }
314
-
315
- if (signal.aborted) {
316
- span.setAttribute("result", "aborted-after-track");
317
- return undefined;
318
- }
319
-
320
- const sample = (await mainInput.seek(
321
- videoTrack.id,
322
- desiredSeekTimeMs,
323
- )) as unknown as VideoSample | undefined;
324
-
325
- span.setAttribute("result", sample ? "success" : "no-sample");
326
- return sample;
327
- } catch (error) {
328
- if (signal.aborted) {
329
- span.setAttribute("result", "aborted");
330
- return undefined;
331
- }
332
- throw error;
333
- }
334
- },
335
- );
336
- }
337
-
338
- /**
339
- * Start background upgrade to main quality (non-blocking)
340
- */
341
- async function startMainQualityUpgrade(
342
- host: EFVideo,
343
- mediaEngine: any,
344
- targetSeekTimeMs: number,
345
- signal: AbortSignal,
346
- ): Promise<void> {
347
- // Small delay to let scrub content display first
348
- await new Promise((resolve) => setTimeout(resolve, 50));
349
- if (signal.aborted || host.desiredSeekTimeMs !== targetSeekTimeMs) return;
350
-
351
- // Get main quality sample and upgrade display
352
- const mainSample = await getMainVideoSample(
353
- host,
354
- mediaEngine,
355
- targetSeekTimeMs,
356
- signal,
357
- );
358
- if (
359
- mainSample &&
360
- !signal.aborted &&
361
- host.desiredSeekTimeMs === targetSeekTimeMs
362
- ) {
363
- const videoFrame = mainSample.toVideoFrame();
364
- try {
365
- host.displayFrame(videoFrame, targetSeekTimeMs);
366
- } finally {
367
- videoFrame.close();
368
- }
369
- }
370
- }
@@ -1,109 +0,0 @@
1
- import { Task } from "@lit/task";
2
-
3
- import { EF_INTERACTIVE } from "../../../EF_INTERACTIVE";
4
- import { EF_RENDERING } from "../../../EF_RENDERING";
5
- import type { VideoRendition } from "../../../transcoding/types";
6
- import type { EFVideo } from "../../EFVideo";
7
- import {
8
- type MediaBufferConfig,
9
- type MediaBufferState,
10
- manageMediaBuffer,
11
- } from "../shared/BufferUtils";
12
- import { getLatestMediaEngine } from "../tasks/makeMediaEngineTask";
13
-
14
- /**
15
- * Configuration for video buffering - extends the generic interface
16
- */
17
- export interface VideoBufferConfig extends MediaBufferConfig {}
18
-
19
- /**
20
- * State of the video buffer - uses the generic interface
21
- */
22
- export interface VideoBufferState extends MediaBufferState {}
23
-
24
- type VideoBufferTask = Task<readonly [number], VideoBufferState>;
25
- export const makeVideoBufferTask = (host: EFVideo): VideoBufferTask => {
26
- let currentState: VideoBufferState = {
27
- currentSeekTimeMs: 0,
28
- requestedSegments: new Set(),
29
- activeRequests: new Set(),
30
- requestQueue: [],
31
- };
32
-
33
- return new Task(host, {
34
- autoRun: EF_INTERACTIVE, // Make lazy - only run when element becomes timeline-active
35
- args: () => [host.desiredSeekTimeMs] as const,
36
- onError: (error) => {
37
- console.error("videoBufferTask error", error);
38
- },
39
- onComplete: (value) => {
40
- currentState = value;
41
- },
42
- task: async ([seekTimeMs], { signal }) => {
43
- // Skip buffering entirely in rendering mode
44
- if (EF_RENDERING()) {
45
- return currentState; // Return existing state without any buffering activity
46
- }
47
-
48
- // Get media engine to potentially override buffer configuration
49
- const mediaEngine = await getLatestMediaEngine(host, signal);
50
-
51
- // Use media engine's buffer config, falling back to host properties
52
- const engineConfig = mediaEngine.getBufferConfig();
53
- const bufferDurationMs = engineConfig.videoBufferDurationMs;
54
- const maxParallelFetches = engineConfig.maxVideoBufferFetches;
55
-
56
- const currentConfig: VideoBufferConfig = {
57
- bufferDurationMs,
58
- maxParallelFetches,
59
- enableBuffering: host.enableVideoBuffering,
60
- bufferThresholdMs: engineConfig.bufferThresholdMs,
61
- };
62
-
63
- // Timeline context for priority-based buffering
64
- const timelineContext =
65
- host.rootTimegroup?.currentTimeMs !== undefined
66
- ? {
67
- elementStartMs: host.startTimeMs,
68
- elementEndMs: host.endTimeMs,
69
- playheadMs: host.rootTimegroup.currentTimeMs,
70
- }
71
- : undefined;
72
-
73
- return manageMediaBuffer<VideoRendition>(
74
- seekTimeMs,
75
- currentConfig,
76
- currentState,
77
- (host as any).intrinsicDurationMs || 10000,
78
- signal,
79
- {
80
- computeSegmentId: async (timeMs, rendition) => {
81
- // Use media engine's computeSegmentId
82
- const mediaEngine = await getLatestMediaEngine(host, signal);
83
- return mediaEngine.computeSegmentId(timeMs, rendition);
84
- },
85
- prefetchSegment: async (segmentId, rendition) => {
86
- // Trigger prefetch through BaseMediaEngine - let it handle caching
87
- const mediaEngine = await getLatestMediaEngine(host, signal);
88
- await mediaEngine.fetchMediaSegment(segmentId, rendition);
89
- // Don't return data - just ensure it's cached in BaseMediaEngine
90
- },
91
- isSegmentCached: (segmentId, rendition) => {
92
- // Check if segment is already cached in BaseMediaEngine
93
- const mediaEngine = host.mediaEngineTask.value;
94
- if (!mediaEngine) return false;
95
-
96
- return mediaEngine.isSegmentCached(segmentId, rendition);
97
- },
98
- getRendition: async () => {
99
- // Get real video rendition from media engine
100
- const mediaEngine = await getLatestMediaEngine(host, signal);
101
- return mediaEngine.getVideoRendition();
102
- },
103
- logError: console.error,
104
- },
105
- timelineContext,
106
- );
107
- },
108
- });
109
- };