@editframe/elements 0.16.8-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/README.md +30 -0
- package/dist/DecoderResetFrequency.test.d.ts +1 -0
- package/dist/DecoderResetRecovery.test.d.ts +1 -0
- package/dist/DelayedLoadingState.d.ts +48 -0
- package/dist/DelayedLoadingState.integration.test.d.ts +1 -0
- package/dist/DelayedLoadingState.js +113 -0
- package/dist/DelayedLoadingState.test.d.ts +1 -0
- package/dist/EF_FRAMEGEN.d.ts +10 -1
- package/dist/EF_FRAMEGEN.js +199 -179
- package/dist/EF_INTERACTIVE.js +2 -6
- package/dist/EF_RENDERING.js +1 -3
- package/dist/LoadingDebounce.test.d.ts +1 -0
- package/dist/LoadingIndicator.browsertest.d.ts +0 -0
- package/dist/ManualScrubTest.test.d.ts +1 -0
- package/dist/ScrubResolvedFlashing.test.d.ts +1 -0
- package/dist/ScrubTrackManager.d.ts +96 -0
- package/dist/ScrubTrackManager.test.d.ts +1 -0
- package/dist/VideoSeekFlashing.browsertest.d.ts +0 -0
- package/dist/VideoStuckDiagnostic.test.d.ts +1 -0
- package/dist/elements/CrossUpdateController.js +13 -15
- package/dist/elements/EFAudio.browsertest.d.ts +0 -0
- package/dist/elements/EFAudio.d.ts +22 -3
- package/dist/elements/EFAudio.js +60 -43
- package/dist/elements/EFCaptions.js +337 -373
- package/dist/elements/EFImage.d.ts +1 -0
- package/dist/elements/EFImage.js +73 -91
- package/dist/elements/EFMedia/AssetIdMediaEngine.d.ts +18 -0
- package/dist/elements/EFMedia/AssetIdMediaEngine.js +41 -0
- package/dist/elements/EFMedia/AssetIdMediaEngine.test.d.ts +1 -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/BaseMediaEngine.test.d.ts +1 -0
- package/dist/elements/EFMedia/BufferedSeekingInput.browsertest.d.ts +1 -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.browsertest.d.ts +1 -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 +95 -66
- package/dist/elements/EFMedia.js +204 -683
- package/dist/elements/EFSourceMixin.js +31 -48
- package/dist/elements/EFTemporal.d.ts +2 -1
- package/dist/elements/EFTemporal.js +266 -360
- package/dist/elements/EFTimegroup.d.ts +14 -1
- package/dist/elements/EFTimegroup.js +337 -323
- package/dist/elements/EFVideo.browsertest.d.ts +0 -0
- package/dist/elements/EFVideo.d.ts +123 -4
- package/dist/elements/EFVideo.js +308 -111
- package/dist/elements/EFWaveform.js +375 -411
- package/dist/elements/FetchMixin.js +14 -24
- package/dist/elements/MediaController.d.ts +30 -0
- package/dist/elements/SampleBuffer.d.ts +14 -0
- package/dist/elements/SampleBuffer.js +52 -0
- package/dist/elements/TargetController.js +130 -156
- package/dist/elements/TimegroupController.js +17 -19
- package/dist/elements/durationConverter.js +15 -4
- package/dist/elements/parseTimeToMs.js +4 -10
- package/dist/elements/printTaskStatus.d.ts +2 -0
- package/dist/elements/updateAnimations.js +39 -59
- package/dist/getRenderInfo.d.ts +2 -2
- package/dist/getRenderInfo.js +59 -67
- package/dist/gui/ContextMixin.js +150 -288
- package/dist/gui/EFConfiguration.js +27 -43
- package/dist/gui/EFFilmstrip.d.ts +3 -3
- package/dist/gui/EFFilmstrip.js +440 -620
- package/dist/gui/EFFitScale.d.ts +2 -2
- package/dist/gui/EFFitScale.js +112 -135
- package/dist/gui/EFFocusOverlay.js +45 -61
- package/dist/gui/EFPreview.js +30 -49
- package/dist/gui/EFScrubber.js +78 -99
- package/dist/gui/EFTimeDisplay.js +49 -70
- package/dist/gui/EFToggleLoop.js +17 -34
- package/dist/gui/EFTogglePlay.js +37 -58
- package/dist/gui/EFWorkbench.js +66 -88
- package/dist/gui/TWMixin.js +2 -48
- package/dist/gui/TWMixin2.js +31 -0
- package/dist/gui/efContext.js +2 -6
- package/dist/gui/fetchContext.js +1 -3
- package/dist/gui/focusContext.js +1 -3
- package/dist/gui/focusedElementContext.js +2 -6
- package/dist/gui/playingContext.js +1 -4
- 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/index.js +5 -30
- package/dist/msToTimeCode.js +11 -13
- package/dist/services/MediaSourceManager.d.ts +62 -0
- package/dist/services/MediaSourceManager.js +211 -0
- package/dist/style.css +2 -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 +4 -3
- package/src/elements/EFAudio.browsertest.ts +709 -0
- package/src/elements/EFAudio.ts +59 -15
- package/src/elements/EFCaptions.browsertest.ts +0 -1
- package/src/elements/EFImage.browsertest.ts +42 -1
- 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 +696 -271
- package/src/elements/EFMedia.ts +218 -776
- package/src/elements/EFTemporal.browsertest.ts +0 -1
- package/src/elements/EFTemporal.ts +13 -3
- package/src/elements/EFTimegroup.browsertest.ts +6 -3
- package/src/elements/EFTimegroup.ts +221 -27
- package/src/elements/EFVideo.browsertest.ts +758 -0
- package/src/elements/EFVideo.ts +418 -68
- package/src/elements/EFWaveform.ts +5 -5
- package/src/elements/MediaController.ts +98 -0
- package/src/elements/SampleBuffer.ts +97 -0
- package/src/elements/printTaskStatus.ts +16 -0
- package/src/elements/updateAnimations.ts +6 -0
- package/src/gui/ContextMixin.ts +23 -104
- package/src/gui/TWMixin.ts +10 -3
- 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 +127 -0
- 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 +425 -0
- package/test/recordReplayProxyPlugin.js +302 -0
- package/test/useAssetMSW.ts +49 -0
- package/test/useMSW.ts +44 -0
- package/types.json +1 -1
- package/dist/gui/TWMixin.css.js +0 -4
- /package/dist/elements/{TargetController.test.d.ts → TargetController.browsertest.d.ts} +0 -0
- /package/src/elements/{TargetController.test.ts → TargetController.browsertest.ts} +0 -0
|
@@ -47,7 +47,6 @@ describe("sourcein and sourceout", () => {
|
|
|
47
47
|
const element = document.createElement("ten-seconds");
|
|
48
48
|
element.sourceInMs = 5_000;
|
|
49
49
|
element.sourceOutMs = 1_000;
|
|
50
|
-
console.log(element.sourceInMs, element.sourceOutMs, element.durationMs);
|
|
51
50
|
expect(element.durationMs).toBe(0);
|
|
52
51
|
});
|
|
53
52
|
});
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { consume, createContext } from "@lit/context";
|
|
2
|
+
import { Task } from "@lit/task";
|
|
2
3
|
import type { LitElement, PropertyValueMap, ReactiveController } from "lit";
|
|
3
4
|
import { property, state } from "lit/decorators.js";
|
|
4
|
-
import type { EFTimegroup } from "./EFTimegroup.js";
|
|
5
|
-
|
|
6
|
-
import { Task } from "@lit/task";
|
|
7
5
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
8
6
|
import { durationConverter } from "./durationConverter.js";
|
|
7
|
+
import type { EFTimegroup } from "./EFTimegroup.js";
|
|
9
8
|
|
|
10
9
|
export const timegroupContext = createContext<EFTimegroup>(
|
|
11
10
|
Symbol("timeGroupContext"),
|
|
@@ -292,6 +291,10 @@ const resetStartTimeMsCache = () => {
|
|
|
292
291
|
};
|
|
293
292
|
resetStartTimeMsCache();
|
|
294
293
|
|
|
294
|
+
export const flushStartTimeMsCache = () => {
|
|
295
|
+
startTimeMsCache = new WeakMap();
|
|
296
|
+
};
|
|
297
|
+
|
|
295
298
|
export const EFTemporal = <T extends Constructor<LitElement>>(
|
|
296
299
|
superClass: T,
|
|
297
300
|
) => {
|
|
@@ -536,12 +539,19 @@ export const EFTemporal = <T extends Constructor<LitElement>>(
|
|
|
536
539
|
const ownIndex = siblingTemorals?.indexOf(
|
|
537
540
|
this as InstanceType<Constructor<TemporalMixinInterface> & T>,
|
|
538
541
|
);
|
|
542
|
+
if (ownIndex === -1) {
|
|
543
|
+
return 0;
|
|
544
|
+
}
|
|
539
545
|
if (ownIndex === 0) {
|
|
540
546
|
startTimeMsCache.set(this, parentTimegroup.startTimeMs);
|
|
541
547
|
return parentTimegroup.startTimeMs;
|
|
542
548
|
}
|
|
543
549
|
const previous = siblingTemorals?.[(ownIndex ?? 0) - 1];
|
|
544
550
|
if (!previous) {
|
|
551
|
+
console.error("Previous temporal element not found", {
|
|
552
|
+
ownIndex,
|
|
553
|
+
siblingTemorals,
|
|
554
|
+
});
|
|
545
555
|
throw new Error("Previous temporal element not found");
|
|
546
556
|
}
|
|
547
557
|
startTimeMsCache.set(
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
LitElement,
|
|
3
|
-
type TemplateResult,
|
|
4
2
|
html,
|
|
3
|
+
LitElement,
|
|
5
4
|
render as litRender,
|
|
5
|
+
type TemplateResult,
|
|
6
6
|
} from "lit";
|
|
7
7
|
import { assert, beforeEach, describe, test } from "vitest";
|
|
8
8
|
import { EFTimegroup } from "./EFTimegroup.js";
|
|
@@ -353,7 +353,7 @@ describe("setting currentTime", () => {
|
|
|
353
353
|
document.body.appendChild(timegroup);
|
|
354
354
|
assert.isNull(localStorage.getItem(timegroup.storageKey));
|
|
355
355
|
timegroup.currentTime = 5_000;
|
|
356
|
-
assert.equal(localStorage.getItem(timegroup.storageKey), "
|
|
356
|
+
assert.equal(localStorage.getItem(timegroup.storageKey), "10"); // Clamped to duration
|
|
357
357
|
timegroup.remove();
|
|
358
358
|
});
|
|
359
359
|
|
|
@@ -392,6 +392,9 @@ describe("setting currentTime", () => {
|
|
|
392
392
|
assert.equal(a.ownCurrentTimeMs, 2_500);
|
|
393
393
|
assert.equal(b.ownCurrentTimeMs, 0);
|
|
394
394
|
|
|
395
|
+
// Wait for frame update to complete before next assignment
|
|
396
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
397
|
+
|
|
395
398
|
root.currentTimeMs = 7_500;
|
|
396
399
|
|
|
397
400
|
assert.equal(a.ownCurrentTimeMs, 5_000);
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { provide } from "@lit/context";
|
|
2
|
-
import { Task } from "@lit/task";
|
|
2
|
+
import { Task, TaskStatus } from "@lit/task";
|
|
3
3
|
import debug from "debug";
|
|
4
|
-
import { LitElement, type PropertyValueMap
|
|
4
|
+
import { css, html, LitElement, type PropertyValueMap } from "lit";
|
|
5
5
|
import { customElement, property } from "lit/decorators.js";
|
|
6
6
|
|
|
7
7
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
8
8
|
import { isContextMixin } from "../gui/ContextMixin.js";
|
|
9
|
+
import { durationConverter } from "./durationConverter.js";
|
|
9
10
|
import { deepGetMediaElements } from "./EFMedia.js";
|
|
10
11
|
import {
|
|
12
|
+
deepGetElementsWithFrameTasks,
|
|
11
13
|
EFTemporal,
|
|
14
|
+
flushStartTimeMsCache,
|
|
12
15
|
shallowGetTemporalElements,
|
|
13
16
|
timegroupContext,
|
|
14
17
|
} from "./EFTemporal.js";
|
|
15
18
|
import { TimegroupController } from "./TimegroupController.js";
|
|
16
|
-
import { durationConverter } from "./durationConverter.js";
|
|
17
19
|
import { updateAnimations } from "./updateAnimations.ts";
|
|
18
20
|
|
|
19
21
|
const log = debug("ef:elements:EFTimegroup");
|
|
@@ -50,6 +52,10 @@ export class EFTimegroup extends EFTemporal(LitElement) {
|
|
|
50
52
|
|
|
51
53
|
#currentTime = 0;
|
|
52
54
|
|
|
55
|
+
// Frame update locking mechanism (only for root timegroups)
|
|
56
|
+
private isFrameUpdateInProgress = false;
|
|
57
|
+
private queuedTimeUpdate: number | null = null;
|
|
58
|
+
|
|
53
59
|
@property({
|
|
54
60
|
type: String,
|
|
55
61
|
attribute: "mode",
|
|
@@ -70,27 +76,84 @@ export class EFTimegroup extends EFTemporal(LitElement) {
|
|
|
70
76
|
|
|
71
77
|
@property({ type: Number, attribute: "currenttime" })
|
|
72
78
|
set currentTime(time: number) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
79
|
+
const newTime = Math.max(0, Math.min(time, this.durationMs / 1000));
|
|
80
|
+
|
|
81
|
+
// Only apply locking mechanism for root timegroups to prevent cascade overload
|
|
82
|
+
if (this.isRootTimegroup && this.isFrameUpdateInProgress) {
|
|
83
|
+
// Queue the latest time update - only keep the most recent
|
|
84
|
+
this.queuedTimeUpdate = newTime;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (this.isRootTimegroup) {
|
|
89
|
+
this.#executeTimeUpdate(newTime);
|
|
90
|
+
} else {
|
|
91
|
+
// Non-root timegroups update immediately (no cascade risk)
|
|
92
|
+
this.#currentTime = newTime;
|
|
93
|
+
this.#saveTimeToLocalStorage(newTime);
|
|
82
94
|
}
|
|
83
95
|
}
|
|
96
|
+
|
|
84
97
|
get currentTime() {
|
|
85
98
|
return this.#currentTime;
|
|
86
99
|
}
|
|
100
|
+
|
|
87
101
|
get currentTimeMs() {
|
|
88
102
|
return this.currentTime * 1000;
|
|
89
103
|
}
|
|
104
|
+
|
|
90
105
|
set currentTimeMs(ms: number) {
|
|
91
106
|
this.currentTime = ms / 1000;
|
|
92
107
|
}
|
|
93
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Determines if this is a root timegroup (no parent timegroups)
|
|
111
|
+
*/
|
|
112
|
+
get isRootTimegroup(): boolean {
|
|
113
|
+
return this.closest("ef-timegroup") === this;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Executes time update with frame locking for root timegroups
|
|
118
|
+
*/
|
|
119
|
+
async #executeTimeUpdate(time: number) {
|
|
120
|
+
this.isFrameUpdateInProgress = true;
|
|
121
|
+
this.#currentTime = time;
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
// Save to localStorage
|
|
125
|
+
this.#saveTimeToLocalStorage(time);
|
|
126
|
+
|
|
127
|
+
// Wait for any pending frame tasks to complete before allowing next update
|
|
128
|
+
await this.waitForFrameTasks();
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.error("⚠️ [TIME_UPDATE_ERROR] Error during frame update:", error);
|
|
131
|
+
} finally {
|
|
132
|
+
this.isFrameUpdateInProgress = false;
|
|
133
|
+
|
|
134
|
+
// Process queued update if any (ensures latest scrub position is processed)
|
|
135
|
+
if (this.queuedTimeUpdate !== null && this.queuedTimeUpdate !== time) {
|
|
136
|
+
const nextTime = this.queuedTimeUpdate;
|
|
137
|
+
this.queuedTimeUpdate = null;
|
|
138
|
+
// Schedule on next tick to avoid recursive call stack
|
|
139
|
+
setTimeout(() => this.#executeTimeUpdate(nextTime), 0);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Saves time to localStorage (extracted for reuse)
|
|
146
|
+
*/
|
|
147
|
+
#saveTimeToLocalStorage(time: number) {
|
|
148
|
+
try {
|
|
149
|
+
if (this.id && this.isConnected) {
|
|
150
|
+
localStorage.setItem(this.storageKey, time.toString());
|
|
151
|
+
}
|
|
152
|
+
} catch (error) {
|
|
153
|
+
log("Failed to save time to localStorage", error);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
94
157
|
render() {
|
|
95
158
|
return html`<slot></slot> `;
|
|
96
159
|
}
|
|
@@ -110,7 +173,7 @@ export class EFTimegroup extends EFTemporal(LitElement) {
|
|
|
110
173
|
super.connectedCallback();
|
|
111
174
|
if (this.id) {
|
|
112
175
|
this.waitForMediaDurations().then(() => {
|
|
113
|
-
this
|
|
176
|
+
this.currentTime = this.maybeLoadTimeFromLocalStorage();
|
|
114
177
|
});
|
|
115
178
|
}
|
|
116
179
|
|
|
@@ -197,6 +260,30 @@ export class EFTimegroup extends EFTemporal(LitElement) {
|
|
|
197
260
|
}
|
|
198
261
|
}
|
|
199
262
|
|
|
263
|
+
async getPendingFrameTasks() {
|
|
264
|
+
await this.updateComplete;
|
|
265
|
+
const temporals = deepGetElementsWithFrameTasks(this);
|
|
266
|
+
return temporals
|
|
267
|
+
.map((temporal) => temporal.frameTask)
|
|
268
|
+
.filter((task) => task.status < TaskStatus.COMPLETE);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async waitForFrameTasks() {
|
|
272
|
+
const limit = 10;
|
|
273
|
+
let step = 0;
|
|
274
|
+
await this.updateComplete;
|
|
275
|
+
while (step < limit) {
|
|
276
|
+
step++;
|
|
277
|
+
let pendingTasks = await this.getPendingFrameTasks();
|
|
278
|
+
await Promise.all(pendingTasks.map((task) => task.taskComplete));
|
|
279
|
+
await this.updateComplete;
|
|
280
|
+
pendingTasks = await this.getPendingFrameTasks();
|
|
281
|
+
if (pendingTasks.length === 0) {
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
200
287
|
/**
|
|
201
288
|
* Wait for all media elements to load their initial segments.
|
|
202
289
|
* Ideally we would only need the extracted index json data, but
|
|
@@ -204,10 +291,30 @@ export class EFTimegroup extends EFTemporal(LitElement) {
|
|
|
204
291
|
* in calculations and it was not clear why.
|
|
205
292
|
*/
|
|
206
293
|
async waitForMediaDurations() {
|
|
294
|
+
// We must await updateComplete to ensure all media elements inside this are connected
|
|
295
|
+
// and will match deepGetMediaElements
|
|
296
|
+
await this.updateComplete;
|
|
207
297
|
const mediaElements = deepGetMediaElements(this);
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
);
|
|
298
|
+
// Then, we must await the fragmentIndexTask to ensure all media elements have their
|
|
299
|
+
// fragment index loaded, which is where their duration is parsed from.
|
|
300
|
+
await Promise.all(mediaElements.map((m) => m.mediaEngineTask.taskComplete));
|
|
301
|
+
|
|
302
|
+
// After waiting for durations, we must force some updates to cascade and ensure all temporal elements
|
|
303
|
+
// have correct durations and start times. It is not ideal that we have to do this inside here,
|
|
304
|
+
// but it is the best current way to ensure that all temporal elements have correct durations and start times.
|
|
305
|
+
|
|
306
|
+
// Next, we must flush the startTimeMs cache to ensure all media elements have their
|
|
307
|
+
// startTimeMs parsed fresh, otherwise the startTimeMs is cached per animation frame.
|
|
308
|
+
flushStartTimeMsCache();
|
|
309
|
+
|
|
310
|
+
// Request an update to the currentTime of this group, ensuring that time updates will cascade
|
|
311
|
+
// down to children, forcing sequence groups to arrange correctly.
|
|
312
|
+
// This also makes the filmstrip update correctly.
|
|
313
|
+
this.requestUpdate("currentTime");
|
|
314
|
+
// Finally, we must await updateComplete to ensure all temporal elements have their
|
|
315
|
+
// currentTime updated and all animations have run.
|
|
316
|
+
|
|
317
|
+
await this.updateComplete;
|
|
211
318
|
}
|
|
212
319
|
|
|
213
320
|
get childTemporals() {
|
|
@@ -290,16 +397,40 @@ export class EFTimegroup extends EFTemporal(LitElement) {
|
|
|
290
397
|
) {
|
|
291
398
|
await this.waitForMediaDurations();
|
|
292
399
|
|
|
400
|
+
// Create AbortController for audio fetch operations
|
|
401
|
+
const abortController = new AbortController();
|
|
402
|
+
|
|
293
403
|
await Promise.all(
|
|
294
404
|
deepGetMediaElements(this).map(async (mediaElement) => {
|
|
405
|
+
// Skip muted elements entirely - no audio fetching or processing needed
|
|
406
|
+
if (mediaElement.mute) {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
|
|
295
410
|
const mediaStartsBeforeEnd = mediaElement.startTimeMs <= toMs;
|
|
296
411
|
const mediaEndsAfterStart = mediaElement.endTimeMs >= fromMs;
|
|
297
412
|
const mediaOverlaps = mediaStartsBeforeEnd && mediaEndsAfterStart;
|
|
298
|
-
if (!mediaOverlaps
|
|
413
|
+
if (!mediaOverlaps) {
|
|
299
414
|
return;
|
|
300
415
|
}
|
|
301
416
|
|
|
302
|
-
|
|
417
|
+
// Convert from root timegroup timeline to media element's local timeline
|
|
418
|
+
const mediaLocalFromMs = Math.max(0, fromMs - mediaElement.startTimeMs);
|
|
419
|
+
const mediaLocalToMs = Math.min(
|
|
420
|
+
mediaElement.endTimeMs - mediaElement.startTimeMs,
|
|
421
|
+
toMs - mediaElement.startTimeMs,
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
// Skip if no valid local time range
|
|
425
|
+
if (mediaLocalFromMs >= mediaLocalToMs) {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const audio = await mediaElement.fetchAudioSpanningTime(
|
|
430
|
+
mediaLocalFromMs, // ✅ Now using media element's local timeline
|
|
431
|
+
mediaLocalToMs, // ✅ Now using media element's local timeline
|
|
432
|
+
abortController.signal,
|
|
433
|
+
);
|
|
303
434
|
if (!audio) {
|
|
304
435
|
throw new Error("Failed to fetch audio");
|
|
305
436
|
}
|
|
@@ -310,16 +441,25 @@ export class EFTimegroup extends EFTemporal(LitElement) {
|
|
|
310
441
|
);
|
|
311
442
|
bufferSource.connect(audioContext.destination);
|
|
312
443
|
|
|
444
|
+
// Calculate timing for placing this audio in the output context
|
|
313
445
|
const ctxStartMs = Math.max(0, mediaElement.startTimeMs - fromMs);
|
|
314
446
|
const ctxEndMs = mediaElement.endTimeMs - fromMs;
|
|
315
447
|
const ctxDurationMs = ctxEndMs - ctxStartMs;
|
|
316
448
|
|
|
317
|
-
|
|
318
|
-
|
|
449
|
+
// Calculate offset within the fetched audio buffer
|
|
450
|
+
// Since we now use local timeline coordinates, audio.startMs is relative to media start
|
|
451
|
+
const requestedOffsetInMedia = mediaLocalFromMs; // Already in local timeline
|
|
452
|
+
const actualOffsetInBuffer = requestedOffsetInMedia - audio.startMs; // Both in local timeline
|
|
453
|
+
|
|
454
|
+
// Ensure offset is never negative (this would cause audio scheduling errors)
|
|
455
|
+
const safeOffset = Math.max(0, actualOffsetInBuffer);
|
|
456
|
+
|
|
457
|
+
if (safeOffset !== actualOffsetInBuffer) {
|
|
458
|
+
}
|
|
319
459
|
|
|
320
460
|
bufferSource.start(
|
|
321
461
|
ctxStartMs / 1000,
|
|
322
|
-
|
|
462
|
+
safeOffset / 1000,
|
|
323
463
|
ctxDurationMs / 1000,
|
|
324
464
|
);
|
|
325
465
|
}),
|
|
@@ -327,14 +467,68 @@ export class EFTimegroup extends EFTemporal(LitElement) {
|
|
|
327
467
|
}
|
|
328
468
|
|
|
329
469
|
async renderAudio(fromMs: number, toMs: number) {
|
|
470
|
+
// Here we determine the number of samples we need to render rather than the duration.
|
|
471
|
+
// We cannot tolerate having more or fewer samples than fit exactlly into AAC frames.
|
|
330
472
|
const durationMs = toMs - fromMs;
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
473
|
+
const duration = durationMs / 1000;
|
|
474
|
+
const exactSamples = 48000 * duration;
|
|
475
|
+
const aacFrames = exactSamples / 1024;
|
|
476
|
+
const alignedFrames = Math.round(aacFrames);
|
|
477
|
+
const contextSize = alignedFrames * 1024; // AAC-aligned sample count
|
|
478
|
+
|
|
479
|
+
// Debug logging for audio duration calculations
|
|
480
|
+
if (contextSize <= 0) {
|
|
481
|
+
throw new Error(
|
|
482
|
+
`Duration must be greater than 0 when rendering audio. ${contextSize}ms`,
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
let audioContext: OfflineAudioContext;
|
|
487
|
+
try {
|
|
488
|
+
audioContext = new OfflineAudioContext(2, contextSize, 48000);
|
|
489
|
+
} catch (error) {
|
|
490
|
+
throw new Error(
|
|
491
|
+
`[EFTimegroup.renderAudio] Failed to create OfflineAudioContext(2, ${contextSize}, 48000) for renderAudio(${fromMs}, ${toMs}) with contextSize=${contextSize}: ${error instanceof Error ? error.message : String(error)}. This typically happens when audio parameters are invalid (e.g., contextSize <= 0).`,
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
|
|
336
495
|
await this.#addAudioToContext(audioContext, fromMs, toMs);
|
|
337
|
-
|
|
496
|
+
const renderedBuffer = await audioContext.startRendering();
|
|
497
|
+
|
|
498
|
+
return renderedBuffer;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* TEMPORARY TEST METHOD: Renders audio and immediately plays it back
|
|
503
|
+
* Usage: timegroup.testPlayAudio(0, 5000) // Play first 5 seconds
|
|
504
|
+
*/
|
|
505
|
+
async testPlayAudio(fromMs: number, toMs: number) {
|
|
506
|
+
try {
|
|
507
|
+
// Render the audio using the existing renderAudio method
|
|
508
|
+
const renderedBuffer = await this.renderAudio(fromMs, toMs);
|
|
509
|
+
|
|
510
|
+
// Create a regular AudioContext for playback
|
|
511
|
+
const playbackContext = new AudioContext();
|
|
512
|
+
|
|
513
|
+
// Create a buffer source and connect it
|
|
514
|
+
const bufferSource = playbackContext.createBufferSource();
|
|
515
|
+
bufferSource.buffer = renderedBuffer;
|
|
516
|
+
bufferSource.connect(playbackContext.destination);
|
|
517
|
+
|
|
518
|
+
// Start playback immediately
|
|
519
|
+
bufferSource.start(0);
|
|
520
|
+
|
|
521
|
+
// Return a promise that resolves when playback ends
|
|
522
|
+
return new Promise<void>((resolve) => {
|
|
523
|
+
bufferSource.onended = () => {
|
|
524
|
+
playbackContext.close();
|
|
525
|
+
resolve();
|
|
526
|
+
};
|
|
527
|
+
});
|
|
528
|
+
} catch (error) {
|
|
529
|
+
console.error("🎵 [TEST_PLAY_AUDIO] Error:", error);
|
|
530
|
+
throw error;
|
|
531
|
+
}
|
|
338
532
|
}
|
|
339
533
|
|
|
340
534
|
async loadMd5Sums() {
|