@codercms/web-player 0.0.37 → 0.0.41
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/core/AudioCtx/AudioContext.d.ts +2 -0
- package/dist/core/AudioCtx/AudioContext.js +92 -0
- package/dist/core/AudioCtx/AudioContext.js.map +1 -0
- package/dist/core/Loaders/BaseLoader.d.ts +17 -0
- package/dist/core/Loaders/BaseLoader.js +50 -0
- package/dist/core/Loaders/BaseLoader.js.map +1 -0
- package/dist/core/Loaders/HLSLoader.d.ts +17 -0
- package/dist/core/Loaders/HLSLoader.js +313 -0
- package/dist/core/Loaders/HLSLoader.js.map +1 -0
- package/dist/core/{LoaderInterface.d.ts → Loaders/LoaderInterface.d.ts} +11 -3
- package/dist/core/{LoaderInterface.js → Loaders/LoaderInterface.js} +6 -0
- package/dist/core/{LoaderInterface.js.map → Loaders/LoaderInterface.js.map} +1 -1
- package/dist/core/Loaders/NativeAudioTrackList.d.ts +39 -0
- package/dist/core/Loaders/NativeAudioTrackList.js.map +1 -0
- package/dist/core/Loaders/NativeLoader.d.ts +16 -0
- package/dist/core/Loaders/NativeLoader.js +114 -0
- package/dist/core/Loaders/NativeLoader.js.map +1 -0
- package/dist/core/Playlist.d.ts +4 -3
- package/dist/core/Playlist.js.map +1 -1
- package/dist/core/PlaylistPlayer.d.ts +3 -2
- package/dist/core/PlaylistPlayer.js +5 -3
- package/dist/core/PlaylistPlayer.js.map +1 -1
- package/dist/core/VideoPlayer.d.ts +19 -191
- package/dist/core/VideoPlayer.js +92 -594
- package/dist/core/VideoPlayer.js.map +1 -1
- package/dist/core/VideoPlayerEvents.d.ts +74 -0
- package/dist/core/VideoPlayerEvents.js +40 -0
- package/dist/core/VideoPlayerEvents.js.map +1 -0
- package/dist/core/VideoPlayerMediaLoadManager.d.ts +50 -0
- package/dist/core/VideoPlayerMediaLoadManager.js +269 -0
- package/dist/core/VideoPlayerMediaLoadManager.js.map +1 -0
- package/dist/core/VideoPlayerMediaState.d.ts +39 -0
- package/dist/core/VideoPlayerMediaState.js +161 -0
- package/dist/core/VideoPlayerMediaState.js.map +1 -0
- package/dist/core/VideoPlayerMediaStateProxy.d.ts +17 -0
- package/dist/core/VideoPlayerMediaStateProxy.js +42 -0
- package/dist/core/VideoPlayerMediaStateProxy.js.map +1 -0
- package/dist/core/svelte/VideoPlayerMediaStateSvelteStore.d.ts +58 -0
- package/dist/core/svelte/VideoPlayerMediaStateSvelteStore.js +146 -0
- package/dist/core/svelte/VideoPlayerMediaStateSvelteStore.js.map +1 -0
- package/dist/core/types/BufferedPart.d.ts +4 -0
- package/dist/core/types/BufferedPart.js +1 -0
- package/dist/core/types/BufferedPart.js.map +1 -0
- package/dist/core/types/PlayerLoadParams.d.ts +11 -0
- package/dist/core/types/PlayerLoadParams.js +1 -0
- package/dist/core/types/PlayerLoadParams.js.map +1 -0
- package/dist/core/types/QualityLevel.js +1 -0
- package/dist/core/types/index.d.ts +4 -0
- package/dist/core/types/index.js +1 -0
- package/dist/core/types/index.js.map +1 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +9 -4
- package/dist/ui/LoadingIndicator.svelte +35 -16
- package/dist/ui/LoadingIndicator.svelte.d.ts +1 -1
- package/dist/ui/ProgressBar.svelte +7 -8
- package/dist/ui/ProgressBar.svelte.d.ts +1 -1
- package/package.json +1 -1
- package/dist/HybridDoublyLinkedList.d.ts +0 -20
- package/dist/HybridDoublyLinkedList.js +0 -90
- package/dist/HybridDoublyLinkedList.js.map +0 -1
- package/dist/HybridLinkedList.d.ts +0 -18
- package/dist/HybridLinkedList.js +0 -90
- package/dist/HybridLinkedList.js.map +0 -1
- package/dist/core/HLSLoader.d.ts +0 -19
- package/dist/core/HLSLoader.js +0 -196
- package/dist/core/HLSLoader.js.map +0 -1
- package/dist/core/NativeLoader.d.ts +0 -14
- package/dist/core/NativeLoader.js +0 -66
- package/dist/core/NativeLoader.js.map +0 -1
- /package/dist/core/{AudioTrack.js → Loaders/NativeAudioTrackList.js} +0 -0
- /package/dist/core/{AudioTrack.d.ts → types/AudioTrack.d.ts} +0 -0
- /package/dist/core/{QualityLevel.js → types/AudioTrack.js} +0 -0
- /package/dist/core/{AudioTrack.js.map → types/AudioTrack.js.map} +0 -0
- /package/dist/core/{QualityLevel.d.ts → types/QualityLevel.d.ts} +0 -0
- /package/dist/core/{QualityLevel.js.map → types/QualityLevel.js.map} +0 -0
package/dist/core/VideoPlayer.js
CHANGED
|
@@ -1,124 +1,30 @@
|
|
|
1
1
|
import { EventEmitter } from 'eventemitter3';
|
|
2
|
-
import { readonly, writable } from 'svelte/store';
|
|
3
|
-
import { HLSLoader, isHlsJsSupported } from './HLSLoader.js';
|
|
4
|
-
import { NativeLoader } from './NativeLoader.js';
|
|
5
|
-
import { LoaderEvents } from './LoaderInterface.js';
|
|
6
|
-
import { DOMEventRegistry } from './DOMEventRegistry.js';
|
|
7
2
|
import screenfull from 'screenfull';
|
|
8
3
|
import { BROWSER } from 'esm-env';
|
|
4
|
+
import { HLSLoader, IS_HLS_JS_SUPPORTED } from './Loaders/HLSLoader.js';
|
|
5
|
+
import { NativeLoader } from './Loaders/NativeLoader.js';
|
|
6
|
+
import { DOMEventRegistry } from './DOMEventRegistry.js';
|
|
7
|
+
import { PlayerEvents } from './VideoPlayerEvents.js';
|
|
8
|
+
import { VideoPlayerMediaState } from './VideoPlayerMediaState.js';
|
|
9
9
|
import { IS_IOS, IS_IPAD_NEW } from '../ui/utils/ios.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
PlayerEvents["Seeking"] = "player.seeking";
|
|
18
|
-
PlayerEvents["Seeked"] = "player.seeked";
|
|
19
|
-
PlayerEvents["MediaElementAttached"] = "player.mediaElementAttached";
|
|
20
|
-
PlayerEvents["MediaElementDetached"] = "player.mediaElementDetached";
|
|
21
|
-
PlayerEvents["ContainerElementAttached"] = "player.containerElementAttached";
|
|
22
|
-
PlayerEvents["ContainerElementDetached"] = "player.containerElementDetached";
|
|
23
|
-
PlayerEvents["FullScreenEnter"] = "player.fullscreenEnter";
|
|
24
|
-
PlayerEvents["FullScreenExit"] = "player.fullscreenExit";
|
|
25
|
-
PlayerEvents["FullScreenToggle"] = "player.fullscreenToggle";
|
|
26
|
-
// LoadingStarted happens when player's load method called
|
|
27
|
-
PlayerEvents["LoadingStarted"] = "player.loadingStarted";
|
|
28
|
-
// LoadingMetadataEnded happens when loader process has been completed
|
|
29
|
-
PlayerEvents["LoadingMetadataEnded"] = "player.loadingMetadataEnded";
|
|
30
|
-
// LoadingMetadataFailed happens when loader fails to load video
|
|
31
|
-
PlayerEvents["LoadingMetadataFailed"] = "player.loadingMedataFailed";
|
|
32
|
-
// LoadingEnded happens when metadata loading is done and there's also initial video content fetched
|
|
33
|
-
PlayerEvents["LoadingEnded"] = "player.loadingEnded";
|
|
34
|
-
PlayerEvents["BufferingStarted"] = "player.bufferingStarted";
|
|
35
|
-
PlayerEvents["BufferingEnded"] = "player.bufferingEnded";
|
|
36
|
-
PlayerEvents["PlaybackBufferingProgress"] = "player.bufferingProgress";
|
|
37
|
-
PlayerEvents["PlaybackDurationChange"] = "player.durationChange";
|
|
38
|
-
PlayerEvents["PlaybackTimeUpdate"] = "player.timeUpdate";
|
|
39
|
-
PlayerEvents["PlaybackRateChange"] = "player.playbackRateChange";
|
|
40
|
-
PlayerEvents["VolumeChange"] = "player.volumeChange";
|
|
41
|
-
PlayerEvents["MuteChange"] = "player.muteChange";
|
|
42
|
-
PlayerEvents["VolumeStateChange"] = "player.volumeStateChange";
|
|
43
|
-
PlayerEvents["QualityLevelsUpdated"] = "player.qualityLevelsUpdated";
|
|
44
|
-
PlayerEvents["QualityLevelSwitching"] = "player.qualityLevelSwitching";
|
|
45
|
-
PlayerEvents["QualityLevelSwitched"] = "player.qualityLevelSwitched";
|
|
46
|
-
PlayerEvents["AudioTracksUpdated"] = "player.audioTracksUpdated";
|
|
47
|
-
PlayerEvents["AudioTrackSwitching"] = "player.audioTrackSwitching";
|
|
48
|
-
PlayerEvents["AudioTrackSwitched"] = "player.audioTrackSwitched";
|
|
49
|
-
})(PlayerEvents || (PlayerEvents = {}));
|
|
50
|
-
export var Loader;
|
|
51
|
-
(function (Loader) {
|
|
52
|
-
Loader[Loader["Native"] = 0] = "Native";
|
|
53
|
-
Loader[Loader["HLS"] = 1] = "HLS";
|
|
54
|
-
Loader[Loader["DASH"] = 2] = "DASH";
|
|
55
|
-
})(Loader || (Loader = {}));
|
|
56
|
-
async function getLoadUrl(paramsUrl, signal) {
|
|
57
|
-
let url;
|
|
58
|
-
if (typeof paramsUrl === 'string') {
|
|
59
|
-
url = paramsUrl;
|
|
60
|
-
}
|
|
61
|
-
else if (typeof paramsUrl === 'function') {
|
|
62
|
-
url = await paramsUrl(signal);
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
url = await paramsUrl;
|
|
66
|
-
}
|
|
67
|
-
if (!url || !url.length) {
|
|
68
|
-
throw Error('Bad load url');
|
|
69
|
-
}
|
|
70
|
-
return url;
|
|
71
|
-
}
|
|
72
|
-
export var VideoLoadingState;
|
|
73
|
-
(function (VideoLoadingState) {
|
|
74
|
-
VideoLoadingState[VideoLoadingState["LoadingMetadata"] = 0] = "LoadingMetadata";
|
|
75
|
-
VideoLoadingState[VideoLoadingState["LoadingData"] = 1] = "LoadingData";
|
|
76
|
-
VideoLoadingState[VideoLoadingState["LoadingDone"] = 2] = "LoadingDone";
|
|
77
|
-
VideoLoadingState[VideoLoadingState["LoadingFailed"] = 3] = "LoadingFailed";
|
|
78
|
-
})(VideoLoadingState || (VideoLoadingState = {}));
|
|
10
|
+
import { VideoLoadingState, VideoPlayerMediaLoadManager } from './VideoPlayerMediaLoadManager.js';
|
|
11
|
+
import { VideoPlayerMediaStateProxy } from './VideoPlayerMediaStateProxy.js';
|
|
12
|
+
import { VideoPlayerMediaStateSvelteStore } from './svelte/VideoPlayerMediaStateSvelteStore.js';
|
|
13
|
+
export { IS_AUDIO_CONTEXT_SUPPORTED, IS_AUDIO_GAIN_SUPPORTED } from './AudioCtx/AudioContext.js';
|
|
14
|
+
export const IS_VOLUME_CHANGE_ALLOWED = BROWSER &&
|
|
15
|
+
Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'volume')?.set !== undefined;
|
|
16
|
+
export const IS_FULLSCREEN_ALLOWED = BROWSER && screenfull.isEnabled;
|
|
79
17
|
export class VideoPlayer {
|
|
80
|
-
static _isFullScreenAllowed = screenfull.isEnabled;
|
|
81
18
|
_el;
|
|
82
19
|
_containerEl;
|
|
83
20
|
elEventsRegistry;
|
|
84
21
|
_cfg;
|
|
85
22
|
emitter = new EventEmitter();
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
_loadingState = VideoLoadingState.LoadingDone;
|
|
91
|
-
// _isBuffering indicates is there and buffering process which block playback
|
|
92
|
-
_isBuffering = false;
|
|
93
|
-
// _isLoading flag indicates combined state of buffering + video loading progress
|
|
94
|
-
_isLoading = false;
|
|
23
|
+
_mediaState = new VideoPlayerMediaState(this.emitter);
|
|
24
|
+
_mediaStateProxy = null;
|
|
25
|
+
_mediaStateSvelteStore = null;
|
|
26
|
+
_loadingMgr = new VideoPlayerMediaLoadManager(this.emitter, this._mediaState);
|
|
95
27
|
_isFullScreen = false;
|
|
96
|
-
_paused = true;
|
|
97
|
-
_duration = 0;
|
|
98
|
-
_currentTime = 0;
|
|
99
|
-
_playbackRate = 0;
|
|
100
|
-
_muted = false;
|
|
101
|
-
_volume = 1;
|
|
102
|
-
_buffered = [];
|
|
103
|
-
_isAutoQuality = true;
|
|
104
|
-
_currentQualityLevel = null;
|
|
105
|
-
_qualityLevels = [];
|
|
106
|
-
_currentAudioTrack = null;
|
|
107
|
-
_audioTracks = [];
|
|
108
|
-
_isFullScreenStore = writable(this._isFullScreen);
|
|
109
|
-
_isLoadingStore = writable(this._isLoading);
|
|
110
|
-
_pausedStore = writable(this._paused);
|
|
111
|
-
_durationStore = writable(this._duration);
|
|
112
|
-
_currentTimeStore = writable(this._currentTime);
|
|
113
|
-
_playbackRateStore = writable(this._playbackRate);
|
|
114
|
-
_mutedStore = writable(this._muted);
|
|
115
|
-
_volumeStore = writable(this._volume);
|
|
116
|
-
_bufferedStore = writable(this._buffered);
|
|
117
|
-
_isAutoQualityStore = writable(this._isAutoQuality);
|
|
118
|
-
_currentQualityLevelStore = writable(this._currentQualityLevel);
|
|
119
|
-
_qualityLevelsStore = writable(this._qualityLevels);
|
|
120
|
-
_currentAudioTrackStore = writable(this._currentAudioTrack);
|
|
121
|
-
_audioTracksStore = writable(this._audioTracks);
|
|
122
28
|
constructor(el, cfg) {
|
|
123
29
|
this._cfg = cfg ?? {};
|
|
124
30
|
// Do nothing in SSR environment
|
|
@@ -128,27 +34,22 @@ export class VideoPlayer {
|
|
|
128
34
|
if (el) {
|
|
129
35
|
this.attachEl(el);
|
|
130
36
|
}
|
|
131
|
-
if (
|
|
37
|
+
if (IS_FULLSCREEN_ALLOWED) {
|
|
132
38
|
screenfull.on('change', this._onFullScreenChange.bind(this));
|
|
133
39
|
}
|
|
134
|
-
this.emitter.on(LoaderEvents.QualityLevelsUpdated, this._onLoaderQualityLevelsUpdated.bind(this));
|
|
135
|
-
this.emitter.on(LoaderEvents.QualityLevelSwitching, this._onLoaderQualityLevelSwitching.bind(this));
|
|
136
|
-
this.emitter.on(LoaderEvents.QualityLevelSwitched, this._onLoaderQualityLevelSwitched.bind(this));
|
|
137
|
-
this.emitter.on(LoaderEvents.AudioTracksUpdated, this._onLoaderAudioTracksUpdated.bind(this));
|
|
138
|
-
this.emitter.on(LoaderEvents.AudioTrackSwitching, this._onLoaderAudioTrackSwitching.bind(this));
|
|
139
|
-
this.emitter.on(LoaderEvents.AudioTrackSwitched, this._onLoaderAudioTrackSwitched.bind(this));
|
|
140
40
|
}
|
|
141
41
|
_registerVideoEvents(el) {
|
|
142
42
|
this.elEventsRegistry?.unsubscribeAll();
|
|
143
43
|
this.elEventsRegistry = new DOMEventRegistry(el);
|
|
144
44
|
this.elEventsRegistry.subscribe('play', () => {
|
|
145
|
-
this.
|
|
45
|
+
this._mediaState.updatePaused(el.paused);
|
|
146
46
|
});
|
|
147
47
|
this.elEventsRegistry.subscribe('pause', () => {
|
|
148
|
-
this.
|
|
48
|
+
this._mediaState.updatePaused(el.paused);
|
|
149
49
|
});
|
|
150
50
|
this.elEventsRegistry.subscribe('playing', () => {
|
|
151
|
-
this.
|
|
51
|
+
this._mediaState.updatePaused(el.paused);
|
|
52
|
+
this._mediaState.updateBuffering(false);
|
|
152
53
|
this.emitter.emit(PlayerEvents.Playing);
|
|
153
54
|
});
|
|
154
55
|
this.elEventsRegistry.subscribe('seeking', () => {
|
|
@@ -158,220 +59,46 @@ export class VideoPlayer {
|
|
|
158
59
|
this.emitter.emit(PlayerEvents.Seeked);
|
|
159
60
|
});
|
|
160
61
|
this.elEventsRegistry.subscribe('waiting', () => {
|
|
161
|
-
this.
|
|
62
|
+
this._mediaState.updateBuffering(true);
|
|
162
63
|
});
|
|
64
|
+
// this.elEventsRegistry.subscribe('stalled', () => {
|
|
65
|
+
// this._mediaState.updateBuffering(true);
|
|
66
|
+
// });
|
|
163
67
|
this.elEventsRegistry.subscribe('ended', () => {
|
|
164
|
-
this.
|
|
68
|
+
this._mediaState.updateBuffering(false);
|
|
165
69
|
this.emitter.emit(PlayerEvents.Ended);
|
|
166
70
|
});
|
|
167
71
|
this.elEventsRegistry.subscribe('progress', () => {
|
|
168
|
-
this.
|
|
72
|
+
this._mediaState.updateBufferedFromTimeRanges(el.buffered);
|
|
169
73
|
});
|
|
170
74
|
this.elEventsRegistry.subscribe('canplaythrough', () => {
|
|
171
|
-
this.
|
|
75
|
+
this._mediaState.updateBuffering(false);
|
|
172
76
|
});
|
|
173
77
|
this.elEventsRegistry.subscribe('durationchange', () => {
|
|
174
|
-
|
|
175
|
-
if (!isFinite(newDur) || isNaN(newDur)) {
|
|
176
|
-
newDur = 0;
|
|
177
|
-
}
|
|
178
|
-
if (this._duration !== newDur) {
|
|
179
|
-
this._updateDuration(newDur);
|
|
180
|
-
}
|
|
78
|
+
this._mediaState.updateDuration(el.duration);
|
|
181
79
|
});
|
|
182
80
|
this.elEventsRegistry.subscribe('timeupdate', () => {
|
|
183
|
-
|
|
184
|
-
if (!isFinite(newTime) || isNaN(newTime)) {
|
|
185
|
-
newTime = 0;
|
|
186
|
-
}
|
|
187
|
-
if (this._currentTime !== newTime) {
|
|
188
|
-
this._updateCurrentTime(newTime);
|
|
189
|
-
}
|
|
81
|
+
this._mediaState.updateCurrentTime(el.currentTime);
|
|
190
82
|
// Buffered parts may not be dispatched in on progress event
|
|
191
83
|
// so take care that there is always fresh buffered parts
|
|
192
|
-
this.
|
|
84
|
+
this._mediaState.updateBufferedFromTimeRanges(el.buffered);
|
|
193
85
|
});
|
|
194
86
|
this.elEventsRegistry.subscribe('ratechange', () => {
|
|
195
|
-
|
|
196
|
-
if (this._playbackRate !== newRate) {
|
|
197
|
-
this._updatePlaybackRate(newRate);
|
|
198
|
-
}
|
|
87
|
+
this._mediaState.updatePlaybackRate(el.playbackRate);
|
|
199
88
|
});
|
|
200
89
|
this.elEventsRegistry.subscribe('volumechange', () => {
|
|
201
|
-
|
|
202
|
-
const newMuted = el.muted;
|
|
203
|
-
const isVolChanged = this._volume !== newVol;
|
|
204
|
-
const isMuteChanged = this._muted !== newMuted;
|
|
205
|
-
if (isVolChanged) {
|
|
206
|
-
this._updateVolume(newVol);
|
|
207
|
-
}
|
|
208
|
-
if (isMuteChanged) {
|
|
209
|
-
this._updateMuted(newMuted);
|
|
210
|
-
}
|
|
211
|
-
if (isVolChanged || isMuteChanged) {
|
|
212
|
-
this.emitter.emit(PlayerEvents.VolumeStateChange, newVol, newMuted);
|
|
213
|
-
}
|
|
90
|
+
this._mediaState.updateVolume(el.volume, el.muted);
|
|
214
91
|
});
|
|
215
92
|
// this.elEventsRegistry.subscribe('emptied', () => {
|
|
216
93
|
// this._resetState();
|
|
217
94
|
// });
|
|
218
95
|
this.elEventsRegistry.subscribe('error', (ev) => {
|
|
219
|
-
this.emitter.emit(PlayerEvents.Error, ev.error ?? '
|
|
96
|
+
this.emitter.emit(PlayerEvents.Error, ev.error ?? new Error('Unknown playback error'));
|
|
220
97
|
});
|
|
221
98
|
}
|
|
222
99
|
_unregisterVideoElementEvents() {
|
|
223
100
|
this.elEventsRegistry?.unsubscribeAll();
|
|
224
101
|
}
|
|
225
|
-
_onBufferingStarted() {
|
|
226
|
-
if (!this._isBuffering) {
|
|
227
|
-
this._isBuffering = true;
|
|
228
|
-
this._calcIsLoadingState();
|
|
229
|
-
this.emitter.emit(PlayerEvents.BufferingStarted);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
_onBufferingEnded() {
|
|
233
|
-
if (this._isBuffering) {
|
|
234
|
-
this._isBuffering = false;
|
|
235
|
-
if (this._loadingState === VideoLoadingState.LoadingData) {
|
|
236
|
-
this._loadingState = VideoLoadingState.LoadingDone;
|
|
237
|
-
this.emitter.emit(PlayerEvents.LoadingEnded);
|
|
238
|
-
}
|
|
239
|
-
this._calcIsLoadingState();
|
|
240
|
-
this.emitter.emit(PlayerEvents.BufferingEnded);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
_calcIsLoadingState() {
|
|
244
|
-
const isFinishedVideoLoading = this._loadingState === VideoLoadingState.LoadingDone ||
|
|
245
|
-
this._loadingState === VideoLoadingState.LoadingFailed;
|
|
246
|
-
this._isLoading = !isFinishedVideoLoading || this._isBuffering;
|
|
247
|
-
this._isLoadingStore.set(this._isLoading);
|
|
248
|
-
}
|
|
249
|
-
_onProgress(el) {
|
|
250
|
-
const newBuf = el.buffered;
|
|
251
|
-
const parts = [];
|
|
252
|
-
if (newBuf.length !== this._buffered.length) {
|
|
253
|
-
for (let i = 0; i < newBuf.length; i++) {
|
|
254
|
-
parts.push({ start: newBuf.start(i), end: newBuf.end(i) });
|
|
255
|
-
}
|
|
256
|
-
this._updateBufferedParts(parts);
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
let isChanged = false;
|
|
260
|
-
for (let i = 0; i < newBuf.length; i++) {
|
|
261
|
-
const start = newBuf.start(i);
|
|
262
|
-
const end = newBuf.end(i);
|
|
263
|
-
isChanged = start !== this._buffered[i].start || end !== this._buffered[i].end;
|
|
264
|
-
parts.push({ start, end });
|
|
265
|
-
}
|
|
266
|
-
if (!isChanged) {
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
this._updateBufferedParts(parts);
|
|
270
|
-
}
|
|
271
|
-
_resetState(newLoadingState) {
|
|
272
|
-
this._updateAudioTracks([]);
|
|
273
|
-
this._updateQualityLevels([]);
|
|
274
|
-
this._updateDuration(0);
|
|
275
|
-
this._updateCurrentTime(0);
|
|
276
|
-
this._updateBufferedParts([]);
|
|
277
|
-
this._currentQualityLevel = null;
|
|
278
|
-
this._currentQualityLevelStore.set(null);
|
|
279
|
-
this._currentAudioTrack = null;
|
|
280
|
-
this._currentAudioTrackStore.set(null);
|
|
281
|
-
if (newLoadingState !== undefined) {
|
|
282
|
-
this._loadingState = newLoadingState;
|
|
283
|
-
}
|
|
284
|
-
else if (this._loadingState !== VideoLoadingState.LoadingDone &&
|
|
285
|
-
this._loadingState !== VideoLoadingState.LoadingFailed) {
|
|
286
|
-
this._loadingState = VideoLoadingState.LoadingDone;
|
|
287
|
-
}
|
|
288
|
-
this._onBufferingEnded();
|
|
289
|
-
this._calcIsLoadingState();
|
|
290
|
-
}
|
|
291
|
-
_refreshState() {
|
|
292
|
-
const el = this.el;
|
|
293
|
-
let currTime = el.currentTime;
|
|
294
|
-
if (isNaN(currTime) || !isFinite(currTime)) {
|
|
295
|
-
currTime = 0;
|
|
296
|
-
}
|
|
297
|
-
let duration = el.duration;
|
|
298
|
-
if (isNaN(duration) || !isFinite(duration)) {
|
|
299
|
-
duration = 0;
|
|
300
|
-
}
|
|
301
|
-
if (el.paused !== this._paused) {
|
|
302
|
-
this._updatePaused(el.paused);
|
|
303
|
-
}
|
|
304
|
-
if (el.muted !== this._muted) {
|
|
305
|
-
this._updateMuted(el.muted);
|
|
306
|
-
}
|
|
307
|
-
if (el.volume !== this._volume) {
|
|
308
|
-
this._updateVolume(el.volume);
|
|
309
|
-
}
|
|
310
|
-
if (currTime !== this._currentTime) {
|
|
311
|
-
this._updateCurrentTime(currTime);
|
|
312
|
-
}
|
|
313
|
-
if (duration !== this._duration) {
|
|
314
|
-
this._updateDuration(duration);
|
|
315
|
-
}
|
|
316
|
-
if (el.playbackRate !== this._playbackRate) {
|
|
317
|
-
this._updatePlaybackRate(el.playbackRate);
|
|
318
|
-
}
|
|
319
|
-
this._onProgress(el);
|
|
320
|
-
}
|
|
321
|
-
_onLoaderQualityLevelsUpdated(newLevels) {
|
|
322
|
-
// console.log('Quality levels updated', newLevels);
|
|
323
|
-
this._updateQualityLevels(newLevels);
|
|
324
|
-
}
|
|
325
|
-
_onLoaderQualityLevelSwitching(newLevelId, isAutoLevel) {
|
|
326
|
-
const newLevel = this._qualityLevels.find((lvl) => lvl.id === newLevelId);
|
|
327
|
-
if (!newLevel) {
|
|
328
|
-
console.error(`Quality level switch to unknown level`, {
|
|
329
|
-
newLevelId,
|
|
330
|
-
levels: this._qualityLevels
|
|
331
|
-
});
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
this._isAutoQuality = isAutoLevel;
|
|
335
|
-
this.emitter.emit(PlayerEvents.QualityLevelSwitching, newLevel, isAutoLevel);
|
|
336
|
-
}
|
|
337
|
-
_onLoaderQualityLevelSwitched(newLevelId, isAutoLevel) {
|
|
338
|
-
const newLevel = this._qualityLevels.find((lvl) => lvl.id === newLevelId);
|
|
339
|
-
if (!newLevel) {
|
|
340
|
-
console.error(`Quality level switch to unknown level`, {
|
|
341
|
-
newLevelId,
|
|
342
|
-
levels: this._qualityLevels
|
|
343
|
-
});
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
this._updateQualityLevel(newLevel, isAutoLevel);
|
|
347
|
-
}
|
|
348
|
-
_onLoaderAudioTracksUpdated(newTracks) {
|
|
349
|
-
// console.log('Audio tracks updated', newTracks);
|
|
350
|
-
this._updateAudioTracks(newTracks);
|
|
351
|
-
}
|
|
352
|
-
_onLoaderAudioTrackSwitching(newTrackId) {
|
|
353
|
-
const newTrack = this._audioTracks.find((lvl) => lvl.id === newTrackId);
|
|
354
|
-
if (!newTrack) {
|
|
355
|
-
console.error(`Audio track switch to unknown track`, {
|
|
356
|
-
newTrackId,
|
|
357
|
-
tracks: this._audioTracks
|
|
358
|
-
});
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
this.emitter.emit(PlayerEvents.AudioTrackSwitching, newTrack);
|
|
362
|
-
}
|
|
363
|
-
_onLoaderAudioTrackSwitched(newTrackId) {
|
|
364
|
-
const newTrack = this._audioTracks.find((lvl) => lvl.id === newTrackId);
|
|
365
|
-
if (!newTrack) {
|
|
366
|
-
console.error(`Audio track switch to unknown track`, {
|
|
367
|
-
newTrackId,
|
|
368
|
-
tracks: this._audioTracks
|
|
369
|
-
});
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
this._updateCurrentAudioTrack(newTrack);
|
|
373
|
-
this.emitter.emit(PlayerEvents.AudioTrackSwitching, newTrack);
|
|
374
|
-
}
|
|
375
102
|
_onFullScreenChange = () => {
|
|
376
103
|
const newFullScreen = screenfull.isFullscreen;
|
|
377
104
|
if (newFullScreen !== this._isFullScreen) {
|
|
@@ -380,7 +107,7 @@ export class VideoPlayer {
|
|
|
380
107
|
};
|
|
381
108
|
_updateIsFullScreen(isFullScreen) {
|
|
382
109
|
this._isFullScreen = isFullScreen;
|
|
383
|
-
this._isFullScreenStore.set(isFullScreen);
|
|
110
|
+
// this._isFullScreenStore.set(isFullScreen);
|
|
384
111
|
if (isFullScreen) {
|
|
385
112
|
this.emitter.emit(PlayerEvents.FullScreenEnter);
|
|
386
113
|
}
|
|
@@ -389,68 +116,6 @@ export class VideoPlayer {
|
|
|
389
116
|
}
|
|
390
117
|
this.emitter.emit(PlayerEvents.FullScreenToggle, isFullScreen);
|
|
391
118
|
}
|
|
392
|
-
_updateBufferedParts(buffered) {
|
|
393
|
-
this._buffered = buffered;
|
|
394
|
-
this._bufferedStore.set(buffered);
|
|
395
|
-
this.emitter.emit(PlayerEvents.PlaybackBufferingProgress, buffered);
|
|
396
|
-
}
|
|
397
|
-
_updateDuration(duration) {
|
|
398
|
-
this._duration = duration;
|
|
399
|
-
this._durationStore.set(duration);
|
|
400
|
-
this.emitter.emit(PlayerEvents.PlaybackDurationChange, duration);
|
|
401
|
-
}
|
|
402
|
-
_updateCurrentTime(currentTime) {
|
|
403
|
-
this._currentTime = currentTime;
|
|
404
|
-
this._currentTimeStore.set(currentTime);
|
|
405
|
-
this.emitter.emit(PlayerEvents.PlaybackTimeUpdate, currentTime);
|
|
406
|
-
}
|
|
407
|
-
_updatePlaybackRate(rate) {
|
|
408
|
-
this._playbackRate = rate;
|
|
409
|
-
this._playbackRateStore.set(rate);
|
|
410
|
-
this.emitter.emit(PlayerEvents.PlaybackRateChange, rate);
|
|
411
|
-
}
|
|
412
|
-
_updateVolume(volume) {
|
|
413
|
-
this._volume = volume;
|
|
414
|
-
this._volumeStore.set(volume);
|
|
415
|
-
this.emitter.emit(PlayerEvents.VolumeChange, volume);
|
|
416
|
-
}
|
|
417
|
-
_updateMuted(muted) {
|
|
418
|
-
this._muted = muted;
|
|
419
|
-
this._mutedStore.set(muted);
|
|
420
|
-
this.emitter.emit(PlayerEvents.MuteChange, muted);
|
|
421
|
-
}
|
|
422
|
-
_updatePaused(paused) {
|
|
423
|
-
this._paused = paused;
|
|
424
|
-
this._pausedStore.set(paused);
|
|
425
|
-
if (!paused) {
|
|
426
|
-
this.emitter.emit(PlayerEvents.Play);
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
this.emitter.emit(PlayerEvents.Pause);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
_updateQualityLevels(levels) {
|
|
433
|
-
this._qualityLevels = levels;
|
|
434
|
-
this._qualityLevelsStore.set(levels);
|
|
435
|
-
this.emitter.emit(PlayerEvents.QualityLevelsUpdated, levels);
|
|
436
|
-
}
|
|
437
|
-
_updateQualityLevel(level, isAutoQuality) {
|
|
438
|
-
this._currentQualityLevel = level;
|
|
439
|
-
this._currentQualityLevelStore.set(level);
|
|
440
|
-
this._isAutoQuality = isAutoQuality;
|
|
441
|
-
this._isAutoQualityStore.set(isAutoQuality);
|
|
442
|
-
this.emitter.emit(PlayerEvents.QualityLevelSwitched, level, isAutoQuality);
|
|
443
|
-
}
|
|
444
|
-
_updateAudioTracks(audioTracks) {
|
|
445
|
-
this._audioTracks = audioTracks;
|
|
446
|
-
this._audioTracksStore.set(audioTracks);
|
|
447
|
-
this.emitter.emit(PlayerEvents.AudioTracksUpdated, audioTracks);
|
|
448
|
-
}
|
|
449
|
-
_updateCurrentAudioTrack(audioTrack) {
|
|
450
|
-
this._currentAudioTrack = audioTrack;
|
|
451
|
-
this._currentAudioTrackStore.set(audioTrack);
|
|
452
|
-
this.emitter.emit(PlayerEvents.AudioTrackSwitched, audioTrack);
|
|
453
|
-
}
|
|
454
119
|
attachEl(el) {
|
|
455
120
|
if (this._el === el) {
|
|
456
121
|
return;
|
|
@@ -459,15 +124,15 @@ export class VideoPlayer {
|
|
|
459
124
|
this.detachEl();
|
|
460
125
|
}
|
|
461
126
|
this._el = el;
|
|
462
|
-
this.
|
|
127
|
+
this._mediaState.syncFromEl(el);
|
|
463
128
|
this._registerVideoEvents(el);
|
|
464
129
|
// Setup HLS.js loader
|
|
465
|
-
if (
|
|
466
|
-
this.
|
|
130
|
+
if (IS_HLS_JS_SUPPORTED) {
|
|
131
|
+
this._loadingMgr.setHlsLoader(new HLSLoader(el, this._cfg.hlsConfig ?? {
|
|
467
132
|
progressive: true
|
|
468
|
-
});
|
|
133
|
+
}));
|
|
469
134
|
}
|
|
470
|
-
this.
|
|
135
|
+
this._loadingMgr.setNativeLoader(new NativeLoader(this._el));
|
|
471
136
|
this.emitter.emit(PlayerEvents.MediaElementAttached, el);
|
|
472
137
|
}
|
|
473
138
|
attachContainerEl(el) {
|
|
@@ -487,6 +152,7 @@ export class VideoPlayer {
|
|
|
487
152
|
this._unregisterVideoElementEvents();
|
|
488
153
|
const el = this._el;
|
|
489
154
|
this._el = undefined;
|
|
155
|
+
this._loadingMgr.destroy();
|
|
490
156
|
this.emitter.emit(PlayerEvents.MediaElementDetached, el);
|
|
491
157
|
}
|
|
492
158
|
detachContainerEl() {
|
|
@@ -498,133 +164,27 @@ export class VideoPlayer {
|
|
|
498
164
|
this.emitter.emit(PlayerEvents.ContainerElementDetached, el);
|
|
499
165
|
}
|
|
500
166
|
destroy() {
|
|
167
|
+
if (this._mediaStateSvelteStore) {
|
|
168
|
+
this._mediaStateSvelteStore.destroy();
|
|
169
|
+
}
|
|
501
170
|
this.detachEl();
|
|
502
171
|
this.detachContainerEl();
|
|
503
|
-
|
|
504
|
-
this.emitter.off(LoaderEvents.QualityLevelSwitching, this._onLoaderQualityLevelSwitching.bind(this));
|
|
505
|
-
this.emitter.off(LoaderEvents.QualityLevelSwitched, this._onLoaderQualityLevelSwitched.bind(this));
|
|
506
|
-
this.emitter.off(LoaderEvents.AudioTracksUpdated, this._onLoaderAudioTracksUpdated.bind(this));
|
|
507
|
-
this.emitter.off(LoaderEvents.AudioTrackSwitching, this._onLoaderAudioTrackSwitching.bind(this));
|
|
508
|
-
this.emitter.off(LoaderEvents.AudioTrackSwitched, this._onLoaderAudioTrackSwitched.bind(this));
|
|
509
|
-
if (this.currentLoader) {
|
|
510
|
-
this.currentLoader.stop();
|
|
511
|
-
this.currentLoader = null;
|
|
512
|
-
this.hlsLoader = null;
|
|
513
|
-
}
|
|
514
|
-
if (VideoPlayer._isFullScreenAllowed) {
|
|
172
|
+
if (IS_FULLSCREEN_ALLOWED) {
|
|
515
173
|
screenfull.off('change', this._onFullScreenChange.bind(this));
|
|
516
174
|
}
|
|
517
175
|
}
|
|
518
176
|
stop() {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
this.loadAbortController.abort('Player stop called');
|
|
522
|
-
this.loadAbortController = null;
|
|
523
|
-
}
|
|
524
|
-
if (!this.el.paused) {
|
|
525
|
-
this.el.pause();
|
|
526
|
-
this._paused = true;
|
|
527
|
-
this._pausedStore.set(true);
|
|
528
|
-
}
|
|
529
|
-
try {
|
|
530
|
-
this.currentLoader.stop();
|
|
531
|
-
}
|
|
532
|
-
catch (e) {
|
|
533
|
-
// Ignore any loader stopping error
|
|
534
|
-
console.log('loader error during stop', e);
|
|
535
|
-
}
|
|
536
|
-
this._resetState();
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
_getLoaderByType(loaderType) {
|
|
540
|
-
let loader = null;
|
|
541
|
-
switch (loaderType) {
|
|
542
|
-
case Loader.Native:
|
|
543
|
-
loader = this.nativeLoader;
|
|
544
|
-
break;
|
|
545
|
-
case Loader.HLS:
|
|
546
|
-
loader = this.hlsLoader ?? this.nativeLoader;
|
|
547
|
-
break;
|
|
548
|
-
case Loader.DASH:
|
|
549
|
-
loader = this.nativeLoader;
|
|
550
|
-
break;
|
|
551
|
-
default:
|
|
552
|
-
throw Error('Unknown loader selected');
|
|
553
|
-
}
|
|
554
|
-
if (!loader) {
|
|
555
|
-
throw Error('No suitable loader found');
|
|
556
|
-
}
|
|
557
|
-
return loader;
|
|
558
|
-
}
|
|
559
|
-
_getLoaderFromUrl(url) {
|
|
560
|
-
let loader = null;
|
|
561
|
-
const urlParsed = new URL(url);
|
|
562
|
-
const path = urlParsed.pathname;
|
|
563
|
-
if (path.endsWith('.m3u8')) {
|
|
564
|
-
// HLS
|
|
565
|
-
loader = this.hlsLoader ?? this.nativeLoader;
|
|
566
|
-
}
|
|
567
|
-
else if (path.endsWith('.mpd')) {
|
|
568
|
-
// DASH
|
|
569
|
-
loader = this.nativeLoader;
|
|
570
|
-
}
|
|
571
|
-
else {
|
|
572
|
-
// For everything else native loader should be used
|
|
573
|
-
loader = this.nativeLoader;
|
|
574
|
-
}
|
|
575
|
-
if (!loader) {
|
|
576
|
-
throw Error('No suitable loader found');
|
|
577
|
-
}
|
|
578
|
-
return loader;
|
|
177
|
+
this._loadingMgr.stop();
|
|
178
|
+
this._mediaState.resetForLoadingStart();
|
|
579
179
|
}
|
|
580
180
|
async load(params) {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
}
|
|
584
|
-
let neededLoader = null;
|
|
585
|
-
if (params.loader !== undefined) {
|
|
586
|
-
neededLoader = this._getLoaderByType(params.loader);
|
|
587
|
-
}
|
|
588
|
-
// Unsubscribe from video events before loading
|
|
181
|
+
const el = this.el;
|
|
182
|
+
this.emitter.emit(PlayerEvents.BeforeLoading, params);
|
|
589
183
|
this._unregisterVideoElementEvents();
|
|
590
|
-
|
|
591
|
-
this.
|
|
592
|
-
this.
|
|
593
|
-
this.
|
|
594
|
-
this._calcIsLoadingState();
|
|
595
|
-
this.emitter.emit(PlayerEvents.LoadingStarted, params);
|
|
596
|
-
try {
|
|
597
|
-
const loadUrl = await getLoadUrl(params.url, this.loadAbortController.signal);
|
|
598
|
-
// Detect needed loader based on load url
|
|
599
|
-
if (neededLoader === null) {
|
|
600
|
-
neededLoader = this._getLoaderFromUrl(loadUrl);
|
|
601
|
-
}
|
|
602
|
-
if (this.currentLoader && this.currentLoader !== neededLoader) {
|
|
603
|
-
this.currentLoader.stop();
|
|
604
|
-
this.currentLoader = neededLoader;
|
|
605
|
-
}
|
|
606
|
-
// Subscribe to video events before loader load call, because it will produce HTML events
|
|
607
|
-
this._registerVideoEvents(this.el);
|
|
608
|
-
await neededLoader.load({
|
|
609
|
-
abortSignal: abortController.signal,
|
|
610
|
-
url: loadUrl,
|
|
611
|
-
startLevel: params.startLevel,
|
|
612
|
-
startPosition: params.startPosition,
|
|
613
|
-
audioTrack: params.audioTrack
|
|
614
|
-
});
|
|
615
|
-
}
|
|
616
|
-
catch (e) {
|
|
617
|
-
this.loadAbortController = null;
|
|
618
|
-
this._loadingState = VideoLoadingState.LoadingFailed;
|
|
619
|
-
this._calcIsLoadingState();
|
|
620
|
-
this.emitter.emit(PlayerEvents.LoadingMetadataFailed, e);
|
|
621
|
-
throw e;
|
|
622
|
-
}
|
|
623
|
-
this.loadAbortController = null;
|
|
624
|
-
this._loadingState = VideoLoadingState.LoadingData;
|
|
625
|
-
this._onBufferingStarted();
|
|
626
|
-
this._calcIsLoadingState();
|
|
627
|
-
this.emitter.emit(PlayerEvents.LoadingMetadataEnded);
|
|
184
|
+
this._mediaState.resetForLoadingStart();
|
|
185
|
+
await this._loadingMgr.load(params);
|
|
186
|
+
this._registerVideoEvents(el);
|
|
187
|
+
this._mediaState.syncFromEl(el);
|
|
628
188
|
if (params.playAfterLoad) {
|
|
629
189
|
await this.play();
|
|
630
190
|
}
|
|
@@ -658,18 +218,18 @@ export class VideoPlayer {
|
|
|
658
218
|
if (pos < 0) {
|
|
659
219
|
pos = 0;
|
|
660
220
|
}
|
|
661
|
-
else if (pos > this.
|
|
662
|
-
pos = this.
|
|
221
|
+
else if (pos > this._mediaState.duration) {
|
|
222
|
+
pos = this._mediaState.duration;
|
|
663
223
|
}
|
|
664
|
-
this.
|
|
224
|
+
this._mediaState.updateCurrentTime(pos);
|
|
665
225
|
this._el.currentTime = pos;
|
|
666
226
|
}
|
|
667
227
|
seekForward(step) {
|
|
668
|
-
const newCurrentTime = this.
|
|
228
|
+
const newCurrentTime = this._mediaState.currentTime + step;
|
|
669
229
|
this.seekTo(newCurrentTime);
|
|
670
230
|
}
|
|
671
231
|
seekBackward(step) {
|
|
672
|
-
const newCurrentTime = this.
|
|
232
|
+
const newCurrentTime = this._mediaState.currentTime - step;
|
|
673
233
|
this.seekTo(newCurrentTime);
|
|
674
234
|
}
|
|
675
235
|
setVolume(vol) {
|
|
@@ -687,6 +247,20 @@ export class VideoPlayer {
|
|
|
687
247
|
}
|
|
688
248
|
this._el.muted = muted;
|
|
689
249
|
}
|
|
250
|
+
// setVolumeGain(gain: number) {
|
|
251
|
+
// if (!this._el) {
|
|
252
|
+
// throw Error('Player is not attached to media element');
|
|
253
|
+
// }
|
|
254
|
+
//
|
|
255
|
+
// if (!this._audioGain) {
|
|
256
|
+
// if (!IS_AUDIO_GAIN_SUPPORTED) {
|
|
257
|
+
// console.error('Audio gain is not supported by the browser');
|
|
258
|
+
// return;
|
|
259
|
+
// }
|
|
260
|
+
//
|
|
261
|
+
// this._audioGain = createGainNode();
|
|
262
|
+
// }
|
|
263
|
+
// }
|
|
690
264
|
setPlaybackRate(rate) {
|
|
691
265
|
if (!this._el) {
|
|
692
266
|
throw Error('Player is not attached to media element');
|
|
@@ -699,9 +273,6 @@ export class VideoPlayer {
|
|
|
699
273
|
}
|
|
700
274
|
this._el.muted = !this._el.muted;
|
|
701
275
|
}
|
|
702
|
-
static isFullScreenAllowed() {
|
|
703
|
-
return VideoPlayer._isFullScreenAllowed;
|
|
704
|
-
}
|
|
705
276
|
async toggleFullScreen() {
|
|
706
277
|
// On iOS only native full screen supported
|
|
707
278
|
if (IS_IOS && !IS_IPAD_NEW) {
|
|
@@ -719,30 +290,33 @@ export class VideoPlayer {
|
|
|
719
290
|
return await screenfull.toggle(this._el);
|
|
720
291
|
}
|
|
721
292
|
setQualityLevel(id, graceful) {
|
|
722
|
-
const found = this.
|
|
293
|
+
const found = this._mediaState.findQualityLevelById(id);
|
|
723
294
|
if (!found) {
|
|
724
295
|
throw Error(`Quality level not found: ${id}`);
|
|
725
296
|
}
|
|
726
|
-
|
|
297
|
+
const loader = this._loadingMgr.getCurrentLoader();
|
|
298
|
+
if (!loader) {
|
|
727
299
|
throw Error('Loader is not set');
|
|
728
300
|
}
|
|
729
|
-
|
|
301
|
+
loader.switchQualityLevel(id, graceful);
|
|
730
302
|
}
|
|
731
303
|
setAutoQualityLevel(graceful) {
|
|
732
|
-
|
|
304
|
+
const loader = this._loadingMgr.getCurrentLoader();
|
|
305
|
+
if (!loader) {
|
|
733
306
|
throw Error('Loader is not set');
|
|
734
307
|
}
|
|
735
|
-
|
|
308
|
+
loader.switchQualityLevel(loader.getAutoQualityLevelId(), graceful);
|
|
736
309
|
}
|
|
737
310
|
setAudioTrack(trackId, graceful) {
|
|
738
|
-
const found = this.
|
|
311
|
+
const found = this._mediaState.findAudioTrackById(trackId);
|
|
739
312
|
if (!found) {
|
|
740
313
|
throw Error(`Audio track not found: ${trackId}`);
|
|
741
314
|
}
|
|
742
|
-
|
|
315
|
+
const loader = this._loadingMgr.getCurrentLoader();
|
|
316
|
+
if (!loader) {
|
|
743
317
|
throw Error('Loader is not set');
|
|
744
318
|
}
|
|
745
|
-
|
|
319
|
+
loader.switchAudioTrack(trackId, graceful);
|
|
746
320
|
}
|
|
747
321
|
subscribe(ev, cb) {
|
|
748
322
|
this.emitter.on(ev, cb);
|
|
@@ -765,98 +339,22 @@ export class VideoPlayer {
|
|
|
765
339
|
}
|
|
766
340
|
return this._containerEl;
|
|
767
341
|
}
|
|
768
|
-
get loader() {
|
|
769
|
-
return this.currentLoader;
|
|
770
|
-
}
|
|
771
342
|
get isFullScreen() {
|
|
772
343
|
return this._isFullScreen;
|
|
773
344
|
}
|
|
774
|
-
get
|
|
775
|
-
return this.
|
|
776
|
-
}
|
|
777
|
-
get isBuffering() {
|
|
778
|
-
return this._isBuffering;
|
|
345
|
+
get loader() {
|
|
346
|
+
return this._loadingMgr.getCurrentLoader();
|
|
779
347
|
}
|
|
780
|
-
// isLoading indicates is there any buffering process or metadata loading
|
|
781
348
|
get isLoading() {
|
|
782
|
-
return this.
|
|
783
|
-
}
|
|
784
|
-
get qualityLevels() {
|
|
785
|
-
return this._qualityLevels;
|
|
786
|
-
}
|
|
787
|
-
get isAutoQuality() {
|
|
788
|
-
return this._isAutoQuality;
|
|
789
|
-
}
|
|
790
|
-
get qualityLevel() {
|
|
791
|
-
return this._currentQualityLevel;
|
|
792
|
-
}
|
|
793
|
-
get audioTracks() {
|
|
794
|
-
return this._audioTracks;
|
|
795
|
-
}
|
|
796
|
-
get audioTrack() {
|
|
797
|
-
return this._currentAudioTrack;
|
|
798
|
-
}
|
|
799
|
-
get duration() {
|
|
800
|
-
return this._duration;
|
|
801
|
-
}
|
|
802
|
-
get paused() {
|
|
803
|
-
return this._paused;
|
|
804
|
-
}
|
|
805
|
-
get currentTime() {
|
|
806
|
-
return this._currentTime;
|
|
807
|
-
}
|
|
808
|
-
get buffered() {
|
|
809
|
-
return this._buffered;
|
|
810
|
-
}
|
|
811
|
-
get playbackRate() {
|
|
812
|
-
return this._playbackRate;
|
|
813
|
-
}
|
|
814
|
-
get volume() {
|
|
815
|
-
return this._volume;
|
|
349
|
+
return this._loadingMgr.getLoadingState() === VideoLoadingState.Loading;
|
|
816
350
|
}
|
|
817
|
-
get
|
|
818
|
-
return this.
|
|
819
|
-
}
|
|
820
|
-
get pausedStore() {
|
|
821
|
-
return readonly(this._pausedStore);
|
|
822
|
-
}
|
|
823
|
-
get isFullScreenStore() {
|
|
824
|
-
return readonly(this._isFullScreenStore);
|
|
825
|
-
}
|
|
826
|
-
get isLoadingStore() {
|
|
827
|
-
return readonly(this._isLoadingStore);
|
|
828
|
-
}
|
|
829
|
-
get qualityLevelsStore() {
|
|
830
|
-
return readonly(this._qualityLevelsStore);
|
|
831
|
-
}
|
|
832
|
-
get isAutoQualityStore() {
|
|
833
|
-
return readonly(this._isAutoQualityStore);
|
|
834
|
-
}
|
|
835
|
-
get qualityLevelStore() {
|
|
836
|
-
return readonly(this._currentQualityLevelStore);
|
|
837
|
-
}
|
|
838
|
-
get audioTracksStore() {
|
|
839
|
-
return readonly(this._audioTracksStore);
|
|
840
|
-
}
|
|
841
|
-
get audioTrackStore() {
|
|
842
|
-
return readonly(this._currentAudioTrackStore);
|
|
843
|
-
}
|
|
844
|
-
get durationStore() {
|
|
845
|
-
return readonly(this._durationStore);
|
|
846
|
-
}
|
|
847
|
-
get currentTimeStore() {
|
|
848
|
-
return readonly(this._currentTimeStore);
|
|
849
|
-
}
|
|
850
|
-
get bufferedStore() {
|
|
851
|
-
return readonly(this._bufferedStore);
|
|
852
|
-
}
|
|
853
|
-
get playbackRateStore() {
|
|
854
|
-
return readonly(this._playbackRateStore);
|
|
351
|
+
get loadingState() {
|
|
352
|
+
return this._loadingMgr.getLoadingState();
|
|
855
353
|
}
|
|
856
|
-
get
|
|
857
|
-
return
|
|
354
|
+
get mediaState() {
|
|
355
|
+
return (this._mediaStateProxy ??= new VideoPlayerMediaStateProxy(this._mediaState));
|
|
858
356
|
}
|
|
859
|
-
get
|
|
860
|
-
return
|
|
357
|
+
get mediaStateSvelteStore() {
|
|
358
|
+
return (this._mediaStateSvelteStore ??= new VideoPlayerMediaStateSvelteStore(this));
|
|
861
359
|
}
|
|
862
360
|
}
|