@livepeer-frameworks/player-core 0.1.0 → 0.1.2
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 +11 -9
- package/dist/cjs/core/ABRController.js +456 -0
- package/dist/cjs/core/ABRController.js.map +1 -0
- package/dist/cjs/core/CodecUtils.js +195 -0
- package/dist/cjs/core/CodecUtils.js.map +1 -0
- package/dist/cjs/core/ErrorClassifier.js +410 -0
- package/dist/cjs/core/ErrorClassifier.js.map +1 -0
- package/dist/cjs/core/EventEmitter.js +108 -0
- package/dist/cjs/core/EventEmitter.js.map +1 -0
- package/dist/cjs/core/GatewayClient.js +342 -0
- package/dist/cjs/core/GatewayClient.js.map +1 -0
- package/dist/cjs/core/InteractionController.js +606 -0
- package/dist/cjs/core/InteractionController.js.map +1 -0
- package/dist/cjs/core/LiveDurationProxy.js +186 -0
- package/dist/cjs/core/LiveDurationProxy.js.map +1 -0
- package/dist/cjs/core/MetaTrackManager.js +624 -0
- package/dist/cjs/core/MetaTrackManager.js.map +1 -0
- package/dist/cjs/core/MistReporter.js +449 -0
- package/dist/cjs/core/MistReporter.js.map +1 -0
- package/dist/cjs/core/MistSignaling.js +264 -0
- package/dist/cjs/core/MistSignaling.js.map +1 -0
- package/dist/cjs/core/PlayerController.js +2658 -0
- package/dist/cjs/core/PlayerController.js.map +1 -0
- package/dist/cjs/core/PlayerInterface.js +269 -0
- package/dist/cjs/core/PlayerInterface.js.map +1 -0
- package/dist/cjs/core/PlayerManager.js +806 -0
- package/dist/cjs/core/PlayerManager.js.map +1 -0
- package/dist/cjs/core/PlayerRegistry.js +270 -0
- package/dist/cjs/core/PlayerRegistry.js.map +1 -0
- package/dist/cjs/core/QualityMonitor.js +474 -0
- package/dist/cjs/core/QualityMonitor.js.map +1 -0
- package/dist/cjs/core/SeekingUtils.js +292 -0
- package/dist/cjs/core/SeekingUtils.js.map +1 -0
- package/dist/cjs/core/StreamStateClient.js +381 -0
- package/dist/cjs/core/StreamStateClient.js.map +1 -0
- package/dist/cjs/core/SubtitleManager.js +227 -0
- package/dist/cjs/core/SubtitleManager.js.map +1 -0
- package/dist/cjs/core/TelemetryReporter.js +258 -0
- package/dist/cjs/core/TelemetryReporter.js.map +1 -0
- package/dist/cjs/core/TimeFormat.js +176 -0
- package/dist/cjs/core/TimeFormat.js.map +1 -0
- package/dist/cjs/core/TimerManager.js +176 -0
- package/dist/cjs/core/TimerManager.js.map +1 -0
- package/dist/cjs/core/UrlUtils.js +160 -0
- package/dist/cjs/core/UrlUtils.js.map +1 -0
- package/dist/cjs/core/detector.js +293 -0
- package/dist/cjs/core/detector.js.map +1 -0
- package/dist/cjs/core/scorer.js +443 -0
- package/dist/cjs/core/scorer.js.map +1 -0
- package/dist/cjs/index.js +121 -20134
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/utils.js +11 -0
- package/dist/cjs/lib/utils.js.map +1 -0
- package/dist/cjs/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.js +6 -0
- package/dist/cjs/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/cjs/node_modules/.pnpm/tailwind-merge@3.4.0/node_modules/tailwind-merge/dist/bundle-mjs.js +3042 -0
- package/dist/cjs/node_modules/.pnpm/tailwind-merge@3.4.0/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/dist/cjs/players/DashJsPlayer.js +638 -0
- package/dist/cjs/players/DashJsPlayer.js.map +1 -0
- package/dist/cjs/players/HlsJsPlayer.js +482 -0
- package/dist/cjs/players/HlsJsPlayer.js.map +1 -0
- package/dist/cjs/players/MewsWsPlayer/SourceBufferManager.js +522 -0
- package/dist/cjs/players/MewsWsPlayer/SourceBufferManager.js.map +1 -0
- package/dist/cjs/players/MewsWsPlayer/WebSocketManager.js +215 -0
- package/dist/cjs/players/MewsWsPlayer/WebSocketManager.js.map +1 -0
- package/dist/cjs/players/MewsWsPlayer/index.js +987 -0
- package/dist/cjs/players/MewsWsPlayer/index.js.map +1 -0
- package/dist/cjs/players/MistPlayer.js +185 -0
- package/dist/cjs/players/MistPlayer.js.map +1 -0
- package/dist/cjs/players/MistWebRTCPlayer/index.js +635 -0
- package/dist/cjs/players/MistWebRTCPlayer/index.js.map +1 -0
- package/dist/cjs/players/NativePlayer.js +762 -0
- package/dist/cjs/players/NativePlayer.js.map +1 -0
- package/dist/cjs/players/VideoJsPlayer.js +585 -0
- package/dist/cjs/players/VideoJsPlayer.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/JitterBuffer.js +236 -0
- package/dist/cjs/players/WebCodecsPlayer/JitterBuffer.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/LatencyProfiles.js +143 -0
- package/dist/cjs/players/WebCodecsPlayer/LatencyProfiles.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/RawChunkParser.js +96 -0
- package/dist/cjs/players/WebCodecsPlayer/RawChunkParser.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/SyncController.js +359 -0
- package/dist/cjs/players/WebCodecsPlayer/SyncController.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/WebSocketController.js +460 -0
- package/dist/cjs/players/WebCodecsPlayer/WebSocketController.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/index.js +1467 -0
- package/dist/cjs/players/WebCodecsPlayer/index.js.map +1 -0
- package/dist/cjs/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.js +320 -0
- package/dist/cjs/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.js.map +1 -0
- package/dist/cjs/styles/index.js +57 -0
- package/dist/cjs/styles/index.js.map +1 -0
- package/dist/cjs/vanilla/FrameWorksPlayer.js +269 -0
- package/dist/cjs/vanilla/FrameWorksPlayer.js.map +1 -0
- package/dist/cjs/vanilla.js +11 -0
- package/dist/cjs/vanilla.js.map +1 -0
- package/dist/esm/core/ABRController.js +454 -0
- package/dist/esm/core/ABRController.js.map +1 -0
- package/dist/esm/core/CodecUtils.js +193 -0
- package/dist/esm/core/CodecUtils.js.map +1 -0
- package/dist/esm/core/ErrorClassifier.js +408 -0
- package/dist/esm/core/ErrorClassifier.js.map +1 -0
- package/dist/esm/core/EventEmitter.js +106 -0
- package/dist/esm/core/EventEmitter.js.map +1 -0
- package/dist/esm/core/GatewayClient.js +340 -0
- package/dist/esm/core/GatewayClient.js.map +1 -0
- package/dist/esm/core/InteractionController.js +604 -0
- package/dist/esm/core/InteractionController.js.map +1 -0
- package/dist/esm/core/LiveDurationProxy.js +184 -0
- package/dist/esm/core/LiveDurationProxy.js.map +1 -0
- package/dist/esm/core/MetaTrackManager.js +622 -0
- package/dist/esm/core/MetaTrackManager.js.map +1 -0
- package/dist/esm/core/MistReporter.js +447 -0
- package/dist/esm/core/MistReporter.js.map +1 -0
- package/dist/esm/core/MistSignaling.js +262 -0
- package/dist/esm/core/MistSignaling.js.map +1 -0
- package/dist/esm/core/PlayerController.js +2651 -0
- package/dist/esm/core/PlayerController.js.map +1 -0
- package/dist/esm/core/PlayerInterface.js +267 -0
- package/dist/esm/core/PlayerInterface.js.map +1 -0
- package/dist/esm/core/PlayerManager.js +804 -0
- package/dist/esm/core/PlayerManager.js.map +1 -0
- package/dist/esm/core/PlayerRegistry.js +264 -0
- package/dist/esm/core/PlayerRegistry.js.map +1 -0
- package/dist/esm/core/QualityMonitor.js +471 -0
- package/dist/esm/core/QualityMonitor.js.map +1 -0
- package/dist/esm/core/SeekingUtils.js +280 -0
- package/dist/esm/core/SeekingUtils.js.map +1 -0
- package/dist/esm/core/StreamStateClient.js +379 -0
- package/dist/esm/core/StreamStateClient.js.map +1 -0
- package/dist/esm/core/SubtitleManager.js +225 -0
- package/dist/esm/core/SubtitleManager.js.map +1 -0
- package/dist/esm/core/TelemetryReporter.js +256 -0
- package/dist/esm/core/TelemetryReporter.js.map +1 -0
- package/dist/esm/core/TimeFormat.js +169 -0
- package/dist/esm/core/TimeFormat.js.map +1 -0
- package/dist/esm/core/TimerManager.js +174 -0
- package/dist/esm/core/TimerManager.js.map +1 -0
- package/dist/esm/core/UrlUtils.js +151 -0
- package/dist/esm/core/UrlUtils.js.map +1 -0
- package/dist/esm/core/detector.js +279 -0
- package/dist/esm/core/detector.js.map +1 -0
- package/dist/esm/core/scorer.js +422 -0
- package/dist/esm/core/scorer.js.map +1 -0
- package/dist/esm/index.js +26 -20043
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/utils.js +9 -0
- package/dist/esm/lib/utils.js.map +1 -0
- package/dist/esm/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.js +4 -0
- package/dist/esm/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/esm/node_modules/.pnpm/tailwind-merge@3.4.0/node_modules/tailwind-merge/dist/bundle-mjs.js +3036 -0
- package/dist/esm/node_modules/.pnpm/tailwind-merge@3.4.0/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/dist/esm/players/DashJsPlayer.js +636 -0
- package/dist/esm/players/DashJsPlayer.js.map +1 -0
- package/dist/esm/players/HlsJsPlayer.js +480 -0
- package/dist/esm/players/HlsJsPlayer.js.map +1 -0
- package/dist/esm/players/MewsWsPlayer/SourceBufferManager.js +520 -0
- package/dist/esm/players/MewsWsPlayer/SourceBufferManager.js.map +1 -0
- package/dist/esm/players/MewsWsPlayer/WebSocketManager.js +213 -0
- package/dist/esm/players/MewsWsPlayer/WebSocketManager.js.map +1 -0
- package/dist/esm/players/MewsWsPlayer/index.js +985 -0
- package/dist/esm/players/MewsWsPlayer/index.js.map +1 -0
- package/dist/esm/players/MistPlayer.js +183 -0
- package/dist/esm/players/MistPlayer.js.map +1 -0
- package/dist/esm/players/MistWebRTCPlayer/index.js +633 -0
- package/dist/esm/players/MistWebRTCPlayer/index.js.map +1 -0
- package/dist/esm/players/NativePlayer.js +759 -0
- package/dist/esm/players/NativePlayer.js.map +1 -0
- package/dist/esm/players/VideoJsPlayer.js +583 -0
- package/dist/esm/players/VideoJsPlayer.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/JitterBuffer.js +233 -0
- package/dist/esm/players/WebCodecsPlayer/JitterBuffer.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/LatencyProfiles.js +134 -0
- package/dist/esm/players/WebCodecsPlayer/LatencyProfiles.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/RawChunkParser.js +91 -0
- package/dist/esm/players/WebCodecsPlayer/RawChunkParser.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/SyncController.js +357 -0
- package/dist/esm/players/WebCodecsPlayer/SyncController.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/WebSocketController.js +458 -0
- package/dist/esm/players/WebCodecsPlayer/WebSocketController.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/index.js +1458 -0
- package/dist/esm/players/WebCodecsPlayer/index.js.map +1 -0
- package/dist/esm/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.js +315 -0
- package/dist/esm/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.js.map +1 -0
- package/dist/esm/styles/index.js +54 -0
- package/dist/esm/styles/index.js.map +1 -0
- package/dist/esm/vanilla/FrameWorksPlayer.js +264 -0
- package/dist/esm/vanilla/FrameWorksPlayer.js.map +1 -0
- package/dist/esm/vanilla.js +2 -0
- package/dist/esm/vanilla.js.map +1 -0
- package/dist/player.css +185 -42
- package/dist/types/core/ABRController.d.ts +4 -4
- package/dist/types/core/CodecUtils.d.ts +1 -1
- package/dist/types/core/ErrorClassifier.d.ts +77 -0
- package/dist/types/core/GatewayClient.d.ts +4 -4
- package/dist/types/core/MetaTrackManager.d.ts +2 -2
- package/dist/types/core/MistReporter.d.ts +3 -3
- package/dist/types/core/MistSignaling.d.ts +12 -12
- package/dist/types/core/PlayerController.d.ts +19 -14
- package/dist/types/core/PlayerInterface.d.ts +100 -2
- package/dist/types/core/PlayerManager.d.ts +36 -9
- package/dist/types/core/PlayerRegistry.d.ts +11 -11
- package/dist/types/core/QualityMonitor.d.ts +2 -2
- package/dist/types/core/SeekingUtils.d.ts +2 -2
- package/dist/types/core/StreamStateClient.d.ts +2 -2
- package/dist/types/core/TelemetryReporter.d.ts +1 -1
- package/dist/types/core/TimerManager.d.ts +1 -1
- package/dist/types/core/detector.d.ts +1 -1
- package/dist/types/core/index.d.ts +44 -44
- package/dist/types/core/scorer.d.ts +1 -1
- package/dist/types/core/selector.d.ts +2 -2
- package/dist/types/index.d.ts +35 -34
- package/dist/types/players/DashJsPlayer.d.ts +3 -3
- package/dist/types/players/HlsJsPlayer.d.ts +3 -3
- package/dist/types/players/MewsWsPlayer/SourceBufferManager.d.ts +1 -1
- package/dist/types/players/MewsWsPlayer/WebSocketManager.d.ts +1 -1
- package/dist/types/players/MewsWsPlayer/index.d.ts +2 -2
- package/dist/types/players/MewsWsPlayer/types.d.ts +15 -15
- package/dist/types/players/MistPlayer.d.ts +2 -2
- package/dist/types/players/MistWebRTCPlayer/index.d.ts +3 -3
- package/dist/types/players/NativePlayer.d.ts +3 -3
- package/dist/types/players/VideoJsPlayer.d.ts +3 -3
- package/dist/types/players/WebCodecsPlayer/JitterBuffer.d.ts +3 -3
- package/dist/types/players/WebCodecsPlayer/LatencyProfiles.d.ts +1 -1
- package/dist/types/players/WebCodecsPlayer/RawChunkParser.d.ts +2 -2
- package/dist/types/players/WebCodecsPlayer/SyncController.d.ts +2 -2
- package/dist/types/players/WebCodecsPlayer/WebSocketController.d.ts +3 -3
- package/dist/types/players/WebCodecsPlayer/index.d.ts +9 -9
- package/dist/types/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.d.ts +1 -1
- package/dist/types/players/WebCodecsPlayer/types.d.ts +49 -49
- package/dist/types/players/WebCodecsPlayer/worker/types.d.ts +31 -31
- package/dist/types/players/index.d.ts +5 -8
- package/dist/types/types.d.ts +15 -15
- package/dist/types/vanilla/FrameWorksPlayer.d.ts +2 -2
- package/dist/types/vanilla/index.d.ts +4 -4
- package/dist/workers/decoder.worker.js +129 -122
- package/dist/workers/decoder.worker.js.map +1 -1
- package/package.json +31 -15
- package/src/core/ABRController.ts +38 -36
- package/src/core/CodecUtils.ts +49 -46
- package/src/core/Disposable.ts +4 -4
- package/src/core/ErrorClassifier.ts +499 -0
- package/src/core/EventEmitter.ts +1 -1
- package/src/core/GatewayClient.ts +41 -39
- package/src/core/InteractionController.ts +89 -82
- package/src/core/LiveDurationProxy.ts +14 -15
- package/src/core/MetaTrackManager.ts +73 -65
- package/src/core/MistReporter.ts +72 -45
- package/src/core/MistSignaling.ts +59 -56
- package/src/core/PlayerController.ts +542 -384
- package/src/core/PlayerInterface.ts +192 -59
- package/src/core/PlayerManager.ts +354 -164
- package/src/core/PlayerRegistry.ts +238 -87
- package/src/core/QualityMonitor.ts +38 -31
- package/src/core/ScreenWakeLockManager.ts +8 -9
- package/src/core/SeekingUtils.ts +31 -22
- package/src/core/StreamStateClient.ts +74 -68
- package/src/core/SubtitleManager.ts +24 -22
- package/src/core/TelemetryReporter.ts +38 -32
- package/src/core/TimeFormat.ts +13 -17
- package/src/core/TimerManager.ts +24 -8
- package/src/core/UrlUtils.ts +20 -17
- package/src/core/detector.ts +44 -44
- package/src/core/index.ts +57 -48
- package/src/core/scorer.ts +136 -141
- package/src/core/selector.ts +2 -6
- package/src/global.d.ts +1 -1
- package/src/index.ts +56 -36
- package/src/players/DashJsPlayer.ts +164 -115
- package/src/players/HlsJsPlayer.ts +132 -78
- package/src/players/MewsWsPlayer/SourceBufferManager.ts +41 -36
- package/src/players/MewsWsPlayer/WebSocketManager.ts +9 -9
- package/src/players/MewsWsPlayer/index.ts +192 -152
- package/src/players/MewsWsPlayer/types.ts +21 -21
- package/src/players/MistPlayer.ts +45 -26
- package/src/players/MistWebRTCPlayer/index.ts +175 -129
- package/src/players/NativePlayer.ts +203 -143
- package/src/players/VideoJsPlayer.ts +170 -118
- package/src/players/WebCodecsPlayer/JitterBuffer.ts +6 -7
- package/src/players/WebCodecsPlayer/LatencyProfiles.ts +43 -43
- package/src/players/WebCodecsPlayer/RawChunkParser.ts +10 -10
- package/src/players/WebCodecsPlayer/SyncController.ts +45 -53
- package/src/players/WebCodecsPlayer/WebSocketController.ts +66 -68
- package/src/players/WebCodecsPlayer/index.ts +265 -223
- package/src/players/WebCodecsPlayer/polyfills/MediaStreamTrackGenerator.ts +12 -17
- package/src/players/WebCodecsPlayer/types.ts +56 -56
- package/src/players/WebCodecsPlayer/worker/decoder.worker.ts +238 -182
- package/src/players/WebCodecsPlayer/worker/types.ts +31 -31
- package/src/players/index.ts +5 -16
- package/src/styles/animations.css +2 -1
- package/src/styles/player.css +185 -42
- package/src/styles/tailwind.css +473 -159
- package/src/types.ts +43 -43
- package/src/vanilla/FrameWorksPlayer.ts +26 -14
- package/src/vanilla/index.ts +4 -4
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { ABRMode, ABROptions, PlaybackQuality, QualityLevel } from
|
|
2
|
-
import { TimerManager } from
|
|
1
|
+
import type { ABRMode, ABROptions, PlaybackQuality, QualityLevel } from "../types";
|
|
2
|
+
import { TimerManager } from "./TimerManager";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Default ABR options
|
|
6
6
|
*/
|
|
7
7
|
const DEFAULT_OPTIONS: Required<ABROptions> = {
|
|
8
|
-
mode:
|
|
8
|
+
mode: "auto",
|
|
9
9
|
maxResolution: { width: 1920, height: 1080 },
|
|
10
10
|
maxBitrate: 8000000, // 8 Mbps
|
|
11
11
|
minBufferForUpgrade: 10,
|
|
@@ -18,7 +18,7 @@ export interface ABRControllerConfig {
|
|
|
18
18
|
/** Callback to get available qualities */
|
|
19
19
|
getQualities: () => QualityLevel[];
|
|
20
20
|
/** Callback to select a quality */
|
|
21
|
-
selectQuality: (id: string |
|
|
21
|
+
selectQuality: (id: string | "auto") => void;
|
|
22
22
|
/** Callback to get current quality */
|
|
23
23
|
getCurrentQuality?: () => QualityLevel | null;
|
|
24
24
|
/** Callback to get bandwidth estimate (bits per second) - typically from player stats */
|
|
@@ -27,7 +27,7 @@ export interface ABRControllerConfig {
|
|
|
27
27
|
debug?: boolean;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export type ABRDecision =
|
|
30
|
+
export type ABRDecision = "upgrade" | "downgrade" | "maintain" | "none";
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* ABRController - Adaptive Bitrate Controller
|
|
@@ -54,8 +54,8 @@ export class ABRController {
|
|
|
54
54
|
private options: Required<ABROptions>;
|
|
55
55
|
private config: ABRControllerConfig;
|
|
56
56
|
private videoElement: HTMLVideoElement | null = null;
|
|
57
|
-
private currentQualityId: string |
|
|
58
|
-
private lastDecision: ABRDecision =
|
|
57
|
+
private currentQualityId: string | "auto" = "auto";
|
|
58
|
+
private lastDecision: ABRDecision = "none";
|
|
59
59
|
private lastDecisionTime = 0;
|
|
60
60
|
private resizeObserver: ResizeObserver | null = null;
|
|
61
61
|
private qualityChangeCallbacks: Array<(level: QualityLevel) => void> = [];
|
|
@@ -96,18 +96,18 @@ export class ABRController {
|
|
|
96
96
|
this.stop();
|
|
97
97
|
this.videoElement = videoElement;
|
|
98
98
|
|
|
99
|
-
if (this.options.mode ===
|
|
100
|
-
this.log(
|
|
99
|
+
if (this.options.mode === "manual") {
|
|
100
|
+
this.log("Manual mode - no automatic ABR");
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
// Setup resize observer for ABR_resize mode
|
|
105
|
-
if (this.options.mode ===
|
|
105
|
+
if (this.options.mode === "resize" || this.options.mode === "auto") {
|
|
106
106
|
this.setupResizeObserver();
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
// Start active bandwidth monitoring for bitrate mode
|
|
110
|
-
if (this.options.mode ===
|
|
110
|
+
if (this.options.mode === "bitrate" || this.options.mode === "auto") {
|
|
111
111
|
this.startActiveMonitoring();
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -133,7 +133,7 @@ export class ABRController {
|
|
|
133
133
|
this.timers.startInterval(
|
|
134
134
|
() => this.checkBandwidthAndSwitch(),
|
|
135
135
|
ABRController.MONITORING_INTERVAL_MS,
|
|
136
|
-
|
|
136
|
+
"monitoring"
|
|
137
137
|
);
|
|
138
138
|
|
|
139
139
|
// Initial check
|
|
@@ -182,8 +182,10 @@ export class ABRController {
|
|
|
182
182
|
if (smoothedBandwidth < currentBitrate * ABRController.DOWNGRADE_THRESHOLD) {
|
|
183
183
|
const lowerQuality = this.findLowerQuality(qualities, currentQuality);
|
|
184
184
|
if (lowerQuality) {
|
|
185
|
-
this.log(
|
|
186
|
-
|
|
185
|
+
this.log(
|
|
186
|
+
`ABR: bandwidth ${Math.round(smoothedBandwidth / 1000)}kbps < ${Math.round((currentBitrate * ABRController.DOWNGRADE_THRESHOLD) / 1000)}kbps threshold -> downgrading to ${lowerQuality.label}`
|
|
187
|
+
);
|
|
188
|
+
this.lastDecision = "downgrade";
|
|
187
189
|
this.lastDecisionTime = now;
|
|
188
190
|
this.lastDowngradeTime = now;
|
|
189
191
|
this.selectQuality(lowerQuality.id);
|
|
@@ -201,11 +203,14 @@ export class ABRController {
|
|
|
201
203
|
// D2: Hysteresis - require 1.5x headroom to upgrade
|
|
202
204
|
// Once at a quality level, stay until bandwidth drops below 1.2x (not 1.0x)
|
|
203
205
|
const shouldUpgrade = smoothedBandwidth >= targetBitrate * ABRController.UPGRADE_HEADROOM;
|
|
204
|
-
const _canHoldHigher =
|
|
206
|
+
const _canHoldHigher =
|
|
207
|
+
smoothedBandwidth >= targetBitrate * ABRController.UPGRADE_HOLD_THRESHOLD;
|
|
205
208
|
|
|
206
209
|
if (shouldUpgrade) {
|
|
207
|
-
this.log(
|
|
208
|
-
|
|
210
|
+
this.log(
|
|
211
|
+
`ABR: bandwidth ${Math.round(smoothedBandwidth / 1000)}kbps >= ${Math.round((targetBitrate * ABRController.UPGRADE_HEADROOM) / 1000)}kbps headroom -> upgrading to ${higherQuality.label}`
|
|
212
|
+
);
|
|
213
|
+
this.lastDecision = "upgrade";
|
|
209
214
|
this.lastDecisionTime = now;
|
|
210
215
|
this.lastUpgradeTime = now;
|
|
211
216
|
this.selectQuality(higherQuality.id);
|
|
@@ -282,7 +287,7 @@ export class ABRController {
|
|
|
282
287
|
* Handle viewport resize (ABR_resize mode)
|
|
283
288
|
*/
|
|
284
289
|
private handleResize(width: number, height: number): void {
|
|
285
|
-
if (this.options.mode !==
|
|
290
|
+
if (this.options.mode !== "resize" && this.options.mode !== "auto") {
|
|
286
291
|
return;
|
|
287
292
|
}
|
|
288
293
|
|
|
@@ -291,7 +296,10 @@ export class ABRController {
|
|
|
291
296
|
|
|
292
297
|
// Find best quality for viewport size
|
|
293
298
|
const targetWidth = Math.min(width * window.devicePixelRatio, this.options.maxResolution.width);
|
|
294
|
-
const targetHeight = Math.min(
|
|
299
|
+
const targetHeight = Math.min(
|
|
300
|
+
height * window.devicePixelRatio,
|
|
301
|
+
this.options.maxResolution.height
|
|
302
|
+
);
|
|
295
303
|
|
|
296
304
|
const bestQuality = this.findBestQualityForResolution(qualities, targetWidth, targetHeight);
|
|
297
305
|
|
|
@@ -307,7 +315,7 @@ export class ABRController {
|
|
|
307
315
|
* Called by QualityMonitor when playback quality drops
|
|
308
316
|
*/
|
|
309
317
|
handleQualityDegraded(quality: PlaybackQuality): void {
|
|
310
|
-
if (this.options.mode !==
|
|
318
|
+
if (this.options.mode !== "bitrate" && this.options.mode !== "auto") {
|
|
311
319
|
return;
|
|
312
320
|
}
|
|
313
321
|
|
|
@@ -327,7 +335,7 @@ export class ABRController {
|
|
|
327
335
|
|
|
328
336
|
if (lowerQuality) {
|
|
329
337
|
this.log(`Bitrate ABR: score ${quality.score} -> downgrading to ${lowerQuality.label}`);
|
|
330
|
-
this.lastDecision =
|
|
338
|
+
this.lastDecision = "downgrade";
|
|
331
339
|
this.lastDecisionTime = now;
|
|
332
340
|
this.lastDowngradeTime = now;
|
|
333
341
|
this.selectQuality(lowerQuality.id);
|
|
@@ -342,7 +350,7 @@ export class ABRController {
|
|
|
342
350
|
* Called when conditions are good enough to try higher quality
|
|
343
351
|
*/
|
|
344
352
|
handleQualityImproved(quality: PlaybackQuality): void {
|
|
345
|
-
if (this.options.mode !==
|
|
353
|
+
if (this.options.mode !== "bitrate" && this.options.mode !== "auto") {
|
|
346
354
|
return;
|
|
347
355
|
}
|
|
348
356
|
|
|
@@ -363,7 +371,7 @@ export class ABRController {
|
|
|
363
371
|
|
|
364
372
|
if (higherQuality && this.isWithinConstraints(higherQuality)) {
|
|
365
373
|
this.log(`Bitrate ABR: score ${quality.score} -> upgrading to ${higherQuality.label}`);
|
|
366
|
-
this.lastDecision =
|
|
374
|
+
this.lastDecision = "upgrade";
|
|
367
375
|
this.lastDecisionTime = now;
|
|
368
376
|
this.lastUpgradeTime = now;
|
|
369
377
|
this.selectQuality(higherQuality.id);
|
|
@@ -381,7 +389,7 @@ export class ABRController {
|
|
|
381
389
|
targetHeight: number
|
|
382
390
|
): QualityLevel | null {
|
|
383
391
|
// Filter out qualities that exceed constraints
|
|
384
|
-
const validQualities = qualities.filter(q => this.isWithinConstraints(q));
|
|
392
|
+
const validQualities = qualities.filter((q) => this.isWithinConstraints(q));
|
|
385
393
|
|
|
386
394
|
if (validQualities.length === 0) return null;
|
|
387
395
|
|
|
@@ -409,10 +417,7 @@ export class ABRController {
|
|
|
409
417
|
/**
|
|
410
418
|
* Find a lower quality level
|
|
411
419
|
*/
|
|
412
|
-
private findLowerQuality(
|
|
413
|
-
qualities: QualityLevel[],
|
|
414
|
-
current: QualityLevel
|
|
415
|
-
): QualityLevel | null {
|
|
420
|
+
private findLowerQuality(qualities: QualityLevel[], current: QualityLevel): QualityLevel | null {
|
|
416
421
|
const currentBitrate = current.bitrate ?? 0;
|
|
417
422
|
|
|
418
423
|
// Sort by bitrate descending
|
|
@@ -431,10 +436,7 @@ export class ABRController {
|
|
|
431
436
|
/**
|
|
432
437
|
* Find a higher quality level
|
|
433
438
|
*/
|
|
434
|
-
private findHigherQuality(
|
|
435
|
-
qualities: QualityLevel[],
|
|
436
|
-
current: QualityLevel
|
|
437
|
-
): QualityLevel | null {
|
|
439
|
+
private findHigherQuality(qualities: QualityLevel[], current: QualityLevel): QualityLevel | null {
|
|
438
440
|
const currentBitrate = current.bitrate ?? 0;
|
|
439
441
|
|
|
440
442
|
// Sort by bitrate ascending
|
|
@@ -466,15 +468,15 @@ export class ABRController {
|
|
|
466
468
|
/**
|
|
467
469
|
* Select a quality level
|
|
468
470
|
*/
|
|
469
|
-
private selectQuality(id: string |
|
|
471
|
+
private selectQuality(id: string | "auto"): void {
|
|
470
472
|
this.currentQualityId = id;
|
|
471
473
|
this.config.selectQuality(id);
|
|
472
474
|
|
|
473
475
|
// Notify callbacks
|
|
474
476
|
const qualities = this.config.getQualities();
|
|
475
|
-
const selected = qualities.find(q => q.id === id);
|
|
477
|
+
const selected = qualities.find((q) => q.id === id);
|
|
476
478
|
if (selected) {
|
|
477
|
-
this.qualityChangeCallbacks.forEach(cb => cb(selected));
|
|
479
|
+
this.qualityChangeCallbacks.forEach((cb) => cb(selected));
|
|
478
480
|
}
|
|
479
481
|
}
|
|
480
482
|
|
|
@@ -494,7 +496,7 @@ export class ABRController {
|
|
|
494
496
|
/**
|
|
495
497
|
* Manually set quality (switches to manual mode temporarily)
|
|
496
498
|
*/
|
|
497
|
-
setQuality(id: string |
|
|
499
|
+
setQuality(id: string | "auto"): void {
|
|
498
500
|
this.selectQuality(id);
|
|
499
501
|
}
|
|
500
502
|
|
package/src/core/CodecUtils.ts
CHANGED
|
@@ -40,61 +40,61 @@ export function translateCodec(track: TrackInfo): string {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
// Audio codecs
|
|
43
|
-
if (track.type ===
|
|
43
|
+
if (track.type === "audio") {
|
|
44
44
|
switch (codec) {
|
|
45
|
-
case
|
|
46
|
-
case
|
|
47
|
-
return
|
|
48
|
-
case
|
|
49
|
-
return
|
|
50
|
-
case
|
|
51
|
-
case
|
|
52
|
-
return
|
|
53
|
-
case
|
|
54
|
-
case
|
|
55
|
-
case
|
|
56
|
-
case
|
|
57
|
-
return
|
|
58
|
-
case
|
|
59
|
-
return
|
|
60
|
-
case
|
|
61
|
-
return
|
|
62
|
-
case
|
|
63
|
-
return
|
|
64
|
-
case
|
|
65
|
-
case
|
|
66
|
-
return
|
|
45
|
+
case "AAC":
|
|
46
|
+
case "MP4A":
|
|
47
|
+
return "mp4a.40.2"; // AAC-LC
|
|
48
|
+
case "MP3":
|
|
49
|
+
return "mp4a.40.34"; // MP3 in MP4 container
|
|
50
|
+
case "AC3":
|
|
51
|
+
case "AC-3":
|
|
52
|
+
return "ac-3";
|
|
53
|
+
case "EAC3":
|
|
54
|
+
case "EC3":
|
|
55
|
+
case "E-AC3":
|
|
56
|
+
case "EC-3":
|
|
57
|
+
return "ec-3";
|
|
58
|
+
case "OPUS":
|
|
59
|
+
return "opus";
|
|
60
|
+
case "VORBIS":
|
|
61
|
+
return "vorbis";
|
|
62
|
+
case "FLAC":
|
|
63
|
+
return "flac";
|
|
64
|
+
case "PCM":
|
|
65
|
+
case "PCMS16LE":
|
|
66
|
+
return "pcm";
|
|
67
67
|
default:
|
|
68
68
|
return codec.toLowerCase();
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
// Video codecs
|
|
73
|
-
if (track.type ===
|
|
73
|
+
if (track.type === "video") {
|
|
74
74
|
switch (codec) {
|
|
75
|
-
case
|
|
76
|
-
case
|
|
77
|
-
case
|
|
75
|
+
case "H264":
|
|
76
|
+
case "AVC":
|
|
77
|
+
case "AVC1": {
|
|
78
78
|
// Try to extract profile/level from init data
|
|
79
79
|
const profileLevel = extractH264Profile(track.init);
|
|
80
|
-
return profileLevel ||
|
|
80
|
+
return profileLevel || "avc1.42E01E"; // Default: Baseline Profile, Level 3.0
|
|
81
81
|
}
|
|
82
|
-
case
|
|
83
|
-
case
|
|
84
|
-
case
|
|
85
|
-
case
|
|
82
|
+
case "H265":
|
|
83
|
+
case "HEVC":
|
|
84
|
+
case "HEV1":
|
|
85
|
+
case "HVC1": {
|
|
86
86
|
// Try to extract profile/level from init data
|
|
87
87
|
const profileLevel = extractHEVCProfile(track.init);
|
|
88
|
-
return profileLevel ||
|
|
88
|
+
return profileLevel || "hev1.1.6.L93.B0"; // Default: Main Profile, Level 3.1
|
|
89
89
|
}
|
|
90
|
-
case
|
|
91
|
-
return
|
|
92
|
-
case
|
|
93
|
-
return
|
|
94
|
-
case
|
|
95
|
-
return
|
|
96
|
-
case
|
|
97
|
-
return
|
|
90
|
+
case "VP8":
|
|
91
|
+
return "vp8";
|
|
92
|
+
case "VP9":
|
|
93
|
+
return "vp09.00.10.08"; // Profile 0, Level 1.0, 8-bit
|
|
94
|
+
case "AV1":
|
|
95
|
+
return "av01.0.01M.08"; // Main Profile, Level 2.1, 8-bit
|
|
96
|
+
case "THEORA":
|
|
97
|
+
return "theora";
|
|
98
98
|
default:
|
|
99
99
|
return codec.toLowerCase();
|
|
100
100
|
}
|
|
@@ -199,7 +199,7 @@ function extractHEVCProfile(init?: string): string | null {
|
|
|
199
199
|
* Convert byte to 2-digit hex string
|
|
200
200
|
*/
|
|
201
201
|
function toHex(byte: number): string {
|
|
202
|
-
return byte.toString(16).padStart(2,
|
|
202
|
+
return byte.toString(16).padStart(2, "0").toUpperCase();
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
/**
|
|
@@ -221,8 +221,8 @@ function base64ToBytes(base64: string): Uint8Array {
|
|
|
221
221
|
* @param containerType - Container type (default: 'video/mp4')
|
|
222
222
|
* @returns true if supported
|
|
223
223
|
*/
|
|
224
|
-
export function isCodecSupported(codecString: string, containerType =
|
|
225
|
-
if (typeof MediaSource ===
|
|
224
|
+
export function isCodecSupported(codecString: string, containerType = "video/mp4"): boolean {
|
|
225
|
+
if (typeof MediaSource === "undefined" || !MediaSource.isTypeSupported) {
|
|
226
226
|
return false;
|
|
227
227
|
}
|
|
228
228
|
|
|
@@ -237,8 +237,11 @@ export function isCodecSupported(codecString: string, containerType = 'video/mp4
|
|
|
237
237
|
* @param type - Track type to filter ('video' or 'audio')
|
|
238
238
|
* @returns Best supported track or null
|
|
239
239
|
*/
|
|
240
|
-
export function getBestSupportedTrack(
|
|
241
|
-
|
|
240
|
+
export function getBestSupportedTrack(
|
|
241
|
+
tracks: TrackInfo[],
|
|
242
|
+
type: "video" | "audio"
|
|
243
|
+
): TrackInfo | null {
|
|
244
|
+
const filteredTracks = tracks.filter((t) => t.type === type);
|
|
242
245
|
|
|
243
246
|
for (const track of filteredTracks) {
|
|
244
247
|
const codecString = translateCodec(track);
|
package/src/core/Disposable.ts
CHANGED
|
@@ -57,7 +57,7 @@ export abstract class BaseDisposable implements Disposable {
|
|
|
57
57
|
* Throw if this object has been disposed.
|
|
58
58
|
* Use at the start of methods that shouldn't run after disposal.
|
|
59
59
|
*/
|
|
60
|
-
protected throwIfDisposed(operation: string =
|
|
60
|
+
protected throwIfDisposed(operation: string = "operation"): void {
|
|
61
61
|
if (this._disposed) {
|
|
62
62
|
throw new Error(`Cannot perform ${operation} on disposed object`);
|
|
63
63
|
}
|
|
@@ -80,7 +80,7 @@ export function disposeAll(...disposables: (Disposable | null | undefined)[]): v
|
|
|
80
80
|
try {
|
|
81
81
|
d.dispose();
|
|
82
82
|
} catch (err) {
|
|
83
|
-
console.warn(
|
|
83
|
+
console.warn("[Disposable] Error during disposal:", err);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -104,13 +104,13 @@ export function createCompositeDisposable(
|
|
|
104
104
|
|
|
105
105
|
for (const d of disposables) {
|
|
106
106
|
try {
|
|
107
|
-
if (typeof d ===
|
|
107
|
+
if (typeof d === "function") {
|
|
108
108
|
d();
|
|
109
109
|
} else if (d && !d.disposed) {
|
|
110
110
|
d.dispose();
|
|
111
111
|
}
|
|
112
112
|
} catch (err) {
|
|
113
|
-
console.warn(
|
|
113
|
+
console.warn("[CompositeDisposable] Error during disposal:", err);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
},
|