@gcorevideo/player 2.28.27 → 2.28.28

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.
@@ -1,5 +1,5 @@
1
1
  import { Playback } from '@clappr/core';
2
- import DASHJS, { type BitrateInfo as DashBitrateInfo, IManifestInfo } from 'dashjs';
2
+ import { IManifestInfo, MediaPlayerClass, Representation } from 'dashjs';
3
3
  import { QualityLevel, TimePosition, TimeValue } from '../../playback.types.js';
4
4
  import { BasePlayback } from '../BasePlayback.js';
5
5
  import { AudioTrack } from '@clappr/core/types/base/playback/playback.js';
@@ -10,8 +10,8 @@ type LocalTimeCorrelation = {
10
10
  remote: number;
11
11
  };
12
12
  export default class DashPlayback extends BasePlayback {
13
- _levels: QualityLevel[] | null;
14
- _currentLevel: number | null;
13
+ _levels: QualityLevel[];
14
+ _currentLevel: number;
15
15
  _durationExcludesAfterLiveSyncPoint: boolean;
16
16
  _isReadyState: boolean;
17
17
  _playableRegionDuration: number;
@@ -19,7 +19,7 @@ export default class DashPlayback extends BasePlayback {
19
19
  _playbackType: PlaybackType;
20
20
  _playlistType: PlaylistType | null;
21
21
  _programDateTime: TimeValue;
22
- _dash: DASHJS.MediaPlayerClass | null;
22
+ _dash: MediaPlayerClass | null;
23
23
  _extrapolatedWindowDuration: number;
24
24
  _lastDuration: TimeValue | null;
25
25
  _lastTimeUpdate: TimePosition;
@@ -66,7 +66,7 @@ export default class DashPlayback extends BasePlayback {
66
66
  private destroyInstance;
67
67
  destroy(): void;
68
68
  _updatePlaybackType(): void;
69
- _fillLevels(levels: DashBitrateInfo[]): void;
69
+ _fillLevels(levels: Representation[]): void;
70
70
  private onLevelSwitch;
71
71
  private onLevelSwitchEnd;
72
72
  getPlaybackType(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"DashPlayback.d.ts","sourceRoot":"","sources":["../../../src/playback/dash-playback/DashPlayback.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DashPlayback.d.ts","sourceRoot":"","sources":["../../../src/playback/dash-playback/DashPlayback.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  import { Events, Log, Playback, PlayerError, Utils, $ } from '@clappr/core';
6
6
  import { trace } from '@gcorevideo/utils';
7
7
  import assert from 'assert';
8
- import DASHJS from 'dashjs';
8
+ import { MediaPlayer, } from 'dashjs';
9
9
  import { PlaybackErrorCode, } from '../../playback.types.js';
10
10
  import { isDashSource } from '../../utils/mediaSources.js';
11
11
  import { BasePlayback } from '../BasePlayback.js';
@@ -14,8 +14,8 @@ const AUTO = -1;
14
14
  const { now } = Utils;
15
15
  const T = 'playback.dash';
16
16
  export default class DashPlayback extends BasePlayback {
17
- _levels = null;
18
- _currentLevel = null;
17
+ _levels = [];
18
+ _currentLevel = AUTO;
19
19
  // true when the actual duration is longer than hlsjs's live sync point
20
20
  // when this is false playableRegionDuration will be the actual duration
21
21
  // when this is true playableRegionDuration will exclude the time after the sync point
@@ -53,13 +53,9 @@ export default class DashPlayback extends BasePlayback {
53
53
  return 'dash';
54
54
  }
55
55
  get levels() {
56
- return this._levels || [];
56
+ return this._levels;
57
57
  }
58
58
  get currentLevel() {
59
- if (this._currentLevel === null) {
60
- return AUTO;
61
- }
62
- // 0 is a valid level ID
63
59
  return this._currentLevel;
64
60
  }
65
61
  get isReady() {
@@ -81,7 +77,7 @@ export default class DashPlayback extends BasePlayback {
81
77
  });
82
78
  dash.updateSettings(settings);
83
79
  if (id !== -1) {
84
- this._dash.setQualityFor('video', id);
80
+ this._dash.setRepresentationForTypeByIndex('video', id);
85
81
  }
86
82
  if (this._playbackType === Playback.VOD) {
87
83
  const curr_time = this._dash.time();
@@ -141,7 +137,7 @@ export default class DashPlayback extends BasePlayback {
141
137
  }
142
138
  }
143
139
  _setup() {
144
- const dash = DASHJS.MediaPlayer().create();
140
+ const dash = MediaPlayer().create();
145
141
  this._dash = dash;
146
142
  this._dash.initialize();
147
143
  if (this.options.dash) {
@@ -154,30 +150,31 @@ export default class DashPlayback extends BasePlayback {
154
150
  }, this.options.dash);
155
151
  this._dash.updateSettings(settings);
156
152
  }
153
+ assert.ok(this.el instanceof HTMLMediaElement, 'el must be an HTMLMediaElement');
157
154
  this._dash.attachView(this.el);
158
155
  this._dash.setAutoPlay(false);
159
156
  this._dash.attachSource(this.options.src);
160
- this._dash.on(DASHJS.MediaPlayer.events.ERROR, this._onDASHJSSError);
161
- this._dash.on(DASHJS.MediaPlayer.events.PLAYBACK_ERROR, this._onPlaybackError);
162
- this._dash.on(DASHJS.MediaPlayer.events.STREAM_INITIALIZED, () => {
163
- const bitrates = dash.getBitrateInfoListFor('video');
157
+ this._dash.on(MediaPlayer.events.ERROR, this._onDASHJSSError);
158
+ this._dash.on(MediaPlayer.events.PLAYBACK_ERROR, this._onPlaybackError);
159
+ this._dash.on(MediaPlayer.events.STREAM_INITIALIZED, () => {
160
+ const bitrates = dash.getRepresentationsByType('video');
164
161
  this._updatePlaybackType();
165
162
  this._fillLevels(bitrates);
166
- const currentLevel = dash.getQualityFor('video');
167
- if (currentLevel !== -1) {
168
- this.trigger(Events.PLAYBACK_BITRATE, this.getLevel(currentLevel));
163
+ const currentLevel = dash.getCurrentRepresentationForType('video');
164
+ if (currentLevel) {
165
+ this.trigger(Events.PLAYBACK_BITRATE, this.getLevel(currentLevel.index));
169
166
  }
170
- dash.on(DASHJS.MediaPlayer.events.QUALITY_CHANGE_REQUESTED, (evt) => {
171
- const newLevel = this.getLevel(evt.newQuality);
167
+ dash.on(MediaPlayer.events.QUALITY_CHANGE_REQUESTED, (evt) => {
168
+ const newLevel = this.getLevel(evt.newRepresentation.index);
172
169
  this.onLevelSwitch(newLevel);
173
170
  });
174
171
  this.checkAudioTracks();
175
172
  });
176
- this._dash.on(DASHJS.MediaPlayer.events.QUALITY_CHANGE_RENDERED, (evt) => {
177
- const currentLevel = this.getLevel(evt.newQuality);
173
+ this._dash.on(MediaPlayer.events.QUALITY_CHANGE_RENDERED, (evt) => {
174
+ const currentLevel = this.getLevel(evt.newRepresentation.index);
178
175
  this.onLevelSwitchEnd(currentLevel);
179
176
  });
180
- this._dash.on(DASHJS.MediaPlayer.events.METRIC_ADDED, (e) => {
177
+ this._dash.on(MediaPlayer.events.METRIC_ADDED, (e) => {
181
178
  // Listen for the first manifest request in order to update player UI
182
179
  if (e.metric === 'DVRInfo') {
183
180
  // TODO fix typings
@@ -189,10 +186,10 @@ export default class DashPlayback extends BasePlayback {
189
186
  }
190
187
  }
191
188
  });
192
- this._dash.on(DASHJS.MediaPlayer.events.PLAYBACK_RATE_CHANGED, (e) => {
189
+ this._dash.on(MediaPlayer.events.PLAYBACK_RATE_CHANGED, (e) => {
193
190
  this.trigger(PlaybackEvents.PLAYBACK_RATE_CHANGED, e.playbackRate);
194
191
  });
195
- this._dash.on(DASHJS.MediaPlayer.events.TRACK_CHANGE_RENDERED, (e) => {
192
+ this._dash.on(MediaPlayer.events.TRACK_CHANGE_RENDERED, (e) => {
196
193
  if (e.mediaType === 'audio') {
197
194
  this.trigger(Events.PLAYBACK_AUDIO_CHANGED, toClapprTrack(e.newMediaInfo));
198
195
  }
@@ -294,17 +291,17 @@ export default class DashPlayback extends BasePlayback {
294
291
  const e = event.error;
295
292
  switch (e.code) {
296
293
  // TODO test handling of these errors
297
- case DASHJS.MediaPlayer.errors.MANIFEST_LOADER_PARSING_FAILURE_ERROR_CODE:
298
- case DASHJS.MediaPlayer.errors.MANIFEST_LOADER_LOADING_FAILURE_ERROR_CODE:
299
- case DASHJS.MediaPlayer.errors.DOWNLOAD_ERROR_ID_MANIFEST_CODE:
300
- case DASHJS.MediaPlayer.errors.DOWNLOAD_ERROR_ID_CONTENT_CODE:
301
- case DASHJS.MediaPlayer.errors.DOWNLOAD_ERROR_ID_INITIALIZATION_CODE:
294
+ case MediaPlayer.errors.MANIFEST_LOADER_PARSING_FAILURE_ERROR_CODE:
295
+ case MediaPlayer.errors.MANIFEST_LOADER_LOADING_FAILURE_ERROR_CODE:
296
+ case MediaPlayer.errors.DOWNLOAD_ERROR_ID_MANIFEST_CODE:
297
+ case MediaPlayer.errors.DOWNLOAD_ERROR_ID_CONTENT_CODE:
298
+ case MediaPlayer.errors.DOWNLOAD_ERROR_ID_INITIALIZATION_CODE:
302
299
  // TODO these probably indicate a broken manifest and should be treated by removing the source
303
- case DASHJS.MediaPlayer.errors.MANIFEST_ERROR_ID_NOSTREAMS_CODE:
304
- case DASHJS.MediaPlayer.errors.MANIFEST_ERROR_ID_PARSE_CODE:
305
- case DASHJS.MediaPlayer.errors.MANIFEST_ERROR_ID_MULTIPLEXED_CODE:
306
- case DASHJS.MediaPlayer.errors.MEDIASOURCE_TYPE_UNSUPPORTED_CODE:
307
- case DASHJS.MediaPlayer.errors.SEGMENT_BASE_LOADER_ERROR_CODE:
300
+ case MediaPlayer.errors.MANIFEST_ERROR_ID_NOSTREAMS_CODE:
301
+ case MediaPlayer.errors.MANIFEST_ERROR_ID_PARSE_CODE:
302
+ case MediaPlayer.errors.MANIFEST_ERROR_ID_MULTIPLEXED_CODE:
303
+ case MediaPlayer.errors.MEDIASOURCE_TYPE_UNSUPPORTED_CODE:
304
+ case MediaPlayer.errors.SEGMENT_BASE_LOADER_ERROR_CODE:
308
305
  this.triggerError({
309
306
  code: PlaybackErrorCode.MediaSourceUnavailable,
310
307
  message: e.message,
@@ -363,7 +360,7 @@ export default class DashPlayback extends BasePlayback {
363
360
  if (!this._dash) {
364
361
  return false;
365
362
  }
366
- return (this._dash?.getDVRWindowSize() >= this._minDvrSize &&
363
+ return (this._dash?.getDvrWindow()?.size >= this._minDvrSize &&
367
364
  this.getPlaybackType() === Playback.LIVE);
368
365
  }
369
366
  _onProgress() {
@@ -402,9 +399,9 @@ export default class DashPlayback extends BasePlayback {
402
399
  }
403
400
  destroyInstance() {
404
401
  if (this._dash) {
405
- this._dash.off(DASHJS.MediaPlayer.events.ERROR, this._onDASHJSSError);
406
- this._dash.off(DASHJS.MediaPlayer.events.PLAYBACK_ERROR, this._onPlaybackError);
407
- this._dash.off(DASHJS.MediaPlayer.events.MANIFEST_LOADED, this.getDuration);
402
+ this._dash.off(MediaPlayer.events.ERROR, this._onDASHJSSError);
403
+ this._dash.off(MediaPlayer.events.PLAYBACK_ERROR, this._onPlaybackError);
404
+ this._dash.off(MediaPlayer.events.MANIFEST_LOADED, this.getDuration);
408
405
  this._dash.reset();
409
406
  this._dash = null;
410
407
  }
@@ -423,11 +420,12 @@ export default class DashPlayback extends BasePlayback {
423
420
  }
424
421
  }
425
422
  _fillLevels(levels) {
426
- // TOOD check that levels[i].qualityIndex === i
423
+ // TOOD check that levels[i].index === i
424
+ trace(`${T} _fillLevels`, { levels });
427
425
  this._levels = levels.map((level) => {
428
426
  return {
429
- level: level.qualityIndex,
430
- bitrate: level.bitrate,
427
+ level: level.index,
428
+ bitrate: level.bitrateInKbit * 1000,
431
429
  width: level.width,
432
430
  height: level.height,
433
431
  };
@@ -451,9 +449,9 @@ export default class DashPlayback extends BasePlayback {
451
449
  return this._playbackType === Playback.VOD || this.dvrEnabled;
452
450
  }
453
451
  getLevel(quality) {
454
- const ret = this.levels.find((level) => level.level === quality);
455
- assert.ok(ret, 'Invalid quality level');
456
- return ret;
452
+ const level = this.levels.find((level) => level.level === quality);
453
+ assert.ok(level, 'Invalid quality level');
454
+ return level;
457
455
  }
458
456
  setPlaybackRate(rate) {
459
457
  this._dash?.setPlaybackRate(rate);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gcorevideo/player",
3
- "version": "2.28.27",
3
+ "version": "2.28.28",
4
4
  "description": "Gcore JavaScript video player",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -61,7 +61,7 @@
61
61
  "@clappr/core": "^0.13.0",
62
62
  "@gcorevideo/utils": "^0.7.1",
63
63
  "@sentry/types": "^8.47.0",
64
- "dashjs": "^4.7.4",
64
+ "dashjs": "^5.1.1",
65
65
  "hls.js": "^1.6.15",
66
66
  "human-format": "^1.2.1",
67
67
  "mousetrap": "^1.6.5",
@@ -6,13 +6,20 @@
6
6
  import { Events, Log, Playback, PlayerError, Utils, $ } from '@clappr/core'
7
7
  import { trace } from '@gcorevideo/utils'
8
8
  import assert from 'assert'
9
- import DASHJS, {
9
+ import {
10
10
  ErrorEvent as DashErrorEvent,
11
11
  MediaPlayerErrorEvent,
12
12
  PlaybackErrorEvent as DashPlaybackErrorEvent,
13
13
  type BitrateInfo as DashBitrateInfo,
14
14
  MetricEvent as DashMetricEvent,
15
15
  IManifestInfo,
16
+ MediaPlayerClass,
17
+ MediaPlayer,
18
+ PlaybackRateChangedEvent,
19
+ TrackChangeRenderedEvent,
20
+ MediaInfo,
21
+ Representation,
22
+ QualityChangeRenderedEvent,
16
23
  } from 'dashjs'
17
24
 
18
25
  import {
@@ -47,9 +54,9 @@ type LocalTimeCorrelation = {
47
54
  const T = 'playback.dash'
48
55
 
49
56
  export default class DashPlayback extends BasePlayback {
50
- _levels: QualityLevel[] | null = null
57
+ _levels: QualityLevel[] = []
51
58
 
52
- _currentLevel: number | null = null
59
+ _currentLevel: number = AUTO
53
60
 
54
61
  // true when the actual duration is longer than hlsjs's live sync point
55
62
  // when this is false playableRegionDuration will be the actual duration
@@ -78,7 +85,7 @@ export default class DashPlayback extends BasePlayback {
78
85
 
79
86
  _programDateTime: TimeValue = 0
80
87
 
81
- _dash: DASHJS.MediaPlayerClass | null = null
88
+ _dash: MediaPlayerClass | null = null
82
89
 
83
90
  _extrapolatedWindowDuration: number = 0
84
91
 
@@ -105,14 +112,10 @@ export default class DashPlayback extends BasePlayback {
105
112
  }
106
113
 
107
114
  get levels(): QualityLevel[] {
108
- return this._levels || []
115
+ return this._levels
109
116
  }
110
117
 
111
118
  get currentLevel(): number {
112
- if (this._currentLevel === null) {
113
- return AUTO
114
- }
115
- // 0 is a valid level ID
116
119
  return this._currentLevel
117
120
  }
118
121
 
@@ -143,7 +146,7 @@ export default class DashPlayback extends BasePlayback {
143
146
 
144
147
  dash.updateSettings(settings)
145
148
  if (id !== -1) {
146
- this._dash.setQualityFor('video', id)
149
+ this._dash.setRepresentationForTypeByIndex('video', id)
147
150
  }
148
151
  if (this._playbackType === Playback.VOD) {
149
152
  const curr_time = this._dash.time()
@@ -226,7 +229,7 @@ export default class DashPlayback extends BasePlayback {
226
229
  }
227
230
 
228
231
  _setup() {
229
- const dash = DASHJS.MediaPlayer().create()
232
+ const dash = MediaPlayer().create()
230
233
  this._dash = dash
231
234
  this._dash.initialize()
232
235
 
@@ -245,29 +248,30 @@ export default class DashPlayback extends BasePlayback {
245
248
  this._dash.updateSettings(settings)
246
249
  }
247
250
 
251
+ assert.ok(this.el instanceof HTMLMediaElement, 'el must be an HTMLMediaElement')
248
252
  this._dash.attachView(this.el)
249
253
 
250
254
  this._dash.setAutoPlay(false)
251
255
  this._dash.attachSource(this.options.src)
252
256
 
253
- this._dash.on(DASHJS.MediaPlayer.events.ERROR, this._onDASHJSSError)
257
+ this._dash.on(MediaPlayer.events.ERROR, this._onDASHJSSError)
254
258
  this._dash.on(
255
- DASHJS.MediaPlayer.events.PLAYBACK_ERROR,
259
+ MediaPlayer.events.PLAYBACK_ERROR,
256
260
  this._onPlaybackError,
257
261
  )
258
262
 
259
- this._dash.on(DASHJS.MediaPlayer.events.STREAM_INITIALIZED, () => {
260
- const bitrates = dash.getBitrateInfoListFor('video')
263
+ this._dash.on(MediaPlayer.events.STREAM_INITIALIZED, () => {
264
+ const bitrates = dash.getRepresentationsByType('video')
261
265
 
262
266
  this._updatePlaybackType()
263
267
  this._fillLevels(bitrates)
264
- const currentLevel = dash.getQualityFor('video')
265
- if (currentLevel !== -1) {
266
- this.trigger(Events.PLAYBACK_BITRATE, this.getLevel(currentLevel))
268
+ const currentLevel = dash.getCurrentRepresentationForType('video')
269
+ if (currentLevel) {
270
+ this.trigger(Events.PLAYBACK_BITRATE, this.getLevel(currentLevel.index))
267
271
  }
268
272
 
269
- dash.on(DASHJS.MediaPlayer.events.QUALITY_CHANGE_REQUESTED, (evt) => {
270
- const newLevel = this.getLevel(evt.newQuality)
273
+ dash.on(MediaPlayer.events.QUALITY_CHANGE_REQUESTED, (evt) => {
274
+ const newLevel = this.getLevel(evt.newRepresentation.index)
271
275
  this.onLevelSwitch(newLevel)
272
276
  })
273
277
 
@@ -275,15 +279,15 @@ export default class DashPlayback extends BasePlayback {
275
279
  })
276
280
 
277
281
  this._dash.on(
278
- DASHJS.MediaPlayer.events.QUALITY_CHANGE_RENDERED,
279
- (evt: DASHJS.QualityChangeRenderedEvent) => {
280
- const currentLevel = this.getLevel(evt.newQuality)
282
+ MediaPlayer.events.QUALITY_CHANGE_RENDERED,
283
+ (evt: QualityChangeRenderedEvent) => {
284
+ const currentLevel = this.getLevel(evt.newRepresentation.index)
281
285
  this.onLevelSwitchEnd(currentLevel)
282
286
  },
283
287
  )
284
288
 
285
289
  this._dash.on(
286
- DASHJS.MediaPlayer.events.METRIC_ADDED,
290
+ MediaPlayer.events.METRIC_ADDED,
287
291
  (e: DashMetricEvent) => {
288
292
  // Listen for the first manifest request in order to update player UI
289
293
  if ((e.metric as string) === 'DVRInfo') {
@@ -302,14 +306,14 @@ export default class DashPlayback extends BasePlayback {
302
306
  )
303
307
 
304
308
  this._dash.on(
305
- DASHJS.MediaPlayer.events.PLAYBACK_RATE_CHANGED,
306
- (e: DASHJS.PlaybackRateChangedEvent) => {
309
+ MediaPlayer.events.PLAYBACK_RATE_CHANGED,
310
+ (e: PlaybackRateChangedEvent) => {
307
311
  this.trigger(PlaybackEvents.PLAYBACK_RATE_CHANGED, e.playbackRate)
308
312
  },
309
313
  )
310
314
 
311
- this._dash.on(DASHJS.MediaPlayer.events.TRACK_CHANGE_RENDERED, (e: any) => {
312
- if ((e as DASHJS.TrackChangeRenderedEvent).mediaType === 'audio') {
315
+ this._dash.on(MediaPlayer.events.TRACK_CHANGE_RENDERED, (e: any) => {
316
+ if ((e as TrackChangeRenderedEvent).mediaType === 'audio') {
313
317
  this.trigger(
314
318
  Events.PLAYBACK_AUDIO_CHANGED,
315
319
  toClapprTrack(e.newMediaInfo),
@@ -442,17 +446,17 @@ export default class DashPlayback extends BasePlayback {
442
446
  const e = (event as MediaPlayerErrorEvent).error
443
447
  switch (e.code) {
444
448
  // TODO test handling of these errors
445
- case DASHJS.MediaPlayer.errors.MANIFEST_LOADER_PARSING_FAILURE_ERROR_CODE:
446
- case DASHJS.MediaPlayer.errors.MANIFEST_LOADER_LOADING_FAILURE_ERROR_CODE:
447
- case DASHJS.MediaPlayer.errors.DOWNLOAD_ERROR_ID_MANIFEST_CODE:
448
- case DASHJS.MediaPlayer.errors.DOWNLOAD_ERROR_ID_CONTENT_CODE:
449
- case DASHJS.MediaPlayer.errors.DOWNLOAD_ERROR_ID_INITIALIZATION_CODE:
449
+ case MediaPlayer.errors.MANIFEST_LOADER_PARSING_FAILURE_ERROR_CODE:
450
+ case MediaPlayer.errors.MANIFEST_LOADER_LOADING_FAILURE_ERROR_CODE:
451
+ case MediaPlayer.errors.DOWNLOAD_ERROR_ID_MANIFEST_CODE:
452
+ case MediaPlayer.errors.DOWNLOAD_ERROR_ID_CONTENT_CODE:
453
+ case MediaPlayer.errors.DOWNLOAD_ERROR_ID_INITIALIZATION_CODE:
450
454
  // TODO these probably indicate a broken manifest and should be treated by removing the source
451
- case DASHJS.MediaPlayer.errors.MANIFEST_ERROR_ID_NOSTREAMS_CODE:
452
- case DASHJS.MediaPlayer.errors.MANIFEST_ERROR_ID_PARSE_CODE:
453
- case DASHJS.MediaPlayer.errors.MANIFEST_ERROR_ID_MULTIPLEXED_CODE:
454
- case DASHJS.MediaPlayer.errors.MEDIASOURCE_TYPE_UNSUPPORTED_CODE:
455
- case DASHJS.MediaPlayer.errors.SEGMENT_BASE_LOADER_ERROR_CODE:
455
+ case MediaPlayer.errors.MANIFEST_ERROR_ID_NOSTREAMS_CODE:
456
+ case MediaPlayer.errors.MANIFEST_ERROR_ID_PARSE_CODE:
457
+ case MediaPlayer.errors.MANIFEST_ERROR_ID_MULTIPLEXED_CODE:
458
+ case MediaPlayer.errors.MEDIASOURCE_TYPE_UNSUPPORTED_CODE:
459
+ case MediaPlayer.errors.SEGMENT_BASE_LOADER_ERROR_CODE:
456
460
  this.triggerError({
457
461
  code: PlaybackErrorCode.MediaSourceUnavailable,
458
462
  message: e.message,
@@ -525,7 +529,7 @@ export default class DashPlayback extends BasePlayback {
525
529
  return false
526
530
  }
527
531
  return (
528
- this._dash?.getDVRWindowSize() >= this._minDvrSize &&
532
+ this._dash?.getDvrWindow()?.size >= this._minDvrSize &&
529
533
  this.getPlaybackType() === Playback.LIVE
530
534
  )
531
535
  }
@@ -572,13 +576,13 @@ export default class DashPlayback extends BasePlayback {
572
576
 
573
577
  private destroyInstance() {
574
578
  if (this._dash) {
575
- this._dash.off(DASHJS.MediaPlayer.events.ERROR, this._onDASHJSSError)
579
+ this._dash.off(MediaPlayer.events.ERROR, this._onDASHJSSError)
576
580
  this._dash.off(
577
- DASHJS.MediaPlayer.events.PLAYBACK_ERROR,
581
+ MediaPlayer.events.PLAYBACK_ERROR,
578
582
  this._onPlaybackError,
579
583
  )
580
584
  this._dash.off(
581
- DASHJS.MediaPlayer.events.MANIFEST_LOADED,
585
+ MediaPlayer.events.MANIFEST_LOADED,
582
586
  this.getDuration,
583
587
  )
584
588
  this._dash.reset()
@@ -601,12 +605,13 @@ export default class DashPlayback extends BasePlayback {
601
605
  }
602
606
  }
603
607
 
604
- _fillLevels(levels: DashBitrateInfo[]) {
605
- // TOOD check that levels[i].qualityIndex === i
608
+ _fillLevels(levels: Representation[]) {
609
+ // TOOD check that levels[i].index === i
610
+ trace(`${T} _fillLevels`, { levels })
606
611
  this._levels = levels.map((level) => {
607
612
  return {
608
- level: level.qualityIndex,
609
- bitrate: level.bitrate,
613
+ level: level.index,
614
+ bitrate: level.bitrateInKbit * 1000,
610
615
  width: level.width,
611
616
  height: level.height,
612
617
  }
@@ -635,10 +640,10 @@ export default class DashPlayback extends BasePlayback {
635
640
  return this._playbackType === Playback.VOD || this.dvrEnabled
636
641
  }
637
642
 
638
- private getLevel(quality: number) {
639
- const ret = this.levels.find((level) => level.level === quality)
640
- assert.ok(ret, 'Invalid quality level')
641
- return ret
643
+ private getLevel(quality: number): QualityLevel {
644
+ const level = this.levels.find((level) => level.level === quality)
645
+ assert.ok(level, 'Invalid quality level')
646
+ return level
642
647
  }
643
648
 
644
649
  setPlaybackRate(rate: number) {
@@ -707,7 +712,7 @@ DashPlayback.canPlay = function (resource, mimeType) {
707
712
  return typeof ctor === 'function'
708
713
  }
709
714
 
710
- function toClapprTrack(t: DASHJS.MediaInfo): AudioTrack {
715
+ function toClapprTrack(t: MediaInfo): AudioTrack {
711
716
  return {
712
717
  id: t.id,
713
718
  kind: t.roles && t.roles?.length > 0 ? t.roles[0] : 'main', // TODO
@@ -305,7 +305,7 @@ export default class HlsPlayback extends BasePlayback {
305
305
  // added/removed every 5.
306
306
  this._extrapolatedWindowNumSegments =
307
307
  !this.options.playback ||
308
- typeof this.options.playback.extrapolatedWindowNumSegments === 'undefined'
308
+ typeof this.options.playback.extrapolatedWindowNumSegments === 'undefined'
309
309
  ? 2
310
310
  : this.options.playback.extrapolatedWindowNumSegments
311
311
 
@@ -527,7 +527,7 @@ export default class HlsPlayback extends BasePlayback {
527
527
  }
528
528
 
529
529
  // this playback manages the src on the video element itself
530
- protected override _setupSrc(srcUrl: string) {} // eslint-disable-line no-unused-vars
530
+ protected override _setupSrc(srcUrl: string) { } // eslint-disable-line no-unused-vars
531
531
 
532
532
  private _startTimeUpdateTimer() {
533
533
  if (this._timeUpdateTimer) {
@@ -592,7 +592,7 @@ export default class HlsPlayback extends BasePlayback {
592
592
  // assume live if time within 3 seconds of end of stream
593
593
  this.dvrEnabled && this._updateDvr(time < this.getDuration() - 3)
594
594
  time += this._startTime
595
- ;(this.el as HTMLMediaElement).currentTime = time
595
+ ; (this.el as HTMLMediaElement).currentTime = time
596
596
  }
597
597
 
598
598
  seekToLivePoint() {
@@ -781,12 +781,12 @@ export default class HlsPlayback extends BasePlayback {
781
781
  start: Math.max(
782
782
  0,
783
783
  (this.el as HTMLMediaElement).buffered.start(i) -
784
- this._playableRegionStartTime,
784
+ this._playableRegionStartTime,
785
785
  ),
786
786
  end: Math.max(
787
787
  0,
788
788
  (this.el as HTMLMediaElement).buffered.end(i) -
789
- this._playableRegionStartTime,
789
+ this._playableRegionStartTime,
790
790
  ),
791
791
  },
792
792
  ]
@@ -826,7 +826,7 @@ export default class HlsPlayback extends BasePlayback {
826
826
  if (!this._hls) {
827
827
  return
828
828
  }
829
- ;(this.el as HTMLMediaElement).pause()
829
+ ; (this.el as HTMLMediaElement).pause()
830
830
  if (this.dvrEnabled) {
831
831
  this._updateDvr(true)
832
832
  }
@@ -942,7 +942,7 @@ export default class HlsPlayback extends BasePlayback {
942
942
  Math.max(
943
943
  fragments[0].start,
944
944
  previousPlayableRegionStartTime +
945
- this._extrapolatedWindowDuration,
945
+ this._extrapolatedWindowDuration,
946
946
  ) * 1000,
947
947
  }
948
948
  }