@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
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export interface MediaSourceManagerOptions {
|
|
2
|
+
onError?: (error: Error) => void;
|
|
3
|
+
onReady?: () => void;
|
|
4
|
+
onUpdateEnd?: () => void;
|
|
5
|
+
timeout?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Manages MediaSource for audio streaming
|
|
9
|
+
*/
|
|
10
|
+
export declare class MediaSourceManager {
|
|
11
|
+
private mediaSource;
|
|
12
|
+
private audioElement;
|
|
13
|
+
private sourceBuffer;
|
|
14
|
+
private mediaSourceReady;
|
|
15
|
+
private pendingSegments;
|
|
16
|
+
private options;
|
|
17
|
+
constructor(options?: MediaSourceManagerOptions);
|
|
18
|
+
/**
|
|
19
|
+
* Initialize MediaSource for audio streaming
|
|
20
|
+
*/
|
|
21
|
+
initialize(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Create SourceBuffer with codec fallback
|
|
24
|
+
*/
|
|
25
|
+
private createSourceBuffer;
|
|
26
|
+
/**
|
|
27
|
+
* Setup SourceBuffer event listeners
|
|
28
|
+
*/
|
|
29
|
+
private setupSourceBufferListeners;
|
|
30
|
+
/**
|
|
31
|
+
* Feed audio segments directly to MediaSource SourceBuffer
|
|
32
|
+
*/
|
|
33
|
+
feedSegment(segmentBuffer: ArrayBuffer): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Process any queued segments when SourceBuffer becomes available
|
|
36
|
+
*/
|
|
37
|
+
private processPendingSegments;
|
|
38
|
+
/**
|
|
39
|
+
* Log debug information for troubleshooting
|
|
40
|
+
*/
|
|
41
|
+
private logDebugInfo;
|
|
42
|
+
/**
|
|
43
|
+
* Set audio element current time
|
|
44
|
+
*/
|
|
45
|
+
setCurrentTime(timeMs: number): void;
|
|
46
|
+
/**
|
|
47
|
+
* Get the audio element for MediaElementSource
|
|
48
|
+
*/
|
|
49
|
+
getAudioElement(): HTMLAudioElement | null;
|
|
50
|
+
/**
|
|
51
|
+
* Check if MediaSource is ready
|
|
52
|
+
*/
|
|
53
|
+
isReady(): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Get buffered time ranges
|
|
56
|
+
*/
|
|
57
|
+
getBuffered(): TimeRanges | null;
|
|
58
|
+
/**
|
|
59
|
+
* Clean up MediaSource resources
|
|
60
|
+
*/
|
|
61
|
+
cleanup(_preserveCache?: boolean): void;
|
|
62
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages MediaSource for audio streaming
|
|
3
|
+
*/
|
|
4
|
+
var MediaSourceManager = class {
|
|
5
|
+
constructor(options = {}) {
|
|
6
|
+
this.mediaSource = null;
|
|
7
|
+
this.audioElement = null;
|
|
8
|
+
this.sourceBuffer = null;
|
|
9
|
+
this.mediaSourceReady = false;
|
|
10
|
+
this.pendingSegments = [];
|
|
11
|
+
this.options = {
|
|
12
|
+
timeout: 1e4,
|
|
13
|
+
...options
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Initialize MediaSource for audio streaming
|
|
18
|
+
*/
|
|
19
|
+
async initialize() {
|
|
20
|
+
this.cleanup(true);
|
|
21
|
+
this.mediaSource = new MediaSource();
|
|
22
|
+
this.audioElement = document.createElement("audio");
|
|
23
|
+
this.audioElement.addEventListener("error", (event) => {
|
|
24
|
+
const error = this.audioElement?.error;
|
|
25
|
+
console.error("🎵 [AUDIO_ELEMENT_ERROR] Audio element error:", {
|
|
26
|
+
code: error?.code,
|
|
27
|
+
message: error?.message,
|
|
28
|
+
event
|
|
29
|
+
});
|
|
30
|
+
if (this.options.onError) this.options.onError(/* @__PURE__ */ new Error(`Audio element error: ${error?.message}`));
|
|
31
|
+
});
|
|
32
|
+
this.audioElement.src = URL.createObjectURL(this.mediaSource);
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
this.mediaSource?.addEventListener("sourceopen", () => {
|
|
35
|
+
try {
|
|
36
|
+
const sourceBuffer = this.createSourceBuffer();
|
|
37
|
+
if (!sourceBuffer) throw new Error("Failed to create SourceBuffer with any supported codec");
|
|
38
|
+
this.sourceBuffer = sourceBuffer;
|
|
39
|
+
this.setupSourceBufferListeners();
|
|
40
|
+
this.mediaSourceReady = true;
|
|
41
|
+
if (this.options.onReady) this.options.onReady();
|
|
42
|
+
resolve();
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error("🎵 [MEDIA_SOURCE_ERROR] Failed to create SourceBuffer:", error);
|
|
45
|
+
reject(error);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
this.mediaSource?.addEventListener("error", (error) => {
|
|
49
|
+
console.error("🎵 [MEDIA_SOURCE_ERROR] MediaSource error:", error);
|
|
50
|
+
reject(error);
|
|
51
|
+
});
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
if (!this.mediaSourceReady) {
|
|
54
|
+
const timeoutError = /* @__PURE__ */ new Error("MediaSource failed to open within timeout");
|
|
55
|
+
console.error("🎵 [MEDIA_SOURCE_TIMEOUT] MediaSource initialization timeout");
|
|
56
|
+
reject(timeoutError);
|
|
57
|
+
}
|
|
58
|
+
}, 4e3);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Create SourceBuffer with codec fallback
|
|
63
|
+
*/
|
|
64
|
+
createSourceBuffer() {
|
|
65
|
+
const codecOptions = [
|
|
66
|
+
"audio/mp4; codecs=\"mp4a.40.2\"",
|
|
67
|
+
"audio/mp4; codecs=\"mp4a.40.5\"",
|
|
68
|
+
"audio/mp4"
|
|
69
|
+
];
|
|
70
|
+
let sourceBuffer;
|
|
71
|
+
let lastError;
|
|
72
|
+
for (const codec of codecOptions) try {
|
|
73
|
+
if (MediaSource.isTypeSupported(codec)) {
|
|
74
|
+
sourceBuffer = this.mediaSource?.addSourceBuffer(codec);
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error(`🎵 [CODEC_ERROR] Failed to create SourceBuffer with ${codec}:`, error);
|
|
79
|
+
lastError = error;
|
|
80
|
+
}
|
|
81
|
+
if (!sourceBuffer && lastError) throw new Error(`Failed to create SourceBuffer with any supported codec. Last error: ${lastError.message}`);
|
|
82
|
+
return sourceBuffer;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Setup SourceBuffer event listeners
|
|
86
|
+
*/
|
|
87
|
+
setupSourceBufferListeners() {
|
|
88
|
+
if (!this.sourceBuffer) return;
|
|
89
|
+
this.sourceBuffer.addEventListener("updateend", () => {
|
|
90
|
+
this.processPendingSegments();
|
|
91
|
+
if (this.options.onUpdateEnd) this.options.onUpdateEnd();
|
|
92
|
+
});
|
|
93
|
+
this.sourceBuffer.addEventListener("error", (event) => {
|
|
94
|
+
console.error("🎵 [SOURCE_BUFFER_EVENT_ERROR] SourceBuffer error event:", event);
|
|
95
|
+
if (this.options.onError) this.options.onError(/* @__PURE__ */ new Error("SourceBuffer error"));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Feed audio segments directly to MediaSource SourceBuffer
|
|
100
|
+
*/
|
|
101
|
+
async feedSegment(segmentBuffer) {
|
|
102
|
+
if (!this.mediaSourceReady || !this.sourceBuffer) {
|
|
103
|
+
this.pendingSegments.push(segmentBuffer);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (this.sourceBuffer.updating) {
|
|
107
|
+
this.pendingSegments.push(segmentBuffer);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (this.audioElement?.error) {
|
|
111
|
+
const error = this.audioElement.error;
|
|
112
|
+
console.error("🎵 [MEDIA_ELEMENT_ERROR] HTMLMediaElement error detected:", {
|
|
113
|
+
code: error.code,
|
|
114
|
+
message: error.message,
|
|
115
|
+
MEDIA_ERR_ABORTED: error.code === MediaError.MEDIA_ERR_ABORTED,
|
|
116
|
+
MEDIA_ERR_NETWORK: error.code === MediaError.MEDIA_ERR_NETWORK,
|
|
117
|
+
MEDIA_ERR_DECODE: error.code === MediaError.MEDIA_ERR_DECODE,
|
|
118
|
+
MEDIA_ERR_SRC_NOT_SUPPORTED: error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED
|
|
119
|
+
});
|
|
120
|
+
this.audioElement.load();
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
this.sourceBuffer.appendBuffer(segmentBuffer);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error("🎵 [SOURCE_BUFFER_ERROR] Failed to append segment:", error);
|
|
127
|
+
this.logDebugInfo();
|
|
128
|
+
this.pendingSegments.push(segmentBuffer);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Process any queued segments when SourceBuffer becomes available
|
|
133
|
+
*/
|
|
134
|
+
processPendingSegments() {
|
|
135
|
+
if (!this.sourceBuffer || this.sourceBuffer.updating || this.pendingSegments.length === 0) return;
|
|
136
|
+
const nextSegment = this.pendingSegments.shift();
|
|
137
|
+
if (nextSegment) this.feedSegment(nextSegment);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Log debug information for troubleshooting
|
|
141
|
+
*/
|
|
142
|
+
logDebugInfo() {
|
|
143
|
+
console.error("🎵 [SOURCE_BUFFER_DEBUG] SourceBuffer state:", {
|
|
144
|
+
updating: this.sourceBuffer?.updating,
|
|
145
|
+
buffered: this.sourceBuffer?.buffered ? Array.from({ length: this.sourceBuffer.buffered.length }, (_, i) => `${this.sourceBuffer?.buffered.start(i)}-${this.sourceBuffer?.buffered.end(i)}`) : [],
|
|
146
|
+
mode: this.sourceBuffer?.mode,
|
|
147
|
+
timestampOffset: this.sourceBuffer?.timestampOffset
|
|
148
|
+
});
|
|
149
|
+
console.error("🎵 [MEDIA_SOURCE_DEBUG] MediaSource state:", {
|
|
150
|
+
readyState: this.mediaSource?.readyState,
|
|
151
|
+
sourceBuffers: this.mediaSource?.sourceBuffers.length,
|
|
152
|
+
duration: this.mediaSource?.duration
|
|
153
|
+
});
|
|
154
|
+
console.error("🎵 [AUDIO_ELEMENT_DEBUG] Audio element state:", {
|
|
155
|
+
readyState: this.audioElement?.readyState,
|
|
156
|
+
networkState: this.audioElement?.networkState,
|
|
157
|
+
error: this.audioElement?.error?.code,
|
|
158
|
+
src: `${this.audioElement?.src.substring(0, 50)}...`
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Set audio element current time
|
|
163
|
+
*/
|
|
164
|
+
setCurrentTime(timeMs) {
|
|
165
|
+
if (this.audioElement) this.audioElement.currentTime = timeMs / 1e3;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get the audio element for MediaElementSource
|
|
169
|
+
*/
|
|
170
|
+
getAudioElement() {
|
|
171
|
+
return this.audioElement;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Check if MediaSource is ready
|
|
175
|
+
*/
|
|
176
|
+
isReady() {
|
|
177
|
+
return this.mediaSourceReady;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get buffered time ranges
|
|
181
|
+
*/
|
|
182
|
+
getBuffered() {
|
|
183
|
+
return this.sourceBuffer?.buffered || null;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Clean up MediaSource resources
|
|
187
|
+
*/
|
|
188
|
+
cleanup(_preserveCache = false) {
|
|
189
|
+
if (this.sourceBuffer && this.mediaSource && this.mediaSource.readyState === "open") try {
|
|
190
|
+
this.mediaSource.removeSourceBuffer(this.sourceBuffer);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
console.warn("🎵 [CLEANUP_ERROR] Error removing SourceBuffer:", error);
|
|
193
|
+
}
|
|
194
|
+
if (this.mediaSource) try {
|
|
195
|
+
if (this.mediaSource.readyState === "open") this.mediaSource.endOfStream();
|
|
196
|
+
} catch (error) {
|
|
197
|
+
console.warn("🎵 [CLEANUP_ERROR] Error ending MediaSource:", error);
|
|
198
|
+
}
|
|
199
|
+
if (this.audioElement) try {
|
|
200
|
+
URL.revokeObjectURL(this.audioElement.src);
|
|
201
|
+
} catch (error) {
|
|
202
|
+
console.warn("🎵 [CLEANUP_ERROR] Error revoking URL:", error);
|
|
203
|
+
}
|
|
204
|
+
this.mediaSource = null;
|
|
205
|
+
this.audioElement = null;
|
|
206
|
+
this.sourceBuffer = null;
|
|
207
|
+
this.mediaSourceReady = false;
|
|
208
|
+
this.pendingSegments = [];
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
export { MediaSourceManager };
|
package/dist/style.css
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
*,:before,:after{box-sizing:border-box;border
|
|
1
|
+
*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:before,:after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.top-0{top:0}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.col-span-2{grid-column:span 2/span 2}.mx-2{margin-left:.5rem;margin-right:.5rem}.mb-\[1px\]{margin-bottom:1px}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-\[1\.1rem\]{height:1.1rem}.h-\[270px\]{height:270px}.h-\[5px\]{height:5px}.h-full{height:100%}.w-1{width:.25rem}.w-\[2px\]{width:2px}.w-\[480px\]{width:480px}.w-full{width:100%}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.cursor-crosshair{cursor:crosshair}.resize{resize:both}.flex-wrap{flex-wrap:wrap}.place-content-center{place-content:center}.items-center{align-items:center}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.text-nowrap{text-wrap:nowrap}.rounded{border-radius:.25rem}.border{border-width:1px}.border-r-2{border-right-width:2px}.border-blue-500{--tw-border-opacity:1;border-color:rgb(59 130 246/var(--tw-border-opacity))}.border-red-700{--tw-border-opacity:1;border-color:rgb(185 28 28/var(--tw-border-opacity))}.border-slate-500{--tw-border-opacity:1;border-color:rgb(100 116 139/var(--tw-border-opacity))}.border-b-slate-600{--tw-border-opacity:1;border-bottom-color:rgb(71 85 105/var(--tw-border-opacity))}.bg-blue-200{--tw-bg-opacity:1;background-color:rgb(191 219 254/var(--tw-bg-opacity))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.bg-slate-300{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity))}.bg-slate-800{--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity))}.bg-opacity-20{--tw-bg-opacity:.2}.p-\[1px\]{padding:1px}.pb-0{padding-bottom:0}.pl-1{padding-left:.25rem}.pl-2{padding-left:.5rem}.pr-0{padding-right:0}.pr-1{padding-right:.25rem}.pt-\[8px\]{padding-top:8px}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-5xl{font-size:3rem;line-height:1}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.line-through{text-decoration-line:line-through}.opacity-50{opacity:.5}.shadow{--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-slate-300{--tw-shadow-color:#cbd5e1;--tw-shadow:var(--tw-shadow-colored)}.shadow-slate-600{--tw-shadow-color:#475569;--tw-shadow:var(--tw-shadow-colored)}.outline{outline-style:solid}.blur{--tw-blur:blur(8px);filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.filter{filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur)var(--tw-backdrop-brightness)var(--tw-backdrop-contrast)var(--tw-backdrop-grayscale)var(--tw-backdrop-hue-rotate)var(--tw-backdrop-invert)var(--tw-backdrop-opacity)var(--tw-backdrop-saturate)var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur)var(--tw-backdrop-brightness)var(--tw-backdrop-contrast)var(--tw-backdrop-grayscale)var(--tw-backdrop-hue-rotate)var(--tw-backdrop-invert)var(--tw-backdrop-opacity)var(--tw-backdrop-saturate)var(--tw-backdrop-sepia)}.hover\:bg-slate-400:hover{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity))}.peer:hover~.peer-hover\:border-slate-400{--tw-border-opacity:1;border-color:rgb(148 163 184/var(--tw-border-opacity))}.peer:hover~.peer-hover\:bg-slate-300{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity))}.data-\[focused\]\:bg-slate-400[data-focused]{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity))}.peer[data-focused]~.peer-data-\[focused\]\:border-slate-400{--tw-border-opacity:1;border-color:rgb(148 163 184/var(--tw-border-opacity))}.peer[data-focused]~.peer-data-\[focused\]\:bg-slate-300{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity))}
|
|
2
|
+
/*$vite$:1*/
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { CacheStats, ManifestResponse, VideoMetadata } from '../types/index.js';
|
|
2
|
+
export declare class CacheManager {
|
|
3
|
+
private maxSize;
|
|
4
|
+
private segmentCache;
|
|
5
|
+
private metadataCache;
|
|
6
|
+
private manifestCache;
|
|
7
|
+
private initSegmentCache;
|
|
8
|
+
private cacheAccessOrder;
|
|
9
|
+
private cacheHits;
|
|
10
|
+
private cacheMisses;
|
|
11
|
+
private totalRequests;
|
|
12
|
+
constructor(maxSize: number);
|
|
13
|
+
/**
|
|
14
|
+
* Cache a segment with LRU eviction
|
|
15
|
+
*/
|
|
16
|
+
cacheSegment(cacheKey: string, buffer: ArrayBuffer): void;
|
|
17
|
+
/**
|
|
18
|
+
* Get a segment from cache
|
|
19
|
+
*/
|
|
20
|
+
getSegment(cacheKey: string): ArrayBuffer | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a segment exists in cache
|
|
23
|
+
*/
|
|
24
|
+
hasSegment(cacheKey: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Cache metadata
|
|
27
|
+
*/
|
|
28
|
+
cacheMetadata(url: string, metadata: VideoMetadata): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get metadata from cache
|
|
31
|
+
*/
|
|
32
|
+
getMetadata(url: string): VideoMetadata | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Cache manifest
|
|
35
|
+
*/
|
|
36
|
+
cacheManifest(url: string, manifest: ManifestResponse): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get manifest from cache
|
|
39
|
+
*/
|
|
40
|
+
getManifest(url: string): ManifestResponse | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Cache init segment
|
|
43
|
+
*/
|
|
44
|
+
cacheInitSegment(cacheKey: string, buffer: ArrayBuffer): void;
|
|
45
|
+
/**
|
|
46
|
+
* Get init segment from cache
|
|
47
|
+
*/
|
|
48
|
+
getInitSegment(cacheKey: string): ArrayBuffer | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Get comprehensive cache statistics
|
|
51
|
+
*/
|
|
52
|
+
getCacheStats(): CacheStats;
|
|
53
|
+
/**
|
|
54
|
+
* Clear all caches
|
|
55
|
+
*/
|
|
56
|
+
clearAll(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Get cache sizes for each cache type
|
|
59
|
+
*/
|
|
60
|
+
getCacheSizes(): {
|
|
61
|
+
segments: number;
|
|
62
|
+
metadata: number;
|
|
63
|
+
manifests: number;
|
|
64
|
+
initSegments: number;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Clear specific cache type
|
|
68
|
+
*/
|
|
69
|
+
clearSegmentCache(): void;
|
|
70
|
+
clearMetadataCache(): void;
|
|
71
|
+
clearManifestCache(): void;
|
|
72
|
+
clearInitSegmentCache(): void;
|
|
73
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request deduplication utility
|
|
3
|
+
* Manages pending requests to prevent concurrent duplicate requests
|
|
4
|
+
*/
|
|
5
|
+
export declare class RequestDeduplicator {
|
|
6
|
+
private pendingRequests;
|
|
7
|
+
/**
|
|
8
|
+
* Execute a request with deduplication
|
|
9
|
+
* If a request with the same key is already pending, return the existing promise
|
|
10
|
+
* Otherwise, execute the request factory and track the promise
|
|
11
|
+
*/
|
|
12
|
+
executeRequest<T>(key: string, requestFactory: () => Promise<T>): Promise<T>;
|
|
13
|
+
/**
|
|
14
|
+
* Clear all pending requests (used in cache clearing)
|
|
15
|
+
*/
|
|
16
|
+
clear(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Get number of pending requests
|
|
19
|
+
*/
|
|
20
|
+
getPendingCount(): number;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a request is pending
|
|
23
|
+
*/
|
|
24
|
+
isPending(key: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Get all pending request keys
|
|
27
|
+
*/
|
|
28
|
+
getPendingKeys(): string[];
|
|
29
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request deduplication utility
|
|
3
|
+
* Manages pending requests to prevent concurrent duplicate requests
|
|
4
|
+
*/
|
|
5
|
+
var RequestDeduplicator = class {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.pendingRequests = /* @__PURE__ */ new Map();
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Execute a request with deduplication
|
|
11
|
+
* If a request with the same key is already pending, return the existing promise
|
|
12
|
+
* Otherwise, execute the request factory and track the promise
|
|
13
|
+
*/
|
|
14
|
+
async executeRequest(key, requestFactory) {
|
|
15
|
+
const existingRequest = this.pendingRequests.get(key);
|
|
16
|
+
if (existingRequest) return existingRequest;
|
|
17
|
+
const requestPromise = requestFactory();
|
|
18
|
+
this.pendingRequests.set(key, requestPromise);
|
|
19
|
+
try {
|
|
20
|
+
const result = await requestPromise;
|
|
21
|
+
this.pendingRequests.delete(key);
|
|
22
|
+
return result;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
this.pendingRequests.delete(key);
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Clear all pending requests (used in cache clearing)
|
|
30
|
+
*/
|
|
31
|
+
clear() {
|
|
32
|
+
this.pendingRequests.clear();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get number of pending requests
|
|
36
|
+
*/
|
|
37
|
+
getPendingCount() {
|
|
38
|
+
return this.pendingRequests.size;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check if a request is pending
|
|
42
|
+
*/
|
|
43
|
+
isPending(key) {
|
|
44
|
+
return this.pendingRequests.has(key);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get all pending request keys
|
|
48
|
+
*/
|
|
49
|
+
getPendingKeys() {
|
|
50
|
+
return Array.from(this.pendingRequests.keys());
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
export { RequestDeduplicator };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|