@editframe/elements 0.26.3-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 (132) hide show
  1. package/package.json +2 -2
  2. package/scripts/build-css.js +3 -3
  3. package/tsdown.config.ts +1 -1
  4. package/src/elements/ContextProxiesController.ts +0 -124
  5. package/src/elements/CrossUpdateController.ts +0 -22
  6. package/src/elements/EFAudio.browsertest.ts +0 -706
  7. package/src/elements/EFAudio.ts +0 -56
  8. package/src/elements/EFCaptions.browsertest.ts +0 -1960
  9. package/src/elements/EFCaptions.ts +0 -823
  10. package/src/elements/EFImage.browsertest.ts +0 -120
  11. package/src/elements/EFImage.ts +0 -113
  12. package/src/elements/EFMedia/AssetIdMediaEngine.test.ts +0 -224
  13. package/src/elements/EFMedia/AssetIdMediaEngine.ts +0 -110
  14. package/src/elements/EFMedia/AssetMediaEngine.browsertest.ts +0 -140
  15. package/src/elements/EFMedia/AssetMediaEngine.ts +0 -385
  16. package/src/elements/EFMedia/BaseMediaEngine.browsertest.ts +0 -400
  17. package/src/elements/EFMedia/BaseMediaEngine.ts +0 -505
  18. package/src/elements/EFMedia/BufferedSeekingInput.browsertest.ts +0 -386
  19. package/src/elements/EFMedia/BufferedSeekingInput.ts +0 -430
  20. package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +0 -226
  21. package/src/elements/EFMedia/JitMediaEngine.ts +0 -256
  22. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.ts +0 -679
  23. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.ts +0 -117
  24. package/src/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.ts +0 -246
  25. package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.ts +0 -59
  26. package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.ts +0 -27
  27. package/src/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.ts +0 -55
  28. package/src/elements/EFMedia/audioTasks/makeAudioInputTask.ts +0 -53
  29. package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.ts +0 -207
  30. package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.ts +0 -72
  31. package/src/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.ts +0 -32
  32. package/src/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.ts +0 -29
  33. package/src/elements/EFMedia/audioTasks/makeAudioTasksVideoOnly.browsertest.ts +0 -95
  34. package/src/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.ts +0 -184
  35. package/src/elements/EFMedia/shared/AudioSpanUtils.ts +0 -129
  36. package/src/elements/EFMedia/shared/BufferUtils.ts +0 -342
  37. package/src/elements/EFMedia/shared/GlobalInputCache.ts +0 -77
  38. package/src/elements/EFMedia/shared/MediaTaskUtils.ts +0 -44
  39. package/src/elements/EFMedia/shared/PrecisionUtils.ts +0 -46
  40. package/src/elements/EFMedia/shared/RenditionHelpers.browsertest.ts +0 -246
  41. package/src/elements/EFMedia/shared/RenditionHelpers.ts +0 -56
  42. package/src/elements/EFMedia/shared/ThumbnailExtractor.ts +0 -227
  43. package/src/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.ts +0 -167
  44. package/src/elements/EFMedia/tasks/makeMediaEngineTask.ts +0 -88
  45. package/src/elements/EFMedia/videoTasks/MainVideoInputCache.ts +0 -76
  46. package/src/elements/EFMedia/videoTasks/ScrubInputCache.ts +0 -61
  47. package/src/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.ts +0 -114
  48. package/src/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.ts +0 -35
  49. package/src/elements/EFMedia/videoTasks/makeScrubVideoInputTask.ts +0 -52
  50. package/src/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.ts +0 -124
  51. package/src/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.ts +0 -44
  52. package/src/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.ts +0 -32
  53. package/src/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.ts +0 -370
  54. package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.ts +0 -109
  55. package/src/elements/EFMedia.browsertest.ts +0 -872
  56. package/src/elements/EFMedia.ts +0 -341
  57. package/src/elements/EFSourceMixin.ts +0 -60
  58. package/src/elements/EFSurface.browsertest.ts +0 -151
  59. package/src/elements/EFSurface.ts +0 -142
  60. package/src/elements/EFTemporal.browsertest.ts +0 -215
  61. package/src/elements/EFTemporal.ts +0 -800
  62. package/src/elements/EFThumbnailStrip.browsertest.ts +0 -585
  63. package/src/elements/EFThumbnailStrip.media-engine.browsertest.ts +0 -714
  64. package/src/elements/EFThumbnailStrip.ts +0 -906
  65. package/src/elements/EFTimegroup.browsertest.ts +0 -934
  66. package/src/elements/EFTimegroup.ts +0 -882
  67. package/src/elements/EFVideo.browsertest.ts +0 -1482
  68. package/src/elements/EFVideo.ts +0 -564
  69. package/src/elements/EFWaveform.ts +0 -547
  70. package/src/elements/FetchContext.browsertest.ts +0 -401
  71. package/src/elements/FetchMixin.ts +0 -38
  72. package/src/elements/SampleBuffer.ts +0 -94
  73. package/src/elements/TargetController.browsertest.ts +0 -230
  74. package/src/elements/TargetController.ts +0 -224
  75. package/src/elements/TimegroupController.ts +0 -26
  76. package/src/elements/durationConverter.ts +0 -35
  77. package/src/elements/parseTimeToMs.ts +0 -9
  78. package/src/elements/printTaskStatus.ts +0 -16
  79. package/src/elements/renderTemporalAudio.ts +0 -108
  80. package/src/elements/updateAnimations.browsertest.ts +0 -1884
  81. package/src/elements/updateAnimations.ts +0 -217
  82. package/src/elements/util.ts +0 -24
  83. package/src/gui/ContextMixin.browsertest.ts +0 -860
  84. package/src/gui/ContextMixin.ts +0 -562
  85. package/src/gui/Controllable.browsertest.ts +0 -258
  86. package/src/gui/Controllable.ts +0 -41
  87. package/src/gui/EFConfiguration.ts +0 -40
  88. package/src/gui/EFControls.browsertest.ts +0 -389
  89. package/src/gui/EFControls.ts +0 -195
  90. package/src/gui/EFDial.browsertest.ts +0 -84
  91. package/src/gui/EFDial.ts +0 -172
  92. package/src/gui/EFFilmstrip.browsertest.ts +0 -712
  93. package/src/gui/EFFilmstrip.ts +0 -1349
  94. package/src/gui/EFFitScale.ts +0 -152
  95. package/src/gui/EFFocusOverlay.ts +0 -79
  96. package/src/gui/EFPause.browsertest.ts +0 -202
  97. package/src/gui/EFPause.ts +0 -73
  98. package/src/gui/EFPlay.browsertest.ts +0 -202
  99. package/src/gui/EFPlay.ts +0 -73
  100. package/src/gui/EFPreview.ts +0 -74
  101. package/src/gui/EFResizableBox.browsertest.ts +0 -79
  102. package/src/gui/EFResizableBox.ts +0 -898
  103. package/src/gui/EFScrubber.ts +0 -151
  104. package/src/gui/EFTimeDisplay.browsertest.ts +0 -237
  105. package/src/gui/EFTimeDisplay.ts +0 -55
  106. package/src/gui/EFToggleLoop.ts +0 -35
  107. package/src/gui/EFTogglePlay.ts +0 -70
  108. package/src/gui/EFWorkbench.ts +0 -115
  109. package/src/gui/PlaybackController.ts +0 -527
  110. package/src/gui/TWMixin.css +0 -6
  111. package/src/gui/TWMixin.ts +0 -61
  112. package/src/gui/TargetOrContextMixin.ts +0 -185
  113. package/src/gui/currentTimeContext.ts +0 -5
  114. package/src/gui/durationContext.ts +0 -3
  115. package/src/gui/efContext.ts +0 -6
  116. package/src/gui/fetchContext.ts +0 -5
  117. package/src/gui/focusContext.ts +0 -7
  118. package/src/gui/focusedElementContext.ts +0 -5
  119. package/src/gui/playingContext.ts +0 -5
  120. package/src/otel/BridgeSpanExporter.ts +0 -150
  121. package/src/otel/setupBrowserTracing.ts +0 -73
  122. package/src/otel/tracingHelpers.ts +0 -251
  123. package/src/transcoding/cache/RequestDeduplicator.test.ts +0 -170
  124. package/src/transcoding/cache/RequestDeduplicator.ts +0 -65
  125. package/src/transcoding/cache/URLTokenDeduplicator.test.ts +0 -182
  126. package/src/transcoding/cache/URLTokenDeduplicator.ts +0 -101
  127. package/src/transcoding/types/index.ts +0 -312
  128. package/src/transcoding/utils/MediaUtils.ts +0 -63
  129. package/src/transcoding/utils/UrlGenerator.ts +0 -68
  130. package/src/transcoding/utils/constants.ts +0 -36
  131. package/src/utils/LRUCache.test.ts +0 -274
  132. 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
- };