@editframe/elements 0.17.6-beta.0 → 0.18.7-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/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.browsertest.d.ts +0 -0
- package/dist/elements/EFMedia/AssetMediaEngine.d.ts +45 -0
- package/dist/elements/EFMedia/AssetMediaEngine.js +135 -0
- package/dist/elements/EFMedia/BaseMediaEngine.d.ts +55 -0
- package/dist/elements/EFMedia/BaseMediaEngine.js +115 -0
- package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +43 -0
- package/dist/elements/EFMedia/BufferedSeekingInput.js +179 -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 +81 -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 +141 -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 +30 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.d.ts +0 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.d.ts +7 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +32 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.d.ts +4 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +28 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.d.ts +4 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +17 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.d.ts +3 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +107 -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/PrecisionUtils.d.ts +28 -0
- package/dist/elements/EFMedia/shared/PrecisionUtils.js +29 -0
- package/dist/elements/EFMedia/shared/RenditionHelpers.d.ts +19 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.d.ts +18 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +60 -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 +34 -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 +28 -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 +17 -0
- package/dist/elements/EFMedia.browsertest.d.ts +1 -0
- package/dist/elements/EFMedia.d.ts +63 -111
- package/dist/elements/EFMedia.js +117 -1113
- 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 +83 -13
- package/dist/elements/EFVideo.d.ts +54 -32
- package/dist/elements/EFVideo.js +100 -207
- 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.js +2 -1
- package/dist/gui/ContextMixin.js +3 -2
- 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/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 -3
- package/src/elements/EFAudio.browsertest.ts +189 -49
- 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.browsertest.ts +100 -0
- package/src/elements/EFMedia/AssetMediaEngine.ts +255 -0
- package/src/elements/EFMedia/BaseMediaEngine.test.ts +164 -0
- package/src/elements/EFMedia/BaseMediaEngine.ts +219 -0
- package/src/elements/EFMedia/BufferedSeekingInput.browsertest.ts +481 -0
- package/src/elements/EFMedia/BufferedSeekingInput.ts +324 -0
- package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +165 -0
- package/src/elements/EFMedia/JitMediaEngine.ts +166 -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 +250 -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 +43 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.ts +199 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.ts +64 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.ts +45 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.ts +24 -0
- package/src/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.ts +183 -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/PrecisionUtils.ts +46 -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 +68 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.ts +57 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.ts +43 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.ts +56 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.ts +24 -0
- package/src/elements/EFMedia.browsertest.ts +706 -273
- package/src/elements/EFMedia.ts +136 -1769
- package/src/elements/EFTemporal.ts +3 -4
- package/src/elements/EFTimegroup.browsertest.ts +6 -3
- package/src/elements/EFTimegroup.ts +147 -21
- package/src/elements/EFVideo.browsertest.ts +980 -169
- package/src/elements/EFVideo.ts +113 -458
- package/src/elements/EFWaveform.ts +1 -1
- package/src/elements/MediaController.ts +2 -12
- package/src/elements/SampleBuffer.ts +95 -0
- package/src/gui/ContextMixin.ts +3 -6
- 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 +269 -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 +39 -30
- 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_1_mp4_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4_bytes_0__9ed2d25c675aa6bb6ff5b3ae23887c71/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_audio_1_mp4_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4_bytes_0__9ed2d25c675aa6bb6ff5b3ae23887c71/metadata.json +22 -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_2_mp4_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4_bytes_0__d5a3309a2bf756dd6e304807eb402f56/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_audio_2_mp4_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4_bytes_0__d5a3309a2bf756dd6e304807eb402f56/metadata.json +22 -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_3_mp4_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4_bytes_0__773254bb671e3466fca8677139fb239e/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_audio_3_mp4_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4_bytes_0__773254bb671e3466fca8677139fb239e/metadata.json +22 -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_4_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a6fb05a22b18d850f7f2950bbcdbdeed/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_high_4_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a6fb05a22b18d850f7f2950bbcdbdeed/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_high_5_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a50058c7c3602e90879fe3428ed891f4/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_high_5_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a50058c7c3602e90879fe3428ed891f4/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 +352 -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.d.ts +0 -96
- 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/{DecoderResetFrequency.test.d.ts → elements/EFMedia/AssetIdMediaEngine.test.d.ts} +0 -0
- /package/dist/{DecoderResetRecovery.test.d.ts → elements/EFMedia/BaseMediaEngine.test.d.ts} +0 -0
- /package/dist/{JitTranscodingClient.browsertest.d.ts → elements/EFMedia/BufferedSeekingInput.browsertest.d.ts} +0 -0
- /package/dist/{JitTranscodingClient.test.d.ts → elements/EFMedia/shared/RenditionHelpers.browsertest.d.ts} +0 -0
- /package/dist/{ScrubTrackIntegration.test.d.ts → elements/EFMedia/tasks/makeMediaEngineTask.browsertest.d.ts} +0 -0
- /package/dist/{SegmentSwitchLoading.test.d.ts → elements/EFMedia/tasks/makeMediaEngineTask.test.d.ts} +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AudioRendition,
|
|
3
|
+
MediaEngine,
|
|
4
|
+
VideoRendition,
|
|
5
|
+
} from "../../../transcoding/types";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Get audio rendition from media engine, throwing if not available
|
|
9
|
+
*/
|
|
10
|
+
export const getAudioRendition = (mediaEngine: MediaEngine): AudioRendition => {
|
|
11
|
+
const audioRendition = mediaEngine.audioRendition;
|
|
12
|
+
if (!audioRendition) {
|
|
13
|
+
throw new Error("Audio rendition is not available");
|
|
14
|
+
}
|
|
15
|
+
return audioRendition;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get video rendition from media engine, throwing if not available
|
|
20
|
+
*/
|
|
21
|
+
export const getVideoRendition = (mediaEngine: MediaEngine): VideoRendition => {
|
|
22
|
+
const videoRendition = mediaEngine.videoRendition;
|
|
23
|
+
if (!videoRendition) {
|
|
24
|
+
throw new Error("Video rendition is not available");
|
|
25
|
+
}
|
|
26
|
+
return videoRendition;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Calculate which segment contains a given timestamp
|
|
31
|
+
* Returns 1-based segment ID, or undefined if segmentDurationMs is not available
|
|
32
|
+
*/
|
|
33
|
+
export const computeSegmentId = (
|
|
34
|
+
timeMs: number,
|
|
35
|
+
rendition: AudioRendition | VideoRendition,
|
|
36
|
+
): number | undefined => {
|
|
37
|
+
if (!rendition.segmentDurationMs) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Handle negative time by clamping to 0
|
|
42
|
+
const adjustedTimeMs = Math.max(0, timeMs);
|
|
43
|
+
const segmentIndex = Math.floor(adjustedTimeMs / rendition.segmentDurationMs);
|
|
44
|
+
return segmentIndex + 1; // Convert to 1-based segment ID
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Calculate range of segment IDs that overlap with a time range
|
|
49
|
+
* Returns array of 1-based segment IDs, or empty array if segmentDurationMs is not available
|
|
50
|
+
*/
|
|
51
|
+
export const calculateSegmentRange = (
|
|
52
|
+
startTimeMs: number,
|
|
53
|
+
endTimeMs: number,
|
|
54
|
+
rendition: AudioRendition | VideoRendition,
|
|
55
|
+
): number[] => {
|
|
56
|
+
if (!rendition.segmentDurationMs) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Handle edge case where start equals end
|
|
61
|
+
if (startTimeMs === endTimeMs) {
|
|
62
|
+
const segmentId = computeSegmentId(startTimeMs, rendition);
|
|
63
|
+
return segmentId ? [segmentId] : [];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const startSegmentId = computeSegmentId(startTimeMs, rendition);
|
|
67
|
+
const endSegmentId = computeSegmentId(endTimeMs, rendition);
|
|
68
|
+
|
|
69
|
+
if (startSegmentId === undefined || endSegmentId === undefined) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const segments: number[] = [];
|
|
74
|
+
for (let segmentId = startSegmentId; segmentId <= endSegmentId; segmentId++) {
|
|
75
|
+
segments.push(segmentId);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return segments;
|
|
79
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { test as baseTest, describe, vi } from "vitest";
|
|
2
|
+
import type { UrlGenerator } from "../../../transcoding/utils/UrlGenerator";
|
|
3
|
+
import {
|
|
4
|
+
createMediaEngine,
|
|
5
|
+
handleMediaEngineComplete,
|
|
6
|
+
} from "./makeMediaEngineTask";
|
|
7
|
+
|
|
8
|
+
// Define test fixtures using test.extend
|
|
9
|
+
const test = baseTest.extend<{
|
|
10
|
+
mockUrlGenerator: UrlGenerator;
|
|
11
|
+
mockHost: any;
|
|
12
|
+
mockTimegroup: any;
|
|
13
|
+
}>({
|
|
14
|
+
mockUrlGenerator: async ({}, use) => {
|
|
15
|
+
const mockUrlGenerator = {
|
|
16
|
+
generateManifestUrl: vi
|
|
17
|
+
.fn()
|
|
18
|
+
.mockReturnValue("https://example.com/manifest.m3u8"),
|
|
19
|
+
} as any;
|
|
20
|
+
await use(mockUrlGenerator);
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
mockTimegroup: async ({}, use) => {
|
|
24
|
+
const mockTimegroup = {
|
|
25
|
+
currentTimeMs: 0,
|
|
26
|
+
requestUpdate: vi.fn(),
|
|
27
|
+
};
|
|
28
|
+
await use(mockTimegroup);
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
mockHost: async ({ mockTimegroup, mockUrlGenerator }, use) => {
|
|
32
|
+
const mockHost = {
|
|
33
|
+
src: "https://example.com/video.mp4",
|
|
34
|
+
assetId: null,
|
|
35
|
+
urlGenerator: mockUrlGenerator,
|
|
36
|
+
apiHost: "https://api.example.com",
|
|
37
|
+
requestUpdate: vi.fn(),
|
|
38
|
+
rootTimegroup: mockTimegroup,
|
|
39
|
+
};
|
|
40
|
+
await use(mockHost);
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe("createMediaEngine", () => {
|
|
45
|
+
describe("input validation", () => {
|
|
46
|
+
test("should reject when assetId provided but apiHost is missing", async ({
|
|
47
|
+
mockHost,
|
|
48
|
+
expect,
|
|
49
|
+
}) => {
|
|
50
|
+
// Set up host with assetId but no apiHost
|
|
51
|
+
mockHost.src = "test.mp4";
|
|
52
|
+
mockHost.assetId = "asset123";
|
|
53
|
+
mockHost.apiHost = null;
|
|
54
|
+
|
|
55
|
+
await expect(createMediaEngine(mockHost)).rejects.toThrow(
|
|
56
|
+
"API host is required for AssetID mode",
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("should reject with empty src", async ({ mockHost, expect }) => {
|
|
61
|
+
// Set up host with empty src
|
|
62
|
+
mockHost.src = "";
|
|
63
|
+
mockHost.assetId = null;
|
|
64
|
+
|
|
65
|
+
await expect(createMediaEngine(mockHost)).rejects.toThrow(
|
|
66
|
+
"Unsupported media source",
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("should reject with null src", async ({ mockHost, expect }) => {
|
|
71
|
+
// Set up host with null src
|
|
72
|
+
mockHost.src = null;
|
|
73
|
+
mockHost.assetId = null;
|
|
74
|
+
|
|
75
|
+
await expect(createMediaEngine(mockHost)).rejects.toThrow(
|
|
76
|
+
"Unsupported media source",
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("should reject with whitespace-only src", async ({
|
|
81
|
+
mockHost,
|
|
82
|
+
expect,
|
|
83
|
+
}) => {
|
|
84
|
+
// Set up host with whitespace-only src
|
|
85
|
+
mockHost.src = " \t\n ";
|
|
86
|
+
mockHost.assetId = null;
|
|
87
|
+
|
|
88
|
+
await expect(createMediaEngine(mockHost)).rejects.toThrow(
|
|
89
|
+
"Unsupported media source",
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("handleMediaEngineComplete", () => {
|
|
96
|
+
test("should call requestUpdate on host", async ({ mockHost, expect }) => {
|
|
97
|
+
handleMediaEngineComplete(mockHost);
|
|
98
|
+
|
|
99
|
+
expect(mockHost.requestUpdate).toHaveBeenCalledWith("intrinsicDurationMs");
|
|
100
|
+
expect(mockHost.requestUpdate).toHaveBeenCalledWith("ownCurrentTimeMs");
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test("should call requestUpdate on rootTimegroup when present", async ({
|
|
104
|
+
mockHost,
|
|
105
|
+
mockTimegroup,
|
|
106
|
+
expect,
|
|
107
|
+
}) => {
|
|
108
|
+
handleMediaEngineComplete(mockHost);
|
|
109
|
+
|
|
110
|
+
expect(mockTimegroup.requestUpdate).toHaveBeenCalledWith(
|
|
111
|
+
"ownCurrentTimeMs",
|
|
112
|
+
);
|
|
113
|
+
expect(mockTimegroup.requestUpdate).toHaveBeenCalledWith("durationMs");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test("should handle missing rootTimegroup gracefully", async ({
|
|
117
|
+
mockHost,
|
|
118
|
+
expect,
|
|
119
|
+
}) => {
|
|
120
|
+
mockHost.rootTimegroup = null;
|
|
121
|
+
|
|
122
|
+
// Should not throw
|
|
123
|
+
handleMediaEngineComplete(mockHost);
|
|
124
|
+
|
|
125
|
+
expect(mockHost.requestUpdate).toHaveBeenCalledWith("intrinsicDurationMs");
|
|
126
|
+
expect(mockHost.requestUpdate).toHaveBeenCalledWith("ownCurrentTimeMs");
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import type { EFMedia } from "../../EFMedia";
|
|
3
|
+
import { AssetIdMediaEngine } from "../AssetIdMediaEngine";
|
|
4
|
+
import { AssetMediaEngine } from "../AssetMediaEngine";
|
|
5
|
+
import { JitMediaEngine } from "../JitMediaEngine";
|
|
6
|
+
import { createMediaEngine } from "./makeMediaEngineTask";
|
|
7
|
+
|
|
8
|
+
// Mock the engine classes
|
|
9
|
+
vi.mock("../AssetIdMediaEngine", () => ({
|
|
10
|
+
AssetIdMediaEngine: {
|
|
11
|
+
fetchByAssetId: vi.fn(),
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
vi.mock("../AssetMediaEngine");
|
|
15
|
+
vi.mock("../JitMediaEngine");
|
|
16
|
+
|
|
17
|
+
describe("makeMediaEngineTask", () => {
|
|
18
|
+
const mockUrlGenerator = {
|
|
19
|
+
generateManifestUrl: vi.fn(),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const createMockHost = (overrides: Partial<EFMedia> = {}): EFMedia =>
|
|
23
|
+
({
|
|
24
|
+
src: "",
|
|
25
|
+
assetId: null,
|
|
26
|
+
apiHost: "https://api.example.com",
|
|
27
|
+
urlGenerator: mockUrlGenerator,
|
|
28
|
+
...overrides,
|
|
29
|
+
}) as EFMedia;
|
|
30
|
+
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
vi.clearAllMocks();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("createMediaEngine", () => {
|
|
36
|
+
it("should use AssetIdMediaEngine when assetId is provided", async () => {
|
|
37
|
+
const mockEngine = { durationMs: 15000 };
|
|
38
|
+
vi.mocked(AssetIdMediaEngine.fetchByAssetId).mockResolvedValue(
|
|
39
|
+
mockEngine as any,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const host = createMockHost({
|
|
43
|
+
assetId: "test-asset-123",
|
|
44
|
+
apiHost: "https://api.example.com",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const result = await createMediaEngine(host);
|
|
48
|
+
|
|
49
|
+
expect(AssetIdMediaEngine.fetchByAssetId).toHaveBeenCalledWith(
|
|
50
|
+
host,
|
|
51
|
+
mockUrlGenerator,
|
|
52
|
+
"test-asset-123",
|
|
53
|
+
"https://api.example.com",
|
|
54
|
+
);
|
|
55
|
+
expect(result).toBe(mockEngine);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("should throw error when assetId is provided but apiHost is missing", async () => {
|
|
59
|
+
const host = createMockHost({
|
|
60
|
+
assetId: "test-asset-123",
|
|
61
|
+
apiHost: undefined,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
await expect(createMediaEngine(host)).rejects.toThrow(
|
|
65
|
+
"API host is required for AssetID mode",
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should ignore empty assetId and use src instead", async () => {
|
|
70
|
+
const mockEngine = { durationMs: 15000 };
|
|
71
|
+
vi.mocked(AssetMediaEngine.fetch).mockResolvedValue(mockEngine as any);
|
|
72
|
+
|
|
73
|
+
const host = createMockHost({
|
|
74
|
+
assetId: "",
|
|
75
|
+
src: "/path/to/asset",
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const result = await createMediaEngine(host);
|
|
79
|
+
|
|
80
|
+
expect(AssetMediaEngine.fetch).toHaveBeenCalledWith(
|
|
81
|
+
host,
|
|
82
|
+
mockUrlGenerator,
|
|
83
|
+
"/path/to/asset",
|
|
84
|
+
);
|
|
85
|
+
expect(AssetIdMediaEngine.fetchByAssetId).not.toHaveBeenCalled();
|
|
86
|
+
expect(result).toBe(mockEngine);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("should ignore whitespace-only assetId and use src instead", async () => {
|
|
90
|
+
const mockEngine = { durationMs: 15000 };
|
|
91
|
+
vi.mocked(AssetMediaEngine.fetch).mockResolvedValue(mockEngine as any);
|
|
92
|
+
|
|
93
|
+
const host = createMockHost({
|
|
94
|
+
assetId: " ",
|
|
95
|
+
src: "/path/to/asset",
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const result = await createMediaEngine(host);
|
|
99
|
+
|
|
100
|
+
expect(AssetMediaEngine.fetch).toHaveBeenCalledWith(
|
|
101
|
+
host,
|
|
102
|
+
mockUrlGenerator,
|
|
103
|
+
"/path/to/asset",
|
|
104
|
+
);
|
|
105
|
+
expect(AssetIdMediaEngine.fetchByAssetId).not.toHaveBeenCalled();
|
|
106
|
+
expect(result).toBe(mockEngine);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("should use JitMediaEngine for HTTP URLs", async () => {
|
|
110
|
+
const mockEngine = { durationMs: 15000 };
|
|
111
|
+
const manifestUrl = "https://api.example.com/manifest.json";
|
|
112
|
+
|
|
113
|
+
vi.mocked(mockUrlGenerator.generateManifestUrl).mockReturnValue(
|
|
114
|
+
manifestUrl,
|
|
115
|
+
);
|
|
116
|
+
vi.mocked(JitMediaEngine.fetch).mockResolvedValue(mockEngine as any);
|
|
117
|
+
|
|
118
|
+
const host = createMockHost({
|
|
119
|
+
src: "https://example.com/video.mp4",
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const result = await createMediaEngine(host);
|
|
123
|
+
|
|
124
|
+
expect(mockUrlGenerator.generateManifestUrl).toHaveBeenCalledWith(
|
|
125
|
+
"https://example.com/video.mp4",
|
|
126
|
+
);
|
|
127
|
+
expect(JitMediaEngine.fetch).toHaveBeenCalledWith(
|
|
128
|
+
host,
|
|
129
|
+
mockUrlGenerator,
|
|
130
|
+
manifestUrl,
|
|
131
|
+
);
|
|
132
|
+
expect(result).toBe(mockEngine);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("should use JitMediaEngine for HTTPS URLs", async () => {
|
|
136
|
+
const mockEngine = { durationMs: 15000 };
|
|
137
|
+
const manifestUrl = "https://api.example.com/manifest.json";
|
|
138
|
+
|
|
139
|
+
vi.mocked(mockUrlGenerator.generateManifestUrl).mockReturnValue(
|
|
140
|
+
manifestUrl,
|
|
141
|
+
);
|
|
142
|
+
vi.mocked(JitMediaEngine.fetch).mockResolvedValue(mockEngine as any);
|
|
143
|
+
|
|
144
|
+
const host = createMockHost({
|
|
145
|
+
src: "https://example.com/video.mp4",
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const result = await createMediaEngine(host);
|
|
149
|
+
|
|
150
|
+
expect(JitMediaEngine.fetch).toHaveBeenCalledWith(
|
|
151
|
+
host,
|
|
152
|
+
mockUrlGenerator,
|
|
153
|
+
manifestUrl,
|
|
154
|
+
);
|
|
155
|
+
expect(result).toBe(mockEngine);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("should use AssetMediaEngine for local paths", async () => {
|
|
159
|
+
const mockEngine = { durationMs: 15000 };
|
|
160
|
+
vi.mocked(AssetMediaEngine.fetch).mockResolvedValue(mockEngine as any);
|
|
161
|
+
|
|
162
|
+
const host = createMockHost({
|
|
163
|
+
src: "/local/asset.mp4",
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const result = await createMediaEngine(host);
|
|
167
|
+
|
|
168
|
+
expect(AssetMediaEngine.fetch).toHaveBeenCalledWith(
|
|
169
|
+
host,
|
|
170
|
+
mockUrlGenerator,
|
|
171
|
+
"/local/asset.mp4",
|
|
172
|
+
);
|
|
173
|
+
expect(result).toBe(mockEngine);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("should throw error for empty src when no assetId", async () => {
|
|
177
|
+
const host = createMockHost({
|
|
178
|
+
src: "",
|
|
179
|
+
assetId: null,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
await expect(createMediaEngine(host)).rejects.toThrow(
|
|
183
|
+
"Unsupported media source",
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it("should throw error for whitespace-only src when no assetId", async () => {
|
|
188
|
+
const host = createMockHost({
|
|
189
|
+
src: " ",
|
|
190
|
+
assetId: null,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
await expect(createMediaEngine(host)).rejects.toThrow(
|
|
194
|
+
"Unsupported media source",
|
|
195
|
+
);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it("should throw error for null src when no assetId", async () => {
|
|
199
|
+
const host = createMockHost({
|
|
200
|
+
src: null as any,
|
|
201
|
+
assetId: null,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
await expect(createMediaEngine(host)).rejects.toThrow(
|
|
205
|
+
"Unsupported media source",
|
|
206
|
+
);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it("should prioritize assetId over src when both are provided", async () => {
|
|
210
|
+
const mockEngine = { durationMs: 15000 };
|
|
211
|
+
vi.mocked(AssetIdMediaEngine.fetchByAssetId).mockResolvedValue(
|
|
212
|
+
mockEngine as any,
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
const host = createMockHost({
|
|
216
|
+
assetId: "test-asset-123",
|
|
217
|
+
src: "/local/asset.mp4",
|
|
218
|
+
apiHost: "https://api.example.com",
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const result = await createMediaEngine(host);
|
|
222
|
+
|
|
223
|
+
expect(AssetIdMediaEngine.fetchByAssetId).toHaveBeenCalledWith(
|
|
224
|
+
host,
|
|
225
|
+
mockUrlGenerator,
|
|
226
|
+
"test-asset-123",
|
|
227
|
+
"https://api.example.com",
|
|
228
|
+
);
|
|
229
|
+
expect(AssetMediaEngine.fetch).not.toHaveBeenCalled();
|
|
230
|
+
expect(result).toBe(mockEngine);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Task } from "@lit/task";
|
|
2
|
+
import { EF_INTERACTIVE } from "../../../EF_INTERACTIVE";
|
|
3
|
+
import type { MediaEngine, VideoRendition } from "../../../transcoding/types";
|
|
4
|
+
import type { EFMedia } from "../../EFMedia";
|
|
5
|
+
import { AssetIdMediaEngine } from "../AssetIdMediaEngine";
|
|
6
|
+
import { AssetMediaEngine } from "../AssetMediaEngine";
|
|
7
|
+
import { JitMediaEngine } from "../JitMediaEngine";
|
|
8
|
+
|
|
9
|
+
export const getLatestMediaEngine = async (
|
|
10
|
+
host: EFMedia,
|
|
11
|
+
signal: AbortSignal,
|
|
12
|
+
): Promise<MediaEngine> => {
|
|
13
|
+
const mediaEngine = await host.mediaEngineTask.taskComplete;
|
|
14
|
+
signal.throwIfAborted();
|
|
15
|
+
if (!mediaEngine) {
|
|
16
|
+
throw new Error("Media engine is not available");
|
|
17
|
+
}
|
|
18
|
+
return mediaEngine;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const getVideoRendition = (mediaEngine: MediaEngine): VideoRendition => {
|
|
22
|
+
const videoRendition = mediaEngine.videoRendition;
|
|
23
|
+
if (!videoRendition) {
|
|
24
|
+
throw new Error("Video rendition is not available");
|
|
25
|
+
}
|
|
26
|
+
return videoRendition;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Core logic for creating a MediaEngine with explicit dependencies.
|
|
31
|
+
* Pure function that requires all dependencies to be provided.
|
|
32
|
+
*/
|
|
33
|
+
export const createMediaEngine = (host: EFMedia): Promise<MediaEngine> => {
|
|
34
|
+
const { src, assetId, urlGenerator, apiHost } = host;
|
|
35
|
+
|
|
36
|
+
// Check for AssetID mode first
|
|
37
|
+
if (assetId !== null && assetId !== undefined && assetId.trim() !== "") {
|
|
38
|
+
if (!apiHost) {
|
|
39
|
+
return Promise.reject(new Error("API host is required for AssetID mode"));
|
|
40
|
+
}
|
|
41
|
+
return AssetIdMediaEngine.fetchByAssetId(
|
|
42
|
+
host,
|
|
43
|
+
urlGenerator,
|
|
44
|
+
assetId,
|
|
45
|
+
apiHost,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Check for null/undefined/empty/whitespace src
|
|
50
|
+
if (!src || typeof src !== "string" || src.trim() === "") {
|
|
51
|
+
console.error(`Unsupported media source: ${src}, assetId: ${assetId}`);
|
|
52
|
+
return Promise.reject(new Error("Unsupported media source"));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Check for HTTP/HTTPS URLs (exactly "http://" or "https://")
|
|
56
|
+
const lowerSrc = src.toLowerCase();
|
|
57
|
+
if (lowerSrc.startsWith("http://") || lowerSrc.startsWith("https://")) {
|
|
58
|
+
const url = urlGenerator.generateManifestUrl(src);
|
|
59
|
+
return JitMediaEngine.fetch(host, urlGenerator, url);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return AssetMediaEngine.fetch(host, urlGenerator, src);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Handle completion of media engine task - triggers necessary updates.
|
|
67
|
+
* Extracted for testability.
|
|
68
|
+
*/
|
|
69
|
+
export const handleMediaEngineComplete = (host: EFMedia): void => {
|
|
70
|
+
host.requestUpdate("intrinsicDurationMs");
|
|
71
|
+
host.requestUpdate("ownCurrentTimeMs");
|
|
72
|
+
host.rootTimegroup?.requestUpdate("ownCurrentTimeMs");
|
|
73
|
+
host.rootTimegroup?.requestUpdate("durationMs");
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
type MediaEngineTask = Task<readonly [string, string | null], MediaEngine>;
|
|
77
|
+
|
|
78
|
+
export const makeMediaEngineTask = (host: EFMedia): MediaEngineTask => {
|
|
79
|
+
return new Task(host, {
|
|
80
|
+
autoRun: EF_INTERACTIVE,
|
|
81
|
+
args: () => [host.src, host.assetId] as const,
|
|
82
|
+
task: async () => {
|
|
83
|
+
return createMediaEngine(host);
|
|
84
|
+
},
|
|
85
|
+
onComplete: (_value) => {
|
|
86
|
+
handleMediaEngineComplete(host);
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
};
|