@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.
- package/dist/EF_FRAMEGEN.js +1 -1
- package/dist/ScrubTrackManager.d.ts +2 -2
- package/dist/elements/EFAudio.d.ts +21 -2
- package/dist/elements/EFAudio.js +41 -11
- package/dist/elements/EFImage.d.ts +1 -0
- package/dist/elements/EFImage.js +11 -3
- package/dist/elements/EFMedia/AssetIdMediaEngine.d.ts +18 -0
- package/dist/elements/EFMedia/AssetIdMediaEngine.js +41 -0
- package/dist/elements/EFMedia/AssetMediaEngine.d.ts +47 -0
- package/dist/elements/EFMedia/AssetMediaEngine.js +116 -0
- package/dist/elements/EFMedia/BaseMediaEngine.d.ts +55 -0
- package/dist/elements/EFMedia/BaseMediaEngine.js +96 -0
- package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +43 -0
- package/dist/elements/EFMedia/BufferedSeekingInput.js +159 -0
- package/dist/elements/EFMedia/JitMediaEngine.browsertest.d.ts +0 -0
- package/dist/elements/EFMedia/JitMediaEngine.d.ts +31 -0
- package/dist/elements/EFMedia/JitMediaEngine.js +62 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.d.ts +16 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +48 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.d.ts +3 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +138 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.d.ts +4 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +16 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.d.ts +3 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +22 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.d.ts +7 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +24 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.d.ts +4 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +18 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.d.ts +4 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +16 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.d.ts +3 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +104 -0
- package/dist/elements/EFMedia/services/AudioElementFactory.d.ts +22 -0
- package/dist/elements/EFMedia/services/AudioElementFactory.js +72 -0
- package/dist/elements/EFMedia/services/MediaSourceService.browsertest.d.ts +1 -0
- package/dist/elements/EFMedia/services/MediaSourceService.d.ts +47 -0
- package/dist/elements/EFMedia/services/MediaSourceService.js +73 -0
- package/dist/elements/EFMedia/shared/AudioSpanUtils.d.ts +7 -0
- package/dist/elements/EFMedia/shared/AudioSpanUtils.js +54 -0
- package/dist/elements/EFMedia/shared/BufferUtils.d.ts +70 -0
- package/dist/elements/EFMedia/shared/BufferUtils.js +89 -0
- package/dist/elements/EFMedia/shared/MediaTaskUtils.d.ts +23 -0
- package/dist/elements/EFMedia/shared/RenditionHelpers.browsertest.d.ts +1 -0
- package/dist/elements/EFMedia/shared/RenditionHelpers.d.ts +19 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.d.ts +1 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.d.ts +18 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +60 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.test.d.ts +1 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.d.ts +16 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +46 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.d.ts +4 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.js +16 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.d.ts +3 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.js +27 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSeekTask.d.ts +7 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSeekTask.js +25 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.d.ts +4 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.js +18 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.d.ts +4 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.js +16 -0
- package/dist/elements/EFMedia.browsertest.d.ts +1 -0
- package/dist/elements/EFMedia.d.ts +75 -111
- package/dist/elements/EFMedia.js +141 -1111
- package/dist/elements/EFTemporal.d.ts +1 -1
- package/dist/elements/EFTemporal.js +1 -1
- package/dist/elements/EFTimegroup.d.ts +11 -0
- package/dist/elements/EFTimegroup.js +88 -13
- package/dist/elements/EFVideo.d.ts +60 -29
- package/dist/elements/EFVideo.js +103 -203
- package/dist/elements/EFWaveform.js +2 -2
- package/dist/elements/SampleBuffer.d.ts +14 -0
- package/dist/elements/SampleBuffer.js +52 -0
- package/dist/getRenderInfo.d.ts +2 -2
- package/dist/getRenderInfo.js +2 -1
- package/dist/gui/ContextMixin.js +17 -70
- package/dist/gui/EFFilmstrip.d.ts +3 -3
- package/dist/gui/EFFilmstrip.js +1 -1
- package/dist/gui/EFFitScale.d.ts +2 -2
- package/dist/gui/TWMixin.js +1 -1
- package/dist/gui/services/ElementConnectionManager.browsertest.d.ts +1 -0
- package/dist/gui/services/ElementConnectionManager.d.ts +59 -0
- package/dist/gui/services/ElementConnectionManager.js +128 -0
- package/dist/gui/services/PlaybackController.browsertest.d.ts +1 -0
- package/dist/gui/services/PlaybackController.d.ts +103 -0
- package/dist/gui/services/PlaybackController.js +290 -0
- package/dist/services/MediaSourceManager.d.ts +62 -0
- package/dist/services/MediaSourceManager.js +211 -0
- package/dist/style.css +1 -1
- package/dist/transcoding/cache/CacheManager.d.ts +73 -0
- package/dist/transcoding/cache/RequestDeduplicator.d.ts +29 -0
- package/dist/transcoding/cache/RequestDeduplicator.js +53 -0
- package/dist/transcoding/cache/RequestDeduplicator.test.d.ts +1 -0
- package/dist/transcoding/types/index.d.ts +242 -0
- package/dist/transcoding/utils/MediaUtils.d.ts +9 -0
- package/dist/transcoding/utils/UrlGenerator.d.ts +26 -0
- package/dist/transcoding/utils/UrlGenerator.js +45 -0
- package/dist/transcoding/utils/constants.d.ts +27 -0
- package/dist/utils/LRUCache.d.ts +34 -0
- package/dist/utils/LRUCache.js +115 -0
- package/package.json +3 -2
- package/src/elements/EFAudio.browsertest.ts +183 -43
- package/src/elements/EFAudio.ts +59 -13
- package/src/elements/EFImage.browsertest.ts +42 -0
- package/src/elements/EFImage.ts +23 -3
- package/src/elements/EFMedia/AssetIdMediaEngine.test.ts +222 -0
- package/src/elements/EFMedia/AssetIdMediaEngine.ts +70 -0
- package/src/elements/EFMedia/AssetMediaEngine.ts +210 -0
- package/src/elements/EFMedia/BaseMediaEngine.test.ts +164 -0
- package/src/elements/EFMedia/BaseMediaEngine.ts +170 -0
- package/src/elements/EFMedia/BufferedSeekingInput.browsertest.ts +400 -0
- package/src/elements/EFMedia/BufferedSeekingInput.ts +267 -0
- package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +165 -0
- package/src/elements/EFMedia/JitMediaEngine.ts +110 -0
- package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.ts +554 -0
- package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.ts +81 -0
- package/src/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.ts +241 -0
- package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.ts +59 -0
- package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.ts +23 -0
- package/src/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.ts +55 -0
- package/src/elements/EFMedia/audioTasks/makeAudioInputTask.ts +35 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.ts +42 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.ts +34 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.ts +23 -0
- package/src/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.ts +174 -0
- package/src/elements/EFMedia/services/AudioElementFactory.browsertest.ts +325 -0
- package/src/elements/EFMedia/services/AudioElementFactory.ts +119 -0
- package/src/elements/EFMedia/services/MediaSourceService.browsertest.ts +257 -0
- package/src/elements/EFMedia/services/MediaSourceService.ts +102 -0
- package/src/elements/EFMedia/shared/AudioSpanUtils.ts +128 -0
- package/src/elements/EFMedia/shared/BufferUtils.ts +310 -0
- package/src/elements/EFMedia/shared/MediaTaskUtils.ts +44 -0
- package/src/elements/EFMedia/shared/RenditionHelpers.browsertest.ts +247 -0
- package/src/elements/EFMedia/shared/RenditionHelpers.ts +79 -0
- package/src/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.ts +128 -0
- package/src/elements/EFMedia/tasks/makeMediaEngineTask.test.ts +233 -0
- package/src/elements/EFMedia/tasks/makeMediaEngineTask.ts +89 -0
- package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.browsertest.ts +555 -0
- package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.ts +79 -0
- package/src/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.browsertest.ts +59 -0
- package/src/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.ts +23 -0
- package/src/elements/EFMedia/videoTasks/makeVideoInputTask.browsertest.ts +55 -0
- package/src/elements/EFMedia/videoTasks/makeVideoInputTask.ts +45 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSeekTask.ts +44 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.ts +57 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.ts +32 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.ts +56 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.ts +23 -0
- package/src/elements/EFMedia.browsertest.ts +658 -265
- package/src/elements/EFMedia.ts +173 -1763
- package/src/elements/EFTemporal.ts +3 -4
- package/src/elements/EFTimegroup.browsertest.ts +6 -3
- package/src/elements/EFTimegroup.ts +152 -21
- package/src/elements/EFVideo.browsertest.ts +115 -37
- package/src/elements/EFVideo.ts +123 -452
- package/src/elements/EFWaveform.ts +1 -1
- package/src/elements/MediaController.ts +2 -12
- package/src/elements/SampleBuffer.ts +97 -0
- package/src/gui/ContextMixin.ts +23 -104
- package/src/gui/services/ElementConnectionManager.browsertest.ts +263 -0
- package/src/gui/services/ElementConnectionManager.ts +224 -0
- package/src/gui/services/PlaybackController.browsertest.ts +437 -0
- package/src/gui/services/PlaybackController.ts +521 -0
- package/src/services/MediaSourceManager.ts +333 -0
- package/src/transcoding/cache/CacheManager.ts +208 -0
- package/src/transcoding/cache/RequestDeduplicator.test.ts +170 -0
- package/src/transcoding/cache/RequestDeduplicator.ts +65 -0
- package/src/transcoding/types/index.ts +265 -0
- package/src/transcoding/utils/MediaUtils.ts +63 -0
- package/src/transcoding/utils/UrlGenerator.ts +68 -0
- package/src/transcoding/utils/constants.ts +36 -0
- package/src/utils/LRUCache.ts +153 -0
- package/test/EFVideo.framegen.browsertest.ts +38 -29
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/test/__cache__/GET__api_v1_transcode_manifest_json_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__3be92a0437de726b431ed5af2369158a/data.bin +1 -0
- package/test/__cache__/GET__api_v1_transcode_manifest_json_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__3be92a0437de726b431ed5af2369158a/metadata.json +19 -0
- package/test/createJitTestClips.ts +320 -188
- package/test/recordReplayProxyPlugin.js +302 -0
- package/test/useAssetMSW.ts +1 -1
- package/test/useMSW.ts +35 -22
- package/types.json +1 -1
- package/dist/JitTranscodingClient.d.ts +0 -167
- package/dist/JitTranscodingClient.js +0 -373
- package/dist/ScrubTrackManager.js +0 -216
- package/dist/elements/printTaskStatus.js +0 -11
- package/src/elements/__screenshots__/EFMedia.browsertest.ts/EFMedia-JIT-audio-playback-audioBufferTask-should-work-in-JIT-mode-without-URL-errors-1.png +0 -0
- package/test/EFVideo.frame-tasks.browsertest.ts +0 -524
- /package/dist/{JitTranscodingClient.browsertest.d.ts → elements/EFMedia/AssetIdMediaEngine.test.d.ts} +0 -0
- /package/dist/{JitTranscodingClient.test.d.ts → elements/EFMedia/BaseMediaEngine.test.d.ts} +0 -0
- /package/dist/{ScrubTrackIntegration.test.d.ts → elements/EFMedia/BufferedSeekingInput.browsertest.d.ts} +0 -0
- /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
|
+
};
|