@editframe/elements 0.17.6-beta.0 → 0.18.3-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 (218) hide show
  1. package/dist/EF_FRAMEGEN.js +1 -1
  2. package/dist/ScrubTrackManager.d.ts +2 -2
  3. package/dist/elements/EFAudio.d.ts +21 -2
  4. package/dist/elements/EFAudio.js +41 -11
  5. package/dist/elements/EFImage.d.ts +1 -0
  6. package/dist/elements/EFImage.js +11 -3
  7. package/dist/elements/EFMedia/AssetIdMediaEngine.d.ts +18 -0
  8. package/dist/elements/EFMedia/AssetIdMediaEngine.js +41 -0
  9. package/dist/elements/EFMedia/AssetMediaEngine.d.ts +47 -0
  10. package/dist/elements/EFMedia/AssetMediaEngine.js +116 -0
  11. package/dist/elements/EFMedia/BaseMediaEngine.d.ts +55 -0
  12. package/dist/elements/EFMedia/BaseMediaEngine.js +96 -0
  13. package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +43 -0
  14. package/dist/elements/EFMedia/BufferedSeekingInput.js +159 -0
  15. package/dist/elements/EFMedia/JitMediaEngine.browsertest.d.ts +0 -0
  16. package/dist/elements/EFMedia/JitMediaEngine.d.ts +31 -0
  17. package/dist/elements/EFMedia/JitMediaEngine.js +62 -0
  18. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.d.ts +9 -0
  19. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.d.ts +16 -0
  20. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +48 -0
  21. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.d.ts +3 -0
  22. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +138 -0
  23. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.d.ts +9 -0
  24. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.d.ts +4 -0
  25. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +16 -0
  26. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.d.ts +9 -0
  27. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.d.ts +3 -0
  28. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +22 -0
  29. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.d.ts +7 -0
  30. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +24 -0
  31. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.d.ts +4 -0
  32. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +18 -0
  33. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.d.ts +4 -0
  34. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +16 -0
  35. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.d.ts +3 -0
  36. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +104 -0
  37. package/dist/elements/EFMedia/services/AudioElementFactory.d.ts +22 -0
  38. package/dist/elements/EFMedia/services/AudioElementFactory.js +72 -0
  39. package/dist/elements/EFMedia/services/MediaSourceService.browsertest.d.ts +1 -0
  40. package/dist/elements/EFMedia/services/MediaSourceService.d.ts +47 -0
  41. package/dist/elements/EFMedia/services/MediaSourceService.js +73 -0
  42. package/dist/elements/EFMedia/shared/AudioSpanUtils.d.ts +7 -0
  43. package/dist/elements/EFMedia/shared/AudioSpanUtils.js +54 -0
  44. package/dist/elements/EFMedia/shared/BufferUtils.d.ts +70 -0
  45. package/dist/elements/EFMedia/shared/BufferUtils.js +89 -0
  46. package/dist/elements/EFMedia/shared/MediaTaskUtils.d.ts +23 -0
  47. package/dist/elements/EFMedia/shared/RenditionHelpers.browsertest.d.ts +1 -0
  48. package/dist/elements/EFMedia/shared/RenditionHelpers.d.ts +19 -0
  49. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.d.ts +1 -0
  50. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.d.ts +18 -0
  51. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +60 -0
  52. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.test.d.ts +1 -0
  53. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.browsertest.d.ts +9 -0
  54. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.d.ts +16 -0
  55. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +46 -0
  56. package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.browsertest.d.ts +9 -0
  57. package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.d.ts +4 -0
  58. package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.js +16 -0
  59. package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.browsertest.d.ts +9 -0
  60. package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.d.ts +3 -0
  61. package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.js +27 -0
  62. package/dist/elements/EFMedia/videoTasks/makeVideoSeekTask.d.ts +7 -0
  63. package/dist/elements/EFMedia/videoTasks/makeVideoSeekTask.js +25 -0
  64. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.d.ts +9 -0
  65. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.d.ts +4 -0
  66. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.js +18 -0
  67. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.d.ts +9 -0
  68. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.d.ts +4 -0
  69. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.js +16 -0
  70. package/dist/elements/EFMedia.browsertest.d.ts +1 -0
  71. package/dist/elements/EFMedia.d.ts +75 -111
  72. package/dist/elements/EFMedia.js +141 -1111
  73. package/dist/elements/EFTemporal.d.ts +1 -1
  74. package/dist/elements/EFTemporal.js +1 -1
  75. package/dist/elements/EFTimegroup.d.ts +11 -0
  76. package/dist/elements/EFTimegroup.js +88 -13
  77. package/dist/elements/EFVideo.d.ts +60 -29
  78. package/dist/elements/EFVideo.js +103 -203
  79. package/dist/elements/EFWaveform.js +2 -2
  80. package/dist/elements/SampleBuffer.d.ts +14 -0
  81. package/dist/elements/SampleBuffer.js +52 -0
  82. package/dist/getRenderInfo.d.ts +2 -2
  83. package/dist/getRenderInfo.js +2 -1
  84. package/dist/gui/ContextMixin.js +17 -70
  85. package/dist/gui/EFFilmstrip.d.ts +3 -3
  86. package/dist/gui/EFFilmstrip.js +1 -1
  87. package/dist/gui/EFFitScale.d.ts +2 -2
  88. package/dist/gui/TWMixin.js +1 -1
  89. package/dist/gui/services/ElementConnectionManager.browsertest.d.ts +1 -0
  90. package/dist/gui/services/ElementConnectionManager.d.ts +59 -0
  91. package/dist/gui/services/ElementConnectionManager.js +128 -0
  92. package/dist/gui/services/PlaybackController.browsertest.d.ts +1 -0
  93. package/dist/gui/services/PlaybackController.d.ts +103 -0
  94. package/dist/gui/services/PlaybackController.js +290 -0
  95. package/dist/services/MediaSourceManager.d.ts +62 -0
  96. package/dist/services/MediaSourceManager.js +211 -0
  97. package/dist/style.css +1 -1
  98. package/dist/transcoding/cache/CacheManager.d.ts +73 -0
  99. package/dist/transcoding/cache/RequestDeduplicator.d.ts +29 -0
  100. package/dist/transcoding/cache/RequestDeduplicator.js +53 -0
  101. package/dist/transcoding/cache/RequestDeduplicator.test.d.ts +1 -0
  102. package/dist/transcoding/types/index.d.ts +242 -0
  103. package/dist/transcoding/utils/MediaUtils.d.ts +9 -0
  104. package/dist/transcoding/utils/UrlGenerator.d.ts +26 -0
  105. package/dist/transcoding/utils/UrlGenerator.js +45 -0
  106. package/dist/transcoding/utils/constants.d.ts +27 -0
  107. package/dist/utils/LRUCache.d.ts +34 -0
  108. package/dist/utils/LRUCache.js +115 -0
  109. package/package.json +3 -2
  110. package/src/elements/EFAudio.browsertest.ts +183 -43
  111. package/src/elements/EFAudio.ts +59 -13
  112. package/src/elements/EFImage.browsertest.ts +42 -0
  113. package/src/elements/EFImage.ts +23 -3
  114. package/src/elements/EFMedia/AssetIdMediaEngine.test.ts +222 -0
  115. package/src/elements/EFMedia/AssetIdMediaEngine.ts +70 -0
  116. package/src/elements/EFMedia/AssetMediaEngine.ts +210 -0
  117. package/src/elements/EFMedia/BaseMediaEngine.test.ts +164 -0
  118. package/src/elements/EFMedia/BaseMediaEngine.ts +170 -0
  119. package/src/elements/EFMedia/BufferedSeekingInput.browsertest.ts +400 -0
  120. package/src/elements/EFMedia/BufferedSeekingInput.ts +267 -0
  121. package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +165 -0
  122. package/src/elements/EFMedia/JitMediaEngine.ts +110 -0
  123. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.ts +554 -0
  124. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.ts +81 -0
  125. package/src/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.ts +241 -0
  126. package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.ts +59 -0
  127. package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.ts +23 -0
  128. package/src/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.ts +55 -0
  129. package/src/elements/EFMedia/audioTasks/makeAudioInputTask.ts +35 -0
  130. package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.ts +42 -0
  131. package/src/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.ts +34 -0
  132. package/src/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.ts +23 -0
  133. package/src/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.ts +174 -0
  134. package/src/elements/EFMedia/services/AudioElementFactory.browsertest.ts +325 -0
  135. package/src/elements/EFMedia/services/AudioElementFactory.ts +119 -0
  136. package/src/elements/EFMedia/services/MediaSourceService.browsertest.ts +257 -0
  137. package/src/elements/EFMedia/services/MediaSourceService.ts +102 -0
  138. package/src/elements/EFMedia/shared/AudioSpanUtils.ts +128 -0
  139. package/src/elements/EFMedia/shared/BufferUtils.ts +310 -0
  140. package/src/elements/EFMedia/shared/MediaTaskUtils.ts +44 -0
  141. package/src/elements/EFMedia/shared/RenditionHelpers.browsertest.ts +247 -0
  142. package/src/elements/EFMedia/shared/RenditionHelpers.ts +79 -0
  143. package/src/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.ts +128 -0
  144. package/src/elements/EFMedia/tasks/makeMediaEngineTask.test.ts +233 -0
  145. package/src/elements/EFMedia/tasks/makeMediaEngineTask.ts +89 -0
  146. package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.browsertest.ts +555 -0
  147. package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.ts +79 -0
  148. package/src/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.browsertest.ts +59 -0
  149. package/src/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.ts +23 -0
  150. package/src/elements/EFMedia/videoTasks/makeVideoInputTask.browsertest.ts +55 -0
  151. package/src/elements/EFMedia/videoTasks/makeVideoInputTask.ts +45 -0
  152. package/src/elements/EFMedia/videoTasks/makeVideoSeekTask.ts +44 -0
  153. package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.ts +57 -0
  154. package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.ts +32 -0
  155. package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.ts +56 -0
  156. package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.ts +23 -0
  157. package/src/elements/EFMedia.browsertest.ts +658 -265
  158. package/src/elements/EFMedia.ts +173 -1763
  159. package/src/elements/EFTemporal.ts +3 -4
  160. package/src/elements/EFTimegroup.browsertest.ts +6 -3
  161. package/src/elements/EFTimegroup.ts +152 -21
  162. package/src/elements/EFVideo.browsertest.ts +115 -37
  163. package/src/elements/EFVideo.ts +123 -452
  164. package/src/elements/EFWaveform.ts +1 -1
  165. package/src/elements/MediaController.ts +2 -12
  166. package/src/elements/SampleBuffer.ts +97 -0
  167. package/src/gui/ContextMixin.ts +23 -104
  168. package/src/gui/services/ElementConnectionManager.browsertest.ts +263 -0
  169. package/src/gui/services/ElementConnectionManager.ts +224 -0
  170. package/src/gui/services/PlaybackController.browsertest.ts +437 -0
  171. package/src/gui/services/PlaybackController.ts +521 -0
  172. package/src/services/MediaSourceManager.ts +333 -0
  173. package/src/transcoding/cache/CacheManager.ts +208 -0
  174. package/src/transcoding/cache/RequestDeduplicator.test.ts +170 -0
  175. package/src/transcoding/cache/RequestDeduplicator.ts +65 -0
  176. package/src/transcoding/types/index.ts +265 -0
  177. package/src/transcoding/utils/MediaUtils.ts +63 -0
  178. package/src/transcoding/utils/UrlGenerator.ts +68 -0
  179. package/src/transcoding/utils/constants.ts +36 -0
  180. package/src/utils/LRUCache.ts +153 -0
  181. package/test/EFVideo.framegen.browsertest.ts +38 -29
  182. package/test/__cache__/GET__api_v1_transcode_audio_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__32da3954ba60c96ad732020c65a08ebc/data.bin +0 -0
  183. package/test/__cache__/GET__api_v1_transcode_audio_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__32da3954ba60c96ad732020c65a08ebc/metadata.json +21 -0
  184. package/test/__cache__/GET__api_v1_transcode_audio_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__b0b2b07efcf607de8ee0f650328c32f7/data.bin +0 -0
  185. package/test/__cache__/GET__api_v1_transcode_audio_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__b0b2b07efcf607de8ee0f650328c32f7/metadata.json +21 -0
  186. package/test/__cache__/GET__api_v1_transcode_audio_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a75c2252b542e0c152c780e9a8d7b154/data.bin +0 -0
  187. package/test/__cache__/GET__api_v1_transcode_audio_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a75c2252b542e0c152c780e9a8d7b154/metadata.json +21 -0
  188. package/test/__cache__/GET__api_v1_transcode_audio_4_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a64ff1cfb1b52cae14df4b5dfa1e222b/data.bin +0 -0
  189. package/test/__cache__/GET__api_v1_transcode_audio_4_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a64ff1cfb1b52cae14df4b5dfa1e222b/metadata.json +21 -0
  190. package/test/__cache__/GET__api_v1_transcode_audio_5_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__91e8a522f950809b9f09f4173113b4b0/data.bin +0 -0
  191. package/test/__cache__/GET__api_v1_transcode_audio_5_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__91e8a522f950809b9f09f4173113b4b0/metadata.json +21 -0
  192. package/test/__cache__/GET__api_v1_transcode_audio_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__e66d2c831d951e74ad0aeaa6489795d0/data.bin +0 -0
  193. package/test/__cache__/GET__api_v1_transcode_audio_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__e66d2c831d951e74ad0aeaa6489795d0/metadata.json +21 -0
  194. package/test/__cache__/GET__api_v1_transcode_high_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__26197f6f7c46cacb0a71134131c3f775/data.bin +0 -0
  195. package/test/__cache__/GET__api_v1_transcode_high_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__26197f6f7c46cacb0a71134131c3f775/metadata.json +21 -0
  196. package/test/__cache__/GET__api_v1_transcode_high_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__4cb6774cd3650ccf59c8f8dc6678c0b9/data.bin +0 -0
  197. package/test/__cache__/GET__api_v1_transcode_high_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__4cb6774cd3650ccf59c8f8dc6678c0b9/metadata.json +21 -0
  198. package/test/__cache__/GET__api_v1_transcode_high_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0b3b2b1c8933f7fcf8a9ecaa88d58b41/data.bin +0 -0
  199. package/test/__cache__/GET__api_v1_transcode_high_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0b3b2b1c8933f7fcf8a9ecaa88d58b41/metadata.json +21 -0
  200. package/test/__cache__/GET__api_v1_transcode_high_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0798c479b44aaeef850609a430f6e613/data.bin +0 -0
  201. package/test/__cache__/GET__api_v1_transcode_high_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0798c479b44aaeef850609a430f6e613/metadata.json +21 -0
  202. package/test/__cache__/GET__api_v1_transcode_manifest_json_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__3be92a0437de726b431ed5af2369158a/data.bin +1 -0
  203. package/test/__cache__/GET__api_v1_transcode_manifest_json_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__3be92a0437de726b431ed5af2369158a/metadata.json +19 -0
  204. package/test/createJitTestClips.ts +320 -188
  205. package/test/recordReplayProxyPlugin.js +302 -0
  206. package/test/useAssetMSW.ts +1 -1
  207. package/test/useMSW.ts +35 -22
  208. package/types.json +1 -1
  209. package/dist/JitTranscodingClient.d.ts +0 -167
  210. package/dist/JitTranscodingClient.js +0 -373
  211. package/dist/ScrubTrackManager.js +0 -216
  212. package/dist/elements/printTaskStatus.js +0 -11
  213. package/src/elements/__screenshots__/EFMedia.browsertest.ts/EFMedia-JIT-audio-playback-audioBufferTask-should-work-in-JIT-mode-without-URL-errors-1.png +0 -0
  214. package/test/EFVideo.frame-tasks.browsertest.ts +0 -524
  215. /package/dist/{JitTranscodingClient.browsertest.d.ts → elements/EFMedia/AssetIdMediaEngine.test.d.ts} +0 -0
  216. /package/dist/{JitTranscodingClient.test.d.ts → elements/EFMedia/BaseMediaEngine.test.d.ts} +0 -0
  217. /package/dist/{ScrubTrackIntegration.test.d.ts → elements/EFMedia/BufferedSeekingInput.browsertest.d.ts} +0 -0
  218. /package/dist/{SegmentSwitchLoading.test.d.ts → elements/EFMedia/services/AudioElementFactory.browsertest.d.ts} +0 -0
