@editframe/elements 0.17.6-beta.0 → 0.18.3-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/EF_FRAMEGEN.js +1 -1
- package/dist/ScrubTrackManager.d.ts +2 -2
- package/dist/elements/EFAudio.d.ts +21 -2
- package/dist/elements/EFAudio.js +41 -11
- package/dist/elements/EFImage.d.ts +1 -0
- package/dist/elements/EFImage.js +11 -3
- package/dist/elements/EFMedia/AssetIdMediaEngine.d.ts +18 -0
- package/dist/elements/EFMedia/AssetIdMediaEngine.js +41 -0
- package/dist/elements/EFMedia/AssetMediaEngine.d.ts +47 -0
- package/dist/elements/EFMedia/AssetMediaEngine.js +116 -0
- package/dist/elements/EFMedia/BaseMediaEngine.d.ts +55 -0
- package/dist/elements/EFMedia/BaseMediaEngine.js +96 -0
- package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +43 -0
- package/dist/elements/EFMedia/BufferedSeekingInput.js +159 -0
- package/dist/elements/EFMedia/JitMediaEngine.browsertest.d.ts +0 -0
- package/dist/elements/EFMedia/JitMediaEngine.d.ts +31 -0
- package/dist/elements/EFMedia/JitMediaEngine.js +62 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.d.ts +16 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +48 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.d.ts +3 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +138 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.d.ts +4 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +16 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.d.ts +3 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +22 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.d.ts +7 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +24 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.d.ts +4 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +18 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.d.ts +4 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +16 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.d.ts +3 -0
- package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +104 -0
- package/dist/elements/EFMedia/services/AudioElementFactory.d.ts +22 -0
- package/dist/elements/EFMedia/services/AudioElementFactory.js +72 -0
- package/dist/elements/EFMedia/services/MediaSourceService.browsertest.d.ts +1 -0
- package/dist/elements/EFMedia/services/MediaSourceService.d.ts +47 -0
- package/dist/elements/EFMedia/services/MediaSourceService.js +73 -0
- package/dist/elements/EFMedia/shared/AudioSpanUtils.d.ts +7 -0
- package/dist/elements/EFMedia/shared/AudioSpanUtils.js +54 -0
- package/dist/elements/EFMedia/shared/BufferUtils.d.ts +70 -0
- package/dist/elements/EFMedia/shared/BufferUtils.js +89 -0
- package/dist/elements/EFMedia/shared/MediaTaskUtils.d.ts +23 -0
- package/dist/elements/EFMedia/shared/RenditionHelpers.browsertest.d.ts +1 -0
- package/dist/elements/EFMedia/shared/RenditionHelpers.d.ts +19 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.d.ts +1 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.d.ts +18 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +60 -0
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.test.d.ts +1 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.d.ts +16 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +46 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.d.ts +4 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.js +16 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.d.ts +3 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.js +27 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSeekTask.d.ts +7 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSeekTask.js +25 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.d.ts +4 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.js +18 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.d.ts +9 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.d.ts +4 -0
- package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.js +16 -0
- package/dist/elements/EFMedia.browsertest.d.ts +1 -0
- package/dist/elements/EFMedia.d.ts +75 -111
- package/dist/elements/EFMedia.js +141 -1111
- package/dist/elements/EFTemporal.d.ts +1 -1
- package/dist/elements/EFTemporal.js +1 -1
- package/dist/elements/EFTimegroup.d.ts +11 -0
- package/dist/elements/EFTimegroup.js +88 -13
- package/dist/elements/EFVideo.d.ts +60 -29
- package/dist/elements/EFVideo.js +103 -203
- package/dist/elements/EFWaveform.js +2 -2
- package/dist/elements/SampleBuffer.d.ts +14 -0
- package/dist/elements/SampleBuffer.js +52 -0
- package/dist/getRenderInfo.d.ts +2 -2
- package/dist/getRenderInfo.js +2 -1
- package/dist/gui/ContextMixin.js +17 -70
- package/dist/gui/EFFilmstrip.d.ts +3 -3
- package/dist/gui/EFFilmstrip.js +1 -1
- package/dist/gui/EFFitScale.d.ts +2 -2
- package/dist/gui/TWMixin.js +1 -1
- package/dist/gui/services/ElementConnectionManager.browsertest.d.ts +1 -0
- package/dist/gui/services/ElementConnectionManager.d.ts +59 -0
- package/dist/gui/services/ElementConnectionManager.js +128 -0
- package/dist/gui/services/PlaybackController.browsertest.d.ts +1 -0
- package/dist/gui/services/PlaybackController.d.ts +103 -0
- package/dist/gui/services/PlaybackController.js +290 -0
- package/dist/services/MediaSourceManager.d.ts +62 -0
- package/dist/services/MediaSourceManager.js +211 -0
- package/dist/style.css +1 -1
- package/dist/transcoding/cache/CacheManager.d.ts +73 -0
- package/dist/transcoding/cache/RequestDeduplicator.d.ts +29 -0
- package/dist/transcoding/cache/RequestDeduplicator.js +53 -0
- package/dist/transcoding/cache/RequestDeduplicator.test.d.ts +1 -0
- package/dist/transcoding/types/index.d.ts +242 -0
- package/dist/transcoding/utils/MediaUtils.d.ts +9 -0
- package/dist/transcoding/utils/UrlGenerator.d.ts +26 -0
- package/dist/transcoding/utils/UrlGenerator.js +45 -0
- package/dist/transcoding/utils/constants.d.ts +27 -0
- package/dist/utils/LRUCache.d.ts +34 -0
- package/dist/utils/LRUCache.js +115 -0
- package/package.json +3 -2
- package/src/elements/EFAudio.browsertest.ts +183 -43
- package/src/elements/EFAudio.ts +59 -13
- package/src/elements/EFImage.browsertest.ts +42 -0
- package/src/elements/EFImage.ts +23 -3
- package/src/elements/EFMedia/AssetIdMediaEngine.test.ts +222 -0
- package/src/elements/EFMedia/AssetIdMediaEngine.ts +70 -0
- package/src/elements/EFMedia/AssetMediaEngine.ts +210 -0
- package/src/elements/EFMedia/BaseMediaEngine.test.ts +164 -0
- package/src/elements/EFMedia/BaseMediaEngine.ts +170 -0
- package/src/elements/EFMedia/BufferedSeekingInput.browsertest.ts +400 -0
- package/src/elements/EFMedia/BufferedSeekingInput.ts +267 -0
- package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +165 -0
- package/src/elements/EFMedia/JitMediaEngine.ts +110 -0
- package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.ts +554 -0
- package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.ts +81 -0
- package/src/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.ts +241 -0
- package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.ts +59 -0
- package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.ts +23 -0
- package/src/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.ts +55 -0
- package/src/elements/EFMedia/audioTasks/makeAudioInputTask.ts +35 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.ts +42 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.ts +34 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.ts +23 -0
- package/src/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.ts +174 -0
- package/src/elements/EFMedia/services/AudioElementFactory.browsertest.ts +325 -0
- package/src/elements/EFMedia/services/AudioElementFactory.ts +119 -0
- package/src/elements/EFMedia/services/MediaSourceService.browsertest.ts +257 -0
- package/src/elements/EFMedia/services/MediaSourceService.ts +102 -0
- package/src/elements/EFMedia/shared/AudioSpanUtils.ts +128 -0
- package/src/elements/EFMedia/shared/BufferUtils.ts +310 -0
- package/src/elements/EFMedia/shared/MediaTaskUtils.ts +44 -0
- package/src/elements/EFMedia/shared/RenditionHelpers.browsertest.ts +247 -0
- package/src/elements/EFMedia/shared/RenditionHelpers.ts +79 -0
- package/src/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.ts +128 -0
- package/src/elements/EFMedia/tasks/makeMediaEngineTask.test.ts +233 -0
- package/src/elements/EFMedia/tasks/makeMediaEngineTask.ts +89 -0
- package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.browsertest.ts +555 -0
- package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.ts +79 -0
- package/src/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.browsertest.ts +59 -0
- package/src/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.ts +23 -0
- package/src/elements/EFMedia/videoTasks/makeVideoInputTask.browsertest.ts +55 -0
- package/src/elements/EFMedia/videoTasks/makeVideoInputTask.ts +45 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSeekTask.ts +44 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.ts +57 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.ts +32 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.ts +56 -0
- package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.ts +23 -0
- package/src/elements/EFMedia.browsertest.ts +658 -265
- package/src/elements/EFMedia.ts +173 -1763
- package/src/elements/EFTemporal.ts +3 -4
- package/src/elements/EFTimegroup.browsertest.ts +6 -3
- package/src/elements/EFTimegroup.ts +152 -21
- package/src/elements/EFVideo.browsertest.ts +115 -37
- package/src/elements/EFVideo.ts +123 -452
- package/src/elements/EFWaveform.ts +1 -1
- package/src/elements/MediaController.ts +2 -12
- package/src/elements/SampleBuffer.ts +97 -0
- package/src/gui/ContextMixin.ts +23 -104
- package/src/gui/services/ElementConnectionManager.browsertest.ts +263 -0
- package/src/gui/services/ElementConnectionManager.ts +224 -0
- package/src/gui/services/PlaybackController.browsertest.ts +437 -0
- package/src/gui/services/PlaybackController.ts +521 -0
- package/src/services/MediaSourceManager.ts +333 -0
- package/src/transcoding/cache/CacheManager.ts +208 -0
- package/src/transcoding/cache/RequestDeduplicator.test.ts +170 -0
- package/src/transcoding/cache/RequestDeduplicator.ts +65 -0
- package/src/transcoding/types/index.ts +265 -0
- package/src/transcoding/utils/MediaUtils.ts +63 -0
- package/src/transcoding/utils/UrlGenerator.ts +68 -0
- package/src/transcoding/utils/constants.ts +36 -0
- package/src/utils/LRUCache.ts +153 -0
- package/test/EFVideo.framegen.browsertest.ts +38 -29
- package/test/__cache__/GET__api_v1_transcode_audio_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__32da3954ba60c96ad732020c65a08ebc/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_audio_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__32da3954ba60c96ad732020c65a08ebc/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_audio_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__b0b2b07efcf607de8ee0f650328c32f7/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_audio_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__b0b2b07efcf607de8ee0f650328c32f7/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_audio_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a75c2252b542e0c152c780e9a8d7b154/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_audio_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a75c2252b542e0c152c780e9a8d7b154/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_audio_4_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a64ff1cfb1b52cae14df4b5dfa1e222b/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_audio_4_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a64ff1cfb1b52cae14df4b5dfa1e222b/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_audio_5_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__91e8a522f950809b9f09f4173113b4b0/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_audio_5_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__91e8a522f950809b9f09f4173113b4b0/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_audio_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__e66d2c831d951e74ad0aeaa6489795d0/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_audio_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__e66d2c831d951e74ad0aeaa6489795d0/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_high_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__26197f6f7c46cacb0a71134131c3f775/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_high_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__26197f6f7c46cacb0a71134131c3f775/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_high_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__4cb6774cd3650ccf59c8f8dc6678c0b9/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_high_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__4cb6774cd3650ccf59c8f8dc6678c0b9/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_high_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0b3b2b1c8933f7fcf8a9ecaa88d58b41/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_high_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0b3b2b1c8933f7fcf8a9ecaa88d58b41/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_high_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0798c479b44aaeef850609a430f6e613/data.bin +0 -0
- package/test/__cache__/GET__api_v1_transcode_high_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0798c479b44aaeef850609a430f6e613/metadata.json +21 -0
- package/test/__cache__/GET__api_v1_transcode_manifest_json_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__3be92a0437de726b431ed5af2369158a/data.bin +1 -0
- package/test/__cache__/GET__api_v1_transcode_manifest_json_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__3be92a0437de726b431ed5af2369158a/metadata.json +19 -0
- package/test/createJitTestClips.ts +320 -188
- package/test/recordReplayProxyPlugin.js +302 -0
- package/test/useAssetMSW.ts +1 -1
- package/test/useMSW.ts +35 -22
- package/types.json +1 -1
- package/dist/JitTranscodingClient.d.ts +0 -167
- package/dist/JitTranscodingClient.js +0 -373
- package/dist/ScrubTrackManager.js +0 -216
- package/dist/elements/printTaskStatus.js +0 -11
- package/src/elements/__screenshots__/EFMedia.browsertest.ts/EFMedia-JIT-audio-playback-audioBufferTask-should-work-in-JIT-mode-without-URL-errors-1.png +0 -0
- package/test/EFVideo.frame-tasks.browsertest.ts +0 -524
- /package/dist/{JitTranscodingClient.browsertest.d.ts → elements/EFMedia/AssetIdMediaEngine.test.d.ts} +0 -0
- /package/dist/{JitTranscodingClient.test.d.ts → elements/EFMedia/BaseMediaEngine.test.d.ts} +0 -0
- /package/dist/{ScrubTrackIntegration.test.d.ts → elements/EFMedia/BufferedSeekingInput.browsertest.d.ts} +0 -0
- /package/dist/{SegmentSwitchLoading.test.d.ts → elements/EFMedia/services/AudioElementFactory.browsertest.d.ts} +0 -0
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JIT Transcoding Client for Elements
|
|
3
|
-
* Handles communication with the JIT transcoding service for real-time video streaming
|
|
4
|
-
*/
|
|
5
|
-
export interface QualityPreset {
|
|
6
|
-
name: string;
|
|
7
|
-
width: number;
|
|
8
|
-
height: number;
|
|
9
|
-
videoBitrate: number;
|
|
10
|
-
audioBitrate: number;
|
|
11
|
-
audioChannels: number;
|
|
12
|
-
audioSampleRate: number;
|
|
13
|
-
audioCodec: "aac";
|
|
14
|
-
}
|
|
15
|
-
export interface VideoMetadata {
|
|
16
|
-
url: string;
|
|
17
|
-
durationMs: number;
|
|
18
|
-
streams: Array<{
|
|
19
|
-
index: number;
|
|
20
|
-
type: "video" | "audio" | "subtitle" | "other";
|
|
21
|
-
codecName: string;
|
|
22
|
-
duration: number;
|
|
23
|
-
durationMs: number;
|
|
24
|
-
width?: number;
|
|
25
|
-
height?: number;
|
|
26
|
-
frameRate?: {
|
|
27
|
-
num: number;
|
|
28
|
-
den: number;
|
|
29
|
-
};
|
|
30
|
-
channels?: number;
|
|
31
|
-
sampleRate?: number;
|
|
32
|
-
}>;
|
|
33
|
-
presets: string[];
|
|
34
|
-
segmentDuration: number;
|
|
35
|
-
supportedFormats: string[];
|
|
36
|
-
extractedAt: string;
|
|
37
|
-
}
|
|
38
|
-
export interface JitTranscodingConfig {
|
|
39
|
-
baseUrl: string;
|
|
40
|
-
defaultQuality: keyof QualityPresets;
|
|
41
|
-
segmentCacheSize: number;
|
|
42
|
-
enableNetworkAdaptation: boolean;
|
|
43
|
-
enablePrefetch: boolean;
|
|
44
|
-
prefetchSegments: number;
|
|
45
|
-
}
|
|
46
|
-
export interface QualityPresets {
|
|
47
|
-
low: QualityPreset;
|
|
48
|
-
medium: QualityPreset;
|
|
49
|
-
high: QualityPreset;
|
|
50
|
-
}
|
|
51
|
-
export interface NetworkCondition {
|
|
52
|
-
bandwidth: number;
|
|
53
|
-
rtt: number;
|
|
54
|
-
connectionType: string;
|
|
55
|
-
}
|
|
56
|
-
export interface SegmentInfo {
|
|
57
|
-
url: string;
|
|
58
|
-
startTimeMs: number;
|
|
59
|
-
durationMs: number;
|
|
60
|
-
quality: string;
|
|
61
|
-
cached: boolean;
|
|
62
|
-
}
|
|
63
|
-
export declare class JitTranscodingClient {
|
|
64
|
-
private config;
|
|
65
|
-
private segmentCache;
|
|
66
|
-
private metadataCache;
|
|
67
|
-
private qualityPresets;
|
|
68
|
-
private currentQuality;
|
|
69
|
-
private networkMonitor;
|
|
70
|
-
private pendingRequests;
|
|
71
|
-
private cacheHits;
|
|
72
|
-
private cacheMisses;
|
|
73
|
-
private totalRequests;
|
|
74
|
-
private cacheAccessOrder;
|
|
75
|
-
constructor(config?: Partial<JitTranscodingConfig>);
|
|
76
|
-
/**
|
|
77
|
-
* Check if a URL is eligible for JIT transcoding
|
|
78
|
-
*/
|
|
79
|
-
static isJitTranscodeEligible(url: string): boolean;
|
|
80
|
-
/**
|
|
81
|
-
* Instance method to check if a URL is eligible for JIT transcoding
|
|
82
|
-
*/
|
|
83
|
-
isJitTranscodeEligible(url: string): boolean;
|
|
84
|
-
/**
|
|
85
|
-
* Load quality presets from the JIT transcoding service
|
|
86
|
-
*/
|
|
87
|
-
loadQualityPresets(): Promise<QualityPresets>;
|
|
88
|
-
/**
|
|
89
|
-
* Internal method to actually fetch quality presets
|
|
90
|
-
*/
|
|
91
|
-
private fetchQualityPresets;
|
|
92
|
-
/**
|
|
93
|
-
* Load video metadata from the JIT transcoding service
|
|
94
|
-
*/
|
|
95
|
-
loadVideoMetadata(url: string): Promise<VideoMetadata>;
|
|
96
|
-
/**
|
|
97
|
-
* Internal method to actually fetch video metadata
|
|
98
|
-
*/
|
|
99
|
-
private fetchVideoMetadata;
|
|
100
|
-
/**
|
|
101
|
-
* Get the appropriate quality based on network conditions
|
|
102
|
-
*/
|
|
103
|
-
getAdaptiveQuality(): Promise<keyof QualityPresets>;
|
|
104
|
-
/**
|
|
105
|
-
* Generate segment URL for JIT transcoding
|
|
106
|
-
*/
|
|
107
|
-
generateSegmentUrl(videoUrl: string, startTimeMs: number, quality?: keyof QualityPresets): string;
|
|
108
|
-
/**
|
|
109
|
-
* Fetch a video segment with caching
|
|
110
|
-
*/
|
|
111
|
-
fetchSegment(videoUrl: string, startTimeMs: number, quality?: keyof QualityPresets): Promise<ArrayBuffer>;
|
|
112
|
-
/**
|
|
113
|
-
* Internal method to actually fetch a video segment
|
|
114
|
-
*/
|
|
115
|
-
private fetchVideoSegment;
|
|
116
|
-
/**
|
|
117
|
-
* Prefetch upcoming segments
|
|
118
|
-
*/
|
|
119
|
-
prefetchSegments(videoUrl: string, currentTimeMs: number, quality?: keyof QualityPresets): Promise<void>;
|
|
120
|
-
/**
|
|
121
|
-
* Cache a segment with LRU eviction
|
|
122
|
-
*/
|
|
123
|
-
private cacheSegment;
|
|
124
|
-
/**
|
|
125
|
-
* Get comprehensive cache statistics
|
|
126
|
-
*/
|
|
127
|
-
getCacheStats(): {
|
|
128
|
-
size: number;
|
|
129
|
-
maxSize: number;
|
|
130
|
-
hitRate: number;
|
|
131
|
-
efficiency: number;
|
|
132
|
-
totalRequests: number;
|
|
133
|
-
recentKeys: string[];
|
|
134
|
-
};
|
|
135
|
-
/**
|
|
136
|
-
* Clear all caches
|
|
137
|
-
*/
|
|
138
|
-
clearCache(): void;
|
|
139
|
-
/**
|
|
140
|
-
* Set manual quality override
|
|
141
|
-
*/
|
|
142
|
-
setQuality(quality: keyof QualityPresets): void;
|
|
143
|
-
/**
|
|
144
|
-
* Get current quality setting
|
|
145
|
-
*/
|
|
146
|
-
getCurrentQuality(): keyof QualityPresets;
|
|
147
|
-
/**
|
|
148
|
-
* Load a video segment for any quality preset including scrub
|
|
149
|
-
*/
|
|
150
|
-
loadSegment(videoUrl: string, quality: string, startTimeMs: number): Promise<ArrayBuffer>;
|
|
151
|
-
/**
|
|
152
|
-
* Load a scrub track segment (30s duration)
|
|
153
|
-
*/
|
|
154
|
-
private loadScrubSegment;
|
|
155
|
-
/**
|
|
156
|
-
* Internal method to fetch scrub segment
|
|
157
|
-
*/
|
|
158
|
-
private fetchScrubSegment;
|
|
159
|
-
/**
|
|
160
|
-
* Check if a segment is cached for a given quality
|
|
161
|
-
*/
|
|
162
|
-
hasSegmentInCache(videoUrl: string, quality: string, timeMs: number): boolean;
|
|
163
|
-
/**
|
|
164
|
-
* Get video metadata
|
|
165
|
-
*/
|
|
166
|
-
getMetadata(videoUrl: string): Promise<VideoMetadata>;
|
|
167
|
-
}
|
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
var JitTranscodingClient = class JitTranscodingClient {
|
|
2
|
-
constructor(config = {}) {
|
|
3
|
-
this.segmentCache = /* @__PURE__ */ new Map();
|
|
4
|
-
this.metadataCache = /* @__PURE__ */ new Map();
|
|
5
|
-
this.qualityPresets = null;
|
|
6
|
-
this.pendingRequests = /* @__PURE__ */ new Map();
|
|
7
|
-
this.cacheHits = 0;
|
|
8
|
-
this.cacheMisses = 0;
|
|
9
|
-
this.totalRequests = 0;
|
|
10
|
-
this.cacheAccessOrder = [];
|
|
11
|
-
this.config = {
|
|
12
|
-
baseUrl: "http://localhost:3000",
|
|
13
|
-
defaultQuality: "medium",
|
|
14
|
-
segmentCacheSize: 50,
|
|
15
|
-
enableNetworkAdaptation: true,
|
|
16
|
-
enablePrefetch: true,
|
|
17
|
-
prefetchSegments: 3,
|
|
18
|
-
...config
|
|
19
|
-
};
|
|
20
|
-
this.currentQuality = this.config.defaultQuality;
|
|
21
|
-
this.networkMonitor = new NetworkMonitor();
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Check if a URL is eligible for JIT transcoding
|
|
25
|
-
*/
|
|
26
|
-
static isJitTranscodeEligible(url) {
|
|
27
|
-
return url.startsWith("http://") || url.startsWith("https://");
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Instance method to check if a URL is eligible for JIT transcoding
|
|
31
|
-
*/
|
|
32
|
-
isJitTranscodeEligible(url) {
|
|
33
|
-
return JitTranscodingClient.isJitTranscodeEligible(url);
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Load quality presets from the JIT transcoding service
|
|
37
|
-
*/
|
|
38
|
-
async loadQualityPresets() {
|
|
39
|
-
if (this.qualityPresets) return this.qualityPresets;
|
|
40
|
-
const requestKey = "quality-presets";
|
|
41
|
-
const pendingRequest = this.pendingRequests.get(requestKey);
|
|
42
|
-
if (pendingRequest) return pendingRequest;
|
|
43
|
-
const requestPromise = this.fetchQualityPresets();
|
|
44
|
-
this.pendingRequests.set(requestKey, requestPromise);
|
|
45
|
-
try {
|
|
46
|
-
const result = await requestPromise;
|
|
47
|
-
this.pendingRequests.delete(requestKey);
|
|
48
|
-
return result;
|
|
49
|
-
} catch (error) {
|
|
50
|
-
this.pendingRequests.delete(requestKey);
|
|
51
|
-
throw error;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Internal method to actually fetch quality presets
|
|
56
|
-
*/
|
|
57
|
-
async fetchQualityPresets() {
|
|
58
|
-
try {
|
|
59
|
-
const response = await fetch(`${this.config.baseUrl}/api/v1/transcode/presets`);
|
|
60
|
-
if (!response.ok) throw new Error(`Failed to load quality presets: ${response.status}`);
|
|
61
|
-
const data = await response.json();
|
|
62
|
-
this.qualityPresets = data.presets;
|
|
63
|
-
if (!this.qualityPresets) throw new Error("No quality presets found");
|
|
64
|
-
return this.qualityPresets;
|
|
65
|
-
} catch (error) {
|
|
66
|
-
console.error("Failed to load quality presets:", error);
|
|
67
|
-
this.qualityPresets = {
|
|
68
|
-
low: {
|
|
69
|
-
name: "low",
|
|
70
|
-
width: 480,
|
|
71
|
-
height: 270,
|
|
72
|
-
videoBitrate: 4e5,
|
|
73
|
-
audioBitrate: 64e3,
|
|
74
|
-
audioChannels: 2,
|
|
75
|
-
audioSampleRate: 48e3,
|
|
76
|
-
audioCodec: "aac"
|
|
77
|
-
},
|
|
78
|
-
medium: {
|
|
79
|
-
name: "medium",
|
|
80
|
-
width: 854,
|
|
81
|
-
height: 480,
|
|
82
|
-
videoBitrate: 1e6,
|
|
83
|
-
audioBitrate: 128e3,
|
|
84
|
-
audioChannels: 2,
|
|
85
|
-
audioSampleRate: 48e3,
|
|
86
|
-
audioCodec: "aac"
|
|
87
|
-
},
|
|
88
|
-
high: {
|
|
89
|
-
name: "high",
|
|
90
|
-
width: 1280,
|
|
91
|
-
height: 720,
|
|
92
|
-
videoBitrate: 25e5,
|
|
93
|
-
audioBitrate: 192e3,
|
|
94
|
-
audioChannels: 2,
|
|
95
|
-
audioSampleRate: 48e3,
|
|
96
|
-
audioCodec: "aac"
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
return this.qualityPresets;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Load video metadata from the JIT transcoding service
|
|
104
|
-
*/
|
|
105
|
-
async loadVideoMetadata(url) {
|
|
106
|
-
const cached = this.metadataCache.get(url);
|
|
107
|
-
if (cached) return cached;
|
|
108
|
-
const requestKey = `metadata:${url}`;
|
|
109
|
-
const pendingRequest = this.pendingRequests.get(requestKey);
|
|
110
|
-
if (pendingRequest) return pendingRequest;
|
|
111
|
-
const requestPromise = this.fetchVideoMetadata(url);
|
|
112
|
-
this.pendingRequests.set(requestKey, requestPromise);
|
|
113
|
-
try {
|
|
114
|
-
const result = await requestPromise;
|
|
115
|
-
this.pendingRequests.delete(requestKey);
|
|
116
|
-
return result;
|
|
117
|
-
} catch (error) {
|
|
118
|
-
this.pendingRequests.delete(requestKey);
|
|
119
|
-
throw error;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Internal method to actually fetch video metadata
|
|
124
|
-
*/
|
|
125
|
-
async fetchVideoMetadata(url) {
|
|
126
|
-
try {
|
|
127
|
-
const response = await fetch(`${this.config.baseUrl}/api/v1/transcode/metadata?url=${encodeURIComponent(url)}`);
|
|
128
|
-
if (!response.ok) throw new Error(`Failed to load video metadata: ${response.status}`);
|
|
129
|
-
const metadata = await response.json();
|
|
130
|
-
this.metadataCache.set(url, metadata);
|
|
131
|
-
return metadata;
|
|
132
|
-
} catch (error) {
|
|
133
|
-
console.error("Failed to load video metadata:", error);
|
|
134
|
-
throw error;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Get the appropriate quality based on network conditions
|
|
139
|
-
*/
|
|
140
|
-
async getAdaptiveQuality() {
|
|
141
|
-
if (!this.config.enableNetworkAdaptation) return this.currentQuality;
|
|
142
|
-
const networkCondition = await this.networkMonitor.getCurrentCondition();
|
|
143
|
-
if (networkCondition.bandwidth < 8e5) return "low";
|
|
144
|
-
if (networkCondition.bandwidth < 2e6) return "medium";
|
|
145
|
-
return "high";
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Generate segment URL for JIT transcoding
|
|
149
|
-
*/
|
|
150
|
-
generateSegmentUrl(videoUrl, startTimeMs, quality = this.currentQuality) {
|
|
151
|
-
const alignedStartTime = Math.floor(startTimeMs / 2e3) * 2e3;
|
|
152
|
-
return `${this.config.baseUrl}/api/v1/transcode/${quality}?url=${encodeURIComponent(videoUrl)}&start=${alignedStartTime}`;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Fetch a video segment with caching
|
|
156
|
-
*/
|
|
157
|
-
async fetchSegment(videoUrl, startTimeMs, quality) {
|
|
158
|
-
const effectiveQuality = quality || await this.getAdaptiveQuality();
|
|
159
|
-
const segmentUrl = this.generateSegmentUrl(videoUrl, startTimeMs, effectiveQuality);
|
|
160
|
-
const cacheKey = `${videoUrl}:${startTimeMs}:${effectiveQuality}`;
|
|
161
|
-
const cached = this.segmentCache.get(cacheKey);
|
|
162
|
-
if (cached) {
|
|
163
|
-
this.cacheHits++;
|
|
164
|
-
return cached;
|
|
165
|
-
}
|
|
166
|
-
const requestKey = `segment:${cacheKey}`;
|
|
167
|
-
const pendingRequest = this.pendingRequests.get(requestKey);
|
|
168
|
-
if (pendingRequest) return pendingRequest;
|
|
169
|
-
const requestPromise = this.fetchVideoSegment(segmentUrl, cacheKey, effectiveQuality);
|
|
170
|
-
this.pendingRequests.set(requestKey, requestPromise);
|
|
171
|
-
try {
|
|
172
|
-
const result = await requestPromise;
|
|
173
|
-
this.pendingRequests.delete(requestKey);
|
|
174
|
-
return result;
|
|
175
|
-
} catch (error) {
|
|
176
|
-
this.pendingRequests.delete(requestKey);
|
|
177
|
-
throw error;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Internal method to actually fetch a video segment
|
|
182
|
-
*/
|
|
183
|
-
async fetchVideoSegment(segmentUrl, cacheKey, effectiveQuality) {
|
|
184
|
-
try {
|
|
185
|
-
const response = await fetch(segmentUrl);
|
|
186
|
-
if (!response.ok) throw new Error(`Failed to fetch segment: ${response.status}`);
|
|
187
|
-
const buffer = await response.arrayBuffer();
|
|
188
|
-
this.cacheSegment(cacheKey, buffer);
|
|
189
|
-
this.currentQuality = effectiveQuality;
|
|
190
|
-
this.cacheMisses++;
|
|
191
|
-
return buffer;
|
|
192
|
-
} catch (error) {
|
|
193
|
-
console.error("Failed to fetch segment:", error);
|
|
194
|
-
throw error;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Prefetch upcoming segments
|
|
199
|
-
*/
|
|
200
|
-
async prefetchSegments(videoUrl, currentTimeMs, quality) {
|
|
201
|
-
if (!this.config.enablePrefetch) return;
|
|
202
|
-
const effectiveQuality = quality || this.currentQuality;
|
|
203
|
-
const segmentDuration = 2e3;
|
|
204
|
-
const prefetchPromises = [];
|
|
205
|
-
for (let i = 1; i <= this.config.prefetchSegments; i++) {
|
|
206
|
-
const nextSegmentStart = currentTimeMs + i * segmentDuration;
|
|
207
|
-
const cacheKey = `${videoUrl}:${nextSegmentStart}:${effectiveQuality}`;
|
|
208
|
-
if (!this.segmentCache.has(cacheKey)) prefetchPromises.push(this.fetchSegment(videoUrl, nextSegmentStart, effectiveQuality).catch((error) => {
|
|
209
|
-
console.warn(`Failed to prefetch segment at ${nextSegmentStart}ms:`, error);
|
|
210
|
-
return /* @__PURE__ */ new ArrayBuffer(0);
|
|
211
|
-
}));
|
|
212
|
-
}
|
|
213
|
-
Promise.allSettled(prefetchPromises).then(() => {
|
|
214
|
-
console.debug(`Prefetched ${prefetchPromises.length} segments`);
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Cache a segment with LRU eviction
|
|
219
|
-
*/
|
|
220
|
-
cacheSegment(cacheKey, buffer) {
|
|
221
|
-
if (this.segmentCache.size >= this.config.segmentCacheSize) {
|
|
222
|
-
const firstKey = this.segmentCache.keys().next().value;
|
|
223
|
-
if (firstKey) {
|
|
224
|
-
this.segmentCache.delete(firstKey);
|
|
225
|
-
const index = this.cacheAccessOrder.indexOf(firstKey);
|
|
226
|
-
if (index > -1) this.cacheAccessOrder.splice(index, 1);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
this.segmentCache.set(cacheKey, buffer);
|
|
230
|
-
const existingIndex = this.cacheAccessOrder.indexOf(cacheKey);
|
|
231
|
-
if (existingIndex > -1) this.cacheAccessOrder.splice(existingIndex, 1);
|
|
232
|
-
this.cacheAccessOrder.push(cacheKey);
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Get comprehensive cache statistics
|
|
236
|
-
*/
|
|
237
|
-
getCacheStats() {
|
|
238
|
-
this.totalRequests = this.cacheHits + this.cacheMisses;
|
|
239
|
-
const hitRate = this.totalRequests > 0 ? this.cacheHits / this.totalRequests : 0;
|
|
240
|
-
const efficiency = this.segmentCache.size > 0 ? this.cacheHits / this.segmentCache.size : 0;
|
|
241
|
-
return {
|
|
242
|
-
size: this.segmentCache.size,
|
|
243
|
-
maxSize: this.config.segmentCacheSize,
|
|
244
|
-
hitRate,
|
|
245
|
-
efficiency,
|
|
246
|
-
totalRequests: this.totalRequests,
|
|
247
|
-
recentKeys: this.cacheAccessOrder.slice(-5)
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Clear all caches
|
|
252
|
-
*/
|
|
253
|
-
clearCache() {
|
|
254
|
-
this.segmentCache.clear();
|
|
255
|
-
this.metadataCache.clear();
|
|
256
|
-
this.pendingRequests.clear();
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Set manual quality override
|
|
260
|
-
*/
|
|
261
|
-
setQuality(quality) {
|
|
262
|
-
this.currentQuality = quality;
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Get current quality setting
|
|
266
|
-
*/
|
|
267
|
-
getCurrentQuality() {
|
|
268
|
-
return this.currentQuality;
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Load a video segment for any quality preset including scrub
|
|
272
|
-
*/
|
|
273
|
-
async loadSegment(videoUrl, quality, startTimeMs) {
|
|
274
|
-
if (quality === "scrub") return this.loadScrubSegment(videoUrl, startTimeMs);
|
|
275
|
-
return this.fetchSegment(videoUrl, startTimeMs, quality);
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Load a scrub track segment (30s duration)
|
|
279
|
-
*/
|
|
280
|
-
async loadScrubSegment(videoUrl, startTimeMs) {
|
|
281
|
-
const alignedStartTime = Math.floor(startTimeMs / 3e4) * 3e4;
|
|
282
|
-
const segmentUrl = `${this.config.baseUrl}/api/v1/transcode/scrub?url=${encodeURIComponent(videoUrl)}&start=${alignedStartTime}`;
|
|
283
|
-
const cacheKey = `${videoUrl}:${alignedStartTime}:scrub`;
|
|
284
|
-
const cached = this.segmentCache.get(cacheKey);
|
|
285
|
-
if (cached) {
|
|
286
|
-
this.cacheHits++;
|
|
287
|
-
return cached;
|
|
288
|
-
}
|
|
289
|
-
const requestKey = `scrub:${cacheKey}`;
|
|
290
|
-
const pendingRequest = this.pendingRequests.get(requestKey);
|
|
291
|
-
if (pendingRequest) return pendingRequest;
|
|
292
|
-
const requestPromise = this.fetchScrubSegment(segmentUrl, cacheKey);
|
|
293
|
-
this.pendingRequests.set(requestKey, requestPromise);
|
|
294
|
-
try {
|
|
295
|
-
const result = await requestPromise;
|
|
296
|
-
this.pendingRequests.delete(requestKey);
|
|
297
|
-
return result;
|
|
298
|
-
} catch (error) {
|
|
299
|
-
this.pendingRequests.delete(requestKey);
|
|
300
|
-
throw error;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Internal method to fetch scrub segment
|
|
305
|
-
*/
|
|
306
|
-
async fetchScrubSegment(segmentUrl, cacheKey) {
|
|
307
|
-
try {
|
|
308
|
-
const response = await fetch(segmentUrl);
|
|
309
|
-
if (!response.ok) throw new Error(`Failed to fetch scrub segment: ${response.status}`);
|
|
310
|
-
const buffer = await response.arrayBuffer();
|
|
311
|
-
this.cacheSegment(cacheKey, buffer);
|
|
312
|
-
this.cacheMisses++;
|
|
313
|
-
return buffer;
|
|
314
|
-
} catch (error) {
|
|
315
|
-
console.error("Failed to fetch scrub segment:", error);
|
|
316
|
-
throw error;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Check if a segment is cached for a given quality
|
|
321
|
-
*/
|
|
322
|
-
hasSegmentInCache(videoUrl, quality, timeMs) {
|
|
323
|
-
let alignedTime;
|
|
324
|
-
let cacheKey;
|
|
325
|
-
if (quality === "scrub") {
|
|
326
|
-
alignedTime = Math.floor(timeMs / 3e4) * 3e4;
|
|
327
|
-
cacheKey = `${videoUrl}:${alignedTime}:scrub`;
|
|
328
|
-
} else {
|
|
329
|
-
alignedTime = Math.floor(timeMs / 2e3) * 2e3;
|
|
330
|
-
cacheKey = `${videoUrl}:${alignedTime}:${quality}`;
|
|
331
|
-
}
|
|
332
|
-
return this.segmentCache.has(cacheKey);
|
|
333
|
-
}
|
|
334
|
-
/**
|
|
335
|
-
* Get video metadata
|
|
336
|
-
*/
|
|
337
|
-
async getMetadata(videoUrl) {
|
|
338
|
-
return this.loadVideoMetadata(videoUrl);
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
/**
|
|
342
|
-
* Network condition monitoring
|
|
343
|
-
*/
|
|
344
|
-
var NetworkMonitor = class {
|
|
345
|
-
constructor() {
|
|
346
|
-
this.measurementHistory = [];
|
|
347
|
-
}
|
|
348
|
-
async getCurrentCondition() {
|
|
349
|
-
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
|
|
350
|
-
if (connection) return {
|
|
351
|
-
bandwidth: (connection.downlink || 1) * 1e6,
|
|
352
|
-
rtt: connection.rtt || 100,
|
|
353
|
-
connectionType: connection.effectiveType || "unknown"
|
|
354
|
-
};
|
|
355
|
-
const estimatedBandwidth = this.estimateBandwidth();
|
|
356
|
-
return {
|
|
357
|
-
bandwidth: estimatedBandwidth,
|
|
358
|
-
rtt: 100,
|
|
359
|
-
connectionType: "unknown"
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
estimateBandwidth() {
|
|
363
|
-
if (this.measurementHistory.length === 0) return 1e6;
|
|
364
|
-
const average = this.measurementHistory.reduce((a, b) => a + b, 0) / this.measurementHistory.length;
|
|
365
|
-
return Math.max(average, 4e5);
|
|
366
|
-
}
|
|
367
|
-
measureBandwidth(bytes, timeMs) {
|
|
368
|
-
const bandwidth = bytes * 8 / (timeMs / 1e3);
|
|
369
|
-
this.measurementHistory.push(bandwidth);
|
|
370
|
-
if (this.measurementHistory.length > 10) this.measurementHistory.shift();
|
|
371
|
-
}
|
|
372
|
-
};
|
|
373
|
-
export { JitTranscodingClient };
|