@@ -0,0 +1,79 @@
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 {
13
+ getLatestMediaEngine,
14
+ getVideoRendition,
15
+ } from "../tasks/makeMediaEngineTask";
16
+
17
+ /**
18
+ * Configuration for video buffering - extends the generic interface
19
+ */
20
+ export interface VideoBufferConfig extends MediaBufferConfig {}
21
+
22
+ /**
23
+ * State of the video buffer - uses the generic interface
24
+ */
25
+ export interface VideoBufferState extends MediaBufferState {}
26
+
27
+ type VideoBufferTask = Task<readonly [number], VideoBufferState>;
28
+ export const makeVideoBufferTask = (host: EFVideo): VideoBufferTask => {
29
+ let currentState: VideoBufferState = {
30
+ currentSeekTimeMs: 0,
31
+ activeRequests: new Set(),
32
+ cachedSegments: new Set(),
33
+ requestQueue: [],
34
+ };
35
+
36
+ return new Task(host, {
37
+ autoRun: EF_INTERACTIVE, // Start buffering automatically when media is ready
38
+ args: () => [host.desiredSeekTimeMs] as const,
39
+ onError: (error) => {
40
+ console.error("videoBufferTask error", error);
41
+ },
42
+ onComplete: (value) => {
43
+ currentState = value;
44
+ },
45
+ task: async ([seekTimeMs], { signal }) => {
46
+ // Use EFMedia properties directly - no hardcoded duplication!
47
+ const currentConfig: VideoBufferConfig = {
48
+ bufferDurationMs: host.videoBufferDurationMs,
49
+ maxParallelFetches: host.maxVideoBufferFetches,
50
+ enableBuffering: host.enableVideoBuffering && !EF_RENDERING,
51
+ };
52
+
53
+ return manageMediaBuffer<VideoRendition>(
54
+ seekTimeMs,
55
+ currentConfig,
56
+ currentState,
57
+ (host as any).intrinsicDurationMs || 10000,
58
+ signal,
59
+ {
60
+ computeSegmentId: async (timeMs, rendition) => {
61
+ // Use media engine's computeSegmentId
62
+ const mediaEngine = await getLatestMediaEngine(host, signal);
63
+ return mediaEngine.computeSegmentId(timeMs, rendition);
64
+ },
65
+ fetchSegment: async (segmentId, rendition) => {
66
+ const mediaEngine = await getLatestMediaEngine(host, signal);
67
+ return mediaEngine.fetchMediaSegment(segmentId, rendition);
68
+ },
69
+ getRendition: async () => {
70
+ // Get real video rendition from media engine
71
+ const mediaEngine = await getLatestMediaEngine(host, signal);
72
+ return getVideoRendition(mediaEngine);
73
+ },
74
+ logError: console.error,
75
+ },
76
+ );
77
+ },
78
+ });
79
+ };
@@ -0,0 +1,59 @@
1
+ import { TaskStatus } from "@lit/task";
2
+ import { customElement } from "lit/decorators.js";
3
+ import { afterEach, beforeEach, describe, vi } from "vitest";
4
+ import { test as baseTest } from "../../../../test/useMSW.js";
5
+ import { EFVideo } from "../../EFVideo";
6
+ import { makeVideoInitSegmentFetchTask } from "./makeVideoInitSegmentFetchTask";
7
+
8
+ @customElement("test-media-video-init-segment-fetch")
9
+ class TestMediaVideoInitSegmentFetch extends EFVideo {}
10
+
11
+ declare global {
12
+ interface HTMLElementTagNameMap {
13
+ "test-media-video-init-segment-fetch": TestMediaVideoInitSegmentFetch;
14
+ }
15
+ }
16
+
17
+ const test = baseTest.extend<{
18
+ element: TestMediaVideoInitSegmentFetch;
19
+ }>({
20
+ element: async ({}, use) => {
21
+ const element = document.createElement(
22
+ "test-media-video-init-segment-fetch",
23
+ );
24
+ await use(element);
25
+ element.remove();
26
+ },
27
+ });
28
+
29
+ describe("makeVideoInitSegmentFetchTask", () => {
30
+ beforeEach(() => {
31
+ // MSW setup is now handled by test fixtures
32
+ });
33
+
34
+ afterEach(() => {
35
+ const elements = document.querySelectorAll(
36
+ "test-media-video-init-segment-fetch",
37
+ );
38
+ for (const element of elements) {
39
+ element.remove();
40
+ }
41
+ vi.restoreAllMocks();
42
+ });
43
+
44
+ test("creates task with correct initial state", ({ element, expect }) => {
45
+ const task = makeVideoInitSegmentFetchTask(element);
46
+
47
+ expect(task).toBeDefined();
48
+ expect(task.status).toBe(TaskStatus.INITIAL);
49
+ expect(task.value).toBeUndefined();
50
+ expect(task.error).toBeUndefined();
51
+ });
52
+
53
+ test("task integrates with element properties", ({ element, expect }) => {
54
+ const task = makeVideoInitSegmentFetchTask(element);
55
+
56
+ expect(task).toBeDefined();
57
+ expect(task.status).toBe(TaskStatus.INITIAL);
58
+ });
59
+ });
@@ -0,0 +1,23 @@
1
+ import { Task } from "@lit/task";
2
+ import type { MediaEngine } from "../../../transcoding/types";
3
+ import type { EFVideo } from "../../EFVideo";
4
+ import { getLatestMediaEngine } from "../tasks/makeMediaEngineTask";
5
+
6
+ export const makeVideoInitSegmentFetchTask = (
7
+ host: EFVideo,
8
+ ): Task<readonly [MediaEngine | undefined], ArrayBuffer> => {
9
+ return new Task(host, {
10
+ args: () => [host.mediaEngineTask.value] as const,
11
+ onError: (error) => {
12
+ console.error("videoInitSegmentFetchTask error", error);
13
+ },
14
+ onComplete: (_value) => {},
15
+ task: async ([_mediaEngine], { signal }) => {
16
+ const mediaEngine = await getLatestMediaEngine(host, signal);
17
+ return mediaEngine.fetchInitSegment(
18
+ mediaEngine.getVideoRendition(),
19
+ signal,
20
+ );
21
+ },
22
+ });
23
+ };
@@ -0,0 +1,55 @@
1
+ import { TaskStatus } from "@lit/task";
2
+ import { customElement } from "lit/decorators.js";
3
+ import { afterEach, beforeEach, describe, vi } from "vitest";
4
+ import { test as baseTest } from "../../../../test/useMSW.js";
5
+ import { EFVideo } from "../../EFVideo";
6
+ import { makeVideoInputTask } from "./makeVideoInputTask";
7
+
8
+ @customElement("test-media-video-input")
9
+ class TestMediaVideoInput extends EFVideo {}
10
+
11
+ declare global {
12
+ interface HTMLElementTagNameMap {
13
+ "test-media-video-input": TestMediaVideoInput;
14
+ }
15
+ }
16
+
17
+ const test = baseTest.extend<{
18
+ element: TestMediaVideoInput;
19
+ }>({
20
+ element: async ({}, use) => {
21
+ const element = document.createElement("test-media-video-input");
22
+ await use(element);
23
+ element.remove();
24
+ },
25
+ });
26
+
27
+ describe("makeVideoInputTask", () => {
28
+ beforeEach(() => {
29
+ // MSW setup is now handled by test fixtures
30
+ });
31
+
32
+ afterEach(() => {
33
+ const elements = document.querySelectorAll("test-media-video-input");
34
+ for (const element of elements) {
35
+ element.remove();
36
+ }
37
+ vi.restoreAllMocks();
38
+ });
39
+
40
+ test("creates task with correct initial state", ({ element, expect }) => {
41
+ const task = makeVideoInputTask(element);
42
+
43
+ expect(task).toBeDefined();
44
+ expect(task.status).toBe(TaskStatus.INITIAL);
45
+ expect(task.value).toBeUndefined();
46
+ expect(task.error).toBeUndefined();
47
+ });
48
+
49
+ test("task integrates with element properties", ({ element, expect }) => {
50
+ const task = makeVideoInputTask(element);
51
+
52
+ expect(task).toBeDefined();
53
+ expect(task.status).toBe(TaskStatus.INITIAL);
54
+ });
55
+ });
@@ -0,0 +1,45 @@
1
+ import { Task } from "@lit/task";
2
+
3
+ import { EFMedia } from "../../EFMedia";
4
+ import type { EFVideo } from "../../EFVideo";
5
+ import { BufferedSeekingInput } from "../BufferedSeekingInput";
6
+ import type { InputTask } from "../shared/MediaTaskUtils";
7
+
8
+ export const makeVideoInputTask = (host: EFVideo): InputTask => {
9
+ return new Task<
10
+ readonly [ArrayBuffer | undefined, ArrayBuffer | undefined],
11
+ BufferedSeekingInput
12
+ >(host, {
13
+ args: () =>
14
+ [
15
+ host.videoInitSegmentFetchTask.value,
16
+ host.videoSegmentFetchTask.value,
17
+ ] as const,
18
+ onError: (error) => {
19
+ console.error("videoInputTask error", error);
20
+ },
21
+ onComplete: (_value) => {},
22
+ task: async () => {
23
+ const initSegment = await host.videoInitSegmentFetchTask.taskComplete;
24
+ const segment = await host.videoSegmentFetchTask.taskComplete;
25
+ if (!initSegment || !segment) {
26
+ throw new Error("Init segment or segment is not available");
27
+ }
28
+
29
+ // Get startTimeOffsetMs from the video rendition if available
30
+ const mediaEngine = await host.mediaEngineTask.taskComplete;
31
+ const videoRendition = mediaEngine?.videoRendition;
32
+ const startTimeOffsetMs = videoRendition?.startTimeOffsetMs;
33
+
34
+ const input = new BufferedSeekingInput(
35
+ await new Blob([initSegment, segment]).arrayBuffer(),
36
+ {
37
+ videoBufferSize: EFMedia.VIDEO_SAMPLE_BUFFER_SIZE,
38
+ audioBufferSize: EFMedia.AUDIO_SAMPLE_BUFFER_SIZE,
39
+ startTimeOffsetMs,
40
+ },
41
+ );
42
+ return input;
43
+ },
44
+ });
45
+ };
@@ -0,0 +1,44 @@
1
+ import { Task } from "@lit/task";
2
+
3
+ import type { VideoSample } from "mediabunny";
4
+ import { IgnorableError } from "../../EFMedia";
5
+ import type { EFVideo } from "../../EFVideo";
6
+ import type { BufferedSeekingInput } from "../BufferedSeekingInput";
7
+
8
+ type VideoSeekTask = Task<
9
+ readonly [number, BufferedSeekingInput | undefined],
10
+ VideoSample | undefined
11
+ >;
12
+ export const makeVideoSeekTask = (host: EFVideo): VideoSeekTask => {
13
+ return new Task(host, {
14
+ args: () => [host.desiredSeekTimeMs, host.videoInputTask.value] as const,
15
+ onError: (error) => {
16
+ if (error instanceof IgnorableError) {
17
+ console.info("videoSeekTask aborted");
18
+ }
19
+ console.error("videoSeekTask error", error);
20
+ },
21
+ onComplete: (_value) => {},
22
+ task: async (_): Promise<VideoSample | undefined> => {
23
+ await host.mediaEngineTask.taskComplete;
24
+ await host.videoSegmentIdTask.taskComplete;
25
+ await host.videoSegmentFetchTask.taskComplete;
26
+ await host.videoInitSegmentFetchTask.taskComplete;
27
+
28
+ const videoInput = await host.videoInputTask.taskComplete;
29
+ if (!videoInput) {
30
+ throw new Error("Video input is not available");
31
+ }
32
+ const videoTrack = await videoInput.getFirstVideoTrack();
33
+ if (!videoTrack) {
34
+ throw new Error("Video track is not available");
35
+ }
36
+ const sample = (await videoInput.seek(
37
+ videoTrack.id,
38
+ host.desiredSeekTimeMs,
39
+ )) as unknown as VideoSample;
40
+
41
+ return sample;
42
+ },
43
+ });
44
+ };
@@ -0,0 +1,57 @@
1
+ import { TaskStatus } from "@lit/task";
2
+ import { customElement } from "lit/decorators.js";
3
+ import { afterEach, beforeEach, describe, vi } from "vitest";
4
+ import { test as baseTest } from "../../../../test/useMSW.js";
5
+ import { EFVideo } from "../../EFVideo";
6
+ import { makeVideoSegmentFetchTask } from "./makeVideoSegmentFetchTask";
7
+
8
+ @customElement("test-media-video-segment-fetch")
9
+ class TestMediaVideoSegmentFetch extends EFVideo {}
10
+
11
+ declare global {
12
+ interface HTMLElementTagNameMap {
13
+ "test-media-video-segment-fetch": TestMediaVideoSegmentFetch;
14
+ }
15
+ }
16
+
17
+ const test = baseTest.extend<{
18
+ element: TestMediaVideoSegmentFetch;
19
+ }>({
20
+ element: async ({}, use) => {
21
+ const element = document.createElement("test-media-video-segment-fetch");
22
+ await use(element);
23
+ element.remove();
24
+ },
25
+ });
26
+
27
+ describe("makeVideoSegmentFetchTask", () => {
28
+ beforeEach(() => {
29
+ // MSW setup is now handled by test fixtures
30
+ });
31
+
32
+ afterEach(() => {
33
+ const elements = document.querySelectorAll(
34
+ "test-media-video-segment-fetch",
35
+ );
36
+ for (const element of elements) {
37
+ element.remove();
38
+ }
39
+ vi.restoreAllMocks();
40
+ });
41
+
42
+ test("creates task with correct initial state", ({ element, expect }) => {
43
+ const task = makeVideoSegmentFetchTask(element);
44
+
45
+ expect(task).toBeDefined();
46
+ expect(task.status).toBe(TaskStatus.INITIAL);
47
+ expect(task.value).toBeUndefined();
48
+ expect(task.error).toBeUndefined();
49
+ });
50
+
51
+ test("task integrates with element properties", ({ element, expect }) => {
52
+ const task = makeVideoSegmentFetchTask(element);
53
+
54
+ expect(task).toBeDefined();
55
+ expect(task.status).toBe(TaskStatus.INITIAL);
56
+ });
57
+ });
@@ -0,0 +1,32 @@
1
+ import { Task } from "@lit/task";
2
+ import type { MediaEngine } from "../../../transcoding/types";
3
+ import type { EFVideo } from "../../EFVideo";
4
+ import { getLatestMediaEngine } from "../tasks/makeMediaEngineTask";
5
+
6
+ export const makeVideoSegmentFetchTask = (
7
+ host: EFVideo,
8
+ ): Task<
9
+ readonly [MediaEngine | undefined, number | undefined],
10
+ ArrayBuffer
11
+ > => {
12
+ return new Task(host, {
13
+ args: () =>
14
+ [host.mediaEngineTask.value, host.videoSegmentIdTask.value] as const,
15
+ onError: (error) => {
16
+ console.error("videoSegmentFetchTask error", error);
17
+ },
18
+ onComplete: (_value) => {},
19
+ task: async (_, { signal }) => {
20
+ const mediaEngine = await getLatestMediaEngine(host, signal);
21
+ const segmentId = await host.videoSegmentIdTask.taskComplete;
22
+ if (segmentId === undefined) {
23
+ throw new Error("Segment ID is not available");
24
+ }
25
+ return mediaEngine.fetchMediaSegment(
26
+ segmentId,
27
+ mediaEngine.getVideoRendition(),
28
+ signal,
29
+ );
30
+ },
31
+ });
32
+ };
@@ -0,0 +1,56 @@
1
+ import { TaskStatus } from "@lit/task";
2
+ import { customElement } from "lit/decorators.js";
3
+ import { afterEach, beforeEach, describe, vi } from "vitest";
4
+ import { test as baseTest } from "../../../../test/useMSW.js";
5
+ import { EFVideo } from "../../EFVideo";
6
+ import { makeVideoSegmentIdTask } from "./makeVideoSegmentIdTask";
7
+
8
+ @customElement("test-media-video-segment")
9
+ class TestMediaVideoSegment extends EFVideo {}
10
+
11
+ declare global {
12
+ interface HTMLElementTagNameMap {
13
+ "test-media-video-segment": TestMediaVideoSegment;
14
+ }
15
+ }
16
+
17
+ const test = baseTest.extend<{
18
+ element: TestMediaVideoSegment;
19
+ }>({
20
+ element: async ({}, use) => {
21
+ const element = document.createElement("test-media-video-segment");
22
+ await use(element);
23
+ element.remove();
24
+ },
25
+ });
26
+
27
+ describe("makeVideoSegmentIdTask", () => {
28
+ beforeEach(() => {
29
+ // MSW setup is now handled by test fixtures
30
+ });
31
+
32
+ afterEach(() => {
33
+ const elements = document.querySelectorAll("test-media-video-segment");
34
+ for (const element of elements) {
35
+ element.remove();
36
+ }
37
+ vi.restoreAllMocks();
38
+ });
39
+
40
+ test("creates task with correct initial state", ({ element, expect }) => {
41
+ const task = makeVideoSegmentIdTask(element);
42
+
43
+ expect(task).toBeDefined();
44
+ expect(task.status).toBe(TaskStatus.INITIAL);
45
+ expect(task.value).toBeUndefined();
46
+ expect(task.error).toBeUndefined();
47
+ });
48
+
49
+ test("task integrates with element properties", ({ element, expect }) => {
50
+ element.desiredSeekTimeMs = 7500;
51
+
52
+ const task = makeVideoSegmentIdTask(element);
53
+ expect(task).toBeDefined();
54
+ expect(task.status).toBe(TaskStatus.INITIAL);
55
+ });
56
+ });
@@ -0,0 +1,23 @@
1
+ import { Task } from "@lit/task";
2
+ import type { MediaEngine } from "../../../transcoding/types";
3
+ import type { EFVideo } from "../../EFVideo";
4
+ import { getLatestMediaEngine } from "../tasks/makeMediaEngineTask";
5
+
6
+ export const makeVideoSegmentIdTask = (
7
+ host: EFVideo,
8
+ ): Task<readonly [MediaEngine | undefined, number], number | undefined> => {
9
+ return new Task(host, {
10
+ args: () => [host.mediaEngineTask.value, host.desiredSeekTimeMs] as const,
11
+ onError: (error) => {
12
+ console.error("videoSegmentIdTask error", error);
13
+ },
14
+ onComplete: (_value) => {},
15
+ task: async (_, { signal }) => {
16
+ const mediaEngine = await getLatestMediaEngine(host, signal);
17
+ return mediaEngine.computeSegmentId(
18
+ host.desiredSeekTimeMs,
19
+ mediaEngine.getVideoRendition(),
20
+ );
21
+ },
22
+ });
23
+ };