@gcorevideo/player 2.6.0 → 2.6.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.
@@ -1,8 +1,8 @@
1
1
  // Copyright 2014 Globo.com Player authors. All rights reserved.
2
2
  // Use of this source code is governed by a BSD-style
3
3
  // license that can be found in the LICENSE file.
4
- import { Events, HTML5Video, Log, Playback, Utils, } from '@clappr/core';
5
- import assert from 'assert'; // uses Node.js's assert types
4
+ import { Events, HTML5Video, Log, Playback, Utils } from '@clappr/core';
5
+ import assert from 'assert';
6
6
  import DASHJS from 'dashjs';
7
7
  import { trace } from '../../trace/index.js';
8
8
  const AUTO = -1;
@@ -11,24 +11,38 @@ const T = 'DashPlayback';
11
11
  export default class DashPlayback extends HTML5Video {
12
12
  _levels = null;
13
13
  _currentLevel = null;
14
+ // true when the actual duration is longer than hlsjs's live sync point
15
+ // when this is false playableRegionDuration will be the actual duration
16
+ // when this is true playableRegionDuration will exclude the time after the sync point
14
17
  _durationExcludesAfterLiveSyncPoint = false;
15
18
  _isReadyState = false;
19
+ // if content is removed from the beginning then this empty area should
20
+ // be ignored. "playableRegionDuration" excludes the empty area
16
21
  _playableRegionDuration = 0;
22
+ // for hls streams which have dvr with a sliding window,
23
+ // the content at the start of the playlist is removed as new
24
+ // content is appended at the end.
25
+ // this means the actual playable start time will increase as the
26
+ // start content is deleted
27
+ // For streams with dvr where the entire recording is kept from the
28
+ // beginning this should stay as 0
17
29
  _playableRegionStartTime = 0;
18
30
  _playbackType = Playback.VOD;
31
+ // #EXT-X-PLAYLIST-TYPE
19
32
  _playlistType = null;
20
33
  // #EXT-X-PROGRAM-DATE-TIME
21
34
  _programDateTime = 0;
22
35
  _dash = null;
23
36
  _extrapolatedWindowDuration = 0;
24
- _extrapolatedWindowNumSegments = 0;
37
+ // _extrapolatedWindowNumSegments: number = 0
25
38
  _lastDuration = null;
26
39
  _lastTimeUpdate = { current: 0, total: 0 };
40
+ // {local, remote} remote is the time in the video element that should represent 0
41
+ // local is the system time when the 'remote' measurment took place
27
42
  _localStartTimeCorrelation = null;
43
+ // {local, remote} remote is the time in the video element that should represents the end
44
+ // local is the system time when the 'remote' measurment took place
28
45
  _localEndTimeCorrelation = null;
29
- _recoverAttemptsRemaining = 0;
30
- _recoveredAudioCodecError = false;
31
- _recoveredDecodingError = false;
32
46
  startChangeQuality = false;
33
47
  manifestInfo = null;
34
48
  // #EXT-X-TARGETDURATION
@@ -53,19 +67,14 @@ export default class DashPlayback extends HTML5Video {
53
67
  set currentLevel(id) {
54
68
  this._currentLevel = id;
55
69
  this.trigger(Events.PLAYBACK_LEVEL_SWITCH_START);
56
- const cfg = {
57
- streaming: {
58
- abr: {
59
- autoSwitchBitrate: {
60
- video: id === -1,
61
- },
62
- ABRStrategy: 'abrL2A',
63
- },
64
- },
65
- };
70
+ const settings = this.options.dash ? structuredClone(this.options.dash) : {};
71
+ settings.streaming = settings.streaming || {};
72
+ settings.streaming.abr = settings.streaming.abr || {};
73
+ settings.streaming.abr.autoSwitchBitrate = settings.streaming.abr.autoSwitchBitrate || {};
74
+ settings.streaming.abr.autoSwitchBitrate.video = id === -1;
66
75
  assert.ok(this._dash, 'An instance of dashjs MediaPlayer is required to switch levels');
67
76
  const dash = this._dash;
68
- this.options.dash && dash.updateSettings({ ...this.options.dash, ...cfg });
77
+ dash.updateSettings(settings);
69
78
  if (id !== -1) {
70
79
  this._dash.setQualityFor('video', id);
71
80
  }
@@ -122,59 +131,26 @@ export default class DashPlayback extends HTML5Video {
122
131
  }
123
132
  constructor(options, i18n, playerError) {
124
133
  super(options, i18n, playerError);
125
- // backwards compatibility (TODO: remove on 0.3.0)
126
- // this.options.playback || (this.options.playback = this.options);
127
- // The size of the start time extrapolation window measured as a multiple of segments.
128
- // Should be 2 or higher, or 0 to disable. Should only need to be increased above 2 if more than one segment is
129
- // removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are
130
- // added/removed every 5.
131
- this._extrapolatedWindowNumSegments =
132
- this.options.playback?.extrapolatedWindowNumSegments ?? 2;
133
134
  if (this.options.playbackType) {
134
135
  this._playbackType = this.options.playbackType;
135
136
  }
136
- // this._lastTimeUpdate = { current: 0, total: 0 };
137
- // this._lastDuration = null;
138
- // for hls streams which have dvr with a sliding window,
139
- // the content at the start of the playlist is removed as new
140
- // content is appended at the end.
141
- // this means the actual playable start time will increase as the
142
- // start content is deleted
143
- // For streams with dvr where the entire recording is kept from the
144
- // beginning this should stay as 0
145
- // this._playableRegionStartTime = 0;
146
- // {local, remote} remote is the time in the video element that should represent 0
147
- // local is the system time when the 'remote' measurment took place
148
- // this._localStartTimeCorrelation = null;
149
- // {local, remote} remote is the time in the video element that should represents the end
150
- // local is the system time when the 'remote' measurment took place
151
- // this._localEndTimeCorrelation = null;
152
- // if content is removed from the beginning then this empty area should
153
- // be ignored. "playableRegionDuration" excludes the empty area
154
- // this._playableRegionDuration = 0;
155
- // #EXT-X-PROGRAM-DATE-TIME
156
- // this._programDateTime = 0;
157
- // this.manifestInfo = null;
158
- // true when the actual duration is longer than hlsjs's live sync point
159
- // when this is false playableRegionDuration will be the actual duration
160
- // when this is true playableRegionDuration will exclude the time after the sync point
161
- // this._durationExcludesAfterLiveSyncPoint = false;
162
- // // #EXT-X-TARGETDURATION
163
- // this._segmentTargetDuration = null;
164
- // #EXT-X-PLAYLIST-TYPE
165
- // this._playlistType = null;
166
- if (this.options.hlsRecoverAttempts) {
167
- this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts;
168
- }
169
137
  }
170
138
  _setup() {
171
139
  const dash = DASHJS.MediaPlayer().create();
172
140
  this._dash = dash;
173
141
  this._dash.initialize();
174
- const cfg = this.options.dash ?? {};
175
- cfg.streaming = cfg.streaming || {};
176
- cfg.streaming.text = cfg.streaming.text || { defaultEnabled: false };
177
- this.options.dash && this._dash.updateSettings(cfg);
142
+ if (this.options.dash) {
143
+ const settings = structuredClone(this.options.dash);
144
+ if (!settings.streaming) {
145
+ settings.streaming = {};
146
+ }
147
+ if (!settings.streaming.text) {
148
+ settings.streaming.text = {
149
+ defaultEnabled: false,
150
+ };
151
+ }
152
+ this._dash.updateSettings(this.options.dash);
153
+ }
178
154
  this._dash.attachView(this.el);
179
155
  this._dash.setAutoPlay(false);
180
156
  this._dash.attachSource(this.options.src);
@@ -216,28 +192,6 @@ export default class DashPlayback extends HTML5Video {
216
192
  this._isReadyState = true;
217
193
  this.trigger(Events.PLAYBACK_READY, this.name);
218
194
  }
219
- // TODO
220
- // _recover(evt, data, error) {
221
- // console.warn('recover', evt, data, error);
222
- // assert.ok(this._dash, 'An instance of dashjs MediaPlayer is required to recover');
223
- // // TODO figure out what's going on here
224
- // const dash = this._dash;
225
- // if (!this._recoveredDecodingError) {
226
- // this._recoveredDecodingError = true;
227
- // // dash.recoverMediaError();
228
- // } else if (!this._recoveredAudioCodecError) {
229
- // this._recoveredAudioCodecError = true;
230
- // // dash.swapAudioCodec();
231
- // // dash.recoverMediaError();
232
- // } else {
233
- // // TODO what does it have to do with hlsjs?
234
- // Log.error('hlsjs: failed to recover', { evt, data });
235
- // error.level = PlayerError.Levels.FATAL;
236
- // const formattedError = this.createError(error);
237
- // this.trigger(Events.PLAYBACK_ERROR, formattedError);
238
- // this.stop();
239
- // }
240
- // }
241
195
  // override
242
196
  _setupSrc() {
243
197
  // this playback manages the src on the video element itself
@@ -305,7 +259,6 @@ export default class DashPlayback extends HTML5Video {
305
259
  _updateSettings() {
306
260
  if (this._playbackType === Playback.VOD) {
307
261
  this.settings.left = ['playpause', 'position', 'duration'];
308
- // this.settings.left.push('playstop');
309
262
  }
310
263
  else if (this.dvrEnabled) {
311
264
  this.settings.left = ['playpause'];
@@ -501,131 +454,6 @@ export default class DashPlayback extends HTML5Video {
501
454
  });
502
455
  this.trigger(Events.PLAYBACK_LEVELS_AVAILABLE, this._levels);
503
456
  }
504
- // _onLevelUpdated(_: any, data) {
505
- // this._segmentTargetDuration = data.details.targetduration;
506
- // this._playlistType = data.details.type || null;
507
- // let startTimeChanged = false;
508
- // let durationChanged = false;
509
- // const fragments = data.details.fragments;
510
- // const previousPlayableRegionStartTime = this._playableRegionStartTime;
511
- // const previousPlayableRegionDuration = this._playableRegionDuration;
512
- // if (fragments.length === 0) {
513
- // return;
514
- // }
515
- // // #EXT-X-PROGRAM-DATE-TIME
516
- // if (fragments[0].rawProgramDateTime) {
517
- // this._programDateTime = fragments[0].rawProgramDateTime;
518
- // }
519
- // if (this._playableRegionStartTime !== fragments[0].start) {
520
- // startTimeChanged = true;
521
- // this._playableRegionStartTime = fragments[0].start;
522
- // }
523
- // if (startTimeChanged) {
524
- // if (!this._localStartTimeCorrelation) {
525
- // // set the correlation to map to middle of the extrapolation window
526
- // this._localStartTimeCorrelation = {
527
- // local: this._now,
528
- // remote: (fragments[0].start + (this._extrapolatedWindowDuration / 2)) * 1000
529
- // };
530
- // } else {
531
- // // check if the correlation still works
532
- // const corr = this._localStartTimeCorrelation;
533
- // const timePassed = this._now - corr.local;
534
- // // this should point to a time within the extrapolation window
535
- // const startTime = (corr.remote + timePassed) / 1000;
536
- // if (startTime < fragments[0].start) {
537
- // // our start time is now earlier than the first chunk
538
- // // (maybe the chunk was removed early)
539
- // // reset correlation so that it sits at the beginning of the first available chunk
540
- // this._localStartTimeCorrelation = {
541
- // local: this._now,
542
- // remote: fragments[0].start * 1000
543
- // };
544
- // } else if (startTime > previousPlayableRegionStartTime + this._extrapolatedWindowDuration) {
545
- // // start time was past the end of the old extrapolation window (so would have been capped)
546
- // // see if now that time would be inside the window, and if it would be set the correlation
547
- // // so that it resumes from the time it was at at the end of the old window
548
- // // update the correlation so that the time starts counting again from the value it's on now
549
- // this._localStartTimeCorrelation = {
550
- // local: this._now,
551
- // remote: Math.max(
552
- // fragments[0].start,
553
- // previousPlayableRegionStartTime + this._extrapolatedWindowDuration
554
- // ) * 1000
555
- // };
556
- // }
557
- // }
558
- // }
559
- // let newDuration = data.details.totalduration;
560
- // // if it's a live stream then shorten the duration to remove access
561
- // // to the area after hlsjs's live sync point
562
- // // seeks to areas after this point sometimes have issues
563
- // if (this._playbackType === Playback.LIVE) {
564
- // const fragmentTargetDuration = data.details.targetduration;
565
- // const hlsjsConfig = this.options.playback.hlsjsConfig || {};
566
- // // eslint-disable-next-line no-undef
567
- // const liveSyncDurationCount = hlsjsConfig.liveSyncDurationCount || HLSJS.DefaultConfig.liveSyncDurationCount;
568
- // const hiddenAreaDuration = fragmentTargetDuration * liveSyncDurationCount;
569
- // if (hiddenAreaDuration <= newDuration) {
570
- // newDuration -= hiddenAreaDuration;
571
- // this._durationExcludesAfterLiveSyncPoint = true;
572
- // } else {
573
- // this._durationExcludesAfterLiveSyncPoint = false;
574
- // }
575
- // }
576
- // if (newDuration !== this._playableRegionDuration) {
577
- // durationChanged = true;
578
- // this._playableRegionDuration = newDuration;
579
- // }
580
- // // Note the end time is not the playableRegionDuration
581
- // // The end time will always increase even if content is removed from the beginning
582
- // const endTime = fragments[0].start + newDuration;
583
- // const previousEndTime = previousPlayableRegionStartTime + previousPlayableRegionDuration;
584
- // const endTimeChanged = endTime !== previousEndTime;
585
- // if (endTimeChanged) {
586
- // if (!this._localEndTimeCorrelation) {
587
- // // set the correlation to map to the end
588
- // this._localEndTimeCorrelation = {
589
- // local: this._now,
590
- // remote: endTime * 1000
591
- // };
592
- // } else {
593
- // // check if the correlation still works
594
- // const corr = this._localEndTimeCorrelation;
595
- // const timePassed = this._now - corr.local;
596
- // // this should point to a time within the extrapolation window from the end
597
- // const extrapolatedEndTime = (corr.remote + timePassed) / 1000;
598
- // if (extrapolatedEndTime > endTime) {
599
- // this._localEndTimeCorrelation = {
600
- // local: this._now,
601
- // remote: endTime * 1000
602
- // };
603
- // } else if (extrapolatedEndTime < endTime - this._extrapolatedWindowDuration) {
604
- // // our extrapolated end time is now earlier than the extrapolation window from the actual end time
605
- // // (maybe a chunk became available early)
606
- // // reset correlation so that it sits at the beginning of the extrapolation window from the end time
607
- // this._localEndTimeCorrelation = {
608
- // local: this._now,
609
- // remote: (endTime - this._extrapolatedWindowDuration) * 1000
610
- // };
611
- // } else if (extrapolatedEndTime > previousEndTime) {
612
- // // end time was past the old end time (so would have been capped)
613
- // // set the correlation so that it resumes from the time it was at at the end of the old window
614
- // this._localEndTimeCorrelation = {
615
- // local: this._now,
616
- // remote: previousEndTime * 1000
617
- // };
618
- // }
619
- // }
620
- // }
621
- // // now that the values have been updated call any methods that use on them so they get the updated values
622
- // // immediately
623
- // durationChanged && this._onDurationChange();
624
- // startTimeChanged && this._onProgress();
625
- // }
626
- // _onFragmentLoaded(evt, data) {
627
- // this.trigger(Events.PLAYBACK_FRAGMENT_LOADED, data);
628
- // }
629
457
  onLevelSwitch(currentLevel) {
630
458
  this.trigger(Events.PLAYBACK_BITRATE, {
631
459
  height: currentLevel.height,
@@ -646,7 +474,6 @@ DashPlayback.canPlay = function (resource, mimeType) {
646
474
  const isDash = (resourceParts.length > 1 && resourceParts[1].toLowerCase() === 'mpd') ||
647
475
  mimeType === 'application/dash+xml' ||
648
476
  mimeType === 'video/mp4';
649
- // TODO check
650
477
  const ms = window.MediaSource;
651
478
  const mms = 'ManagedMediaSource' in window ? window.ManagedMediaSource : undefined;
652
479
  const wms = 'WebKitMediaSource' in window ? window.WebKitMediaSource : undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gcorevideo/player",
3
- "version": "2.6.0",
3
+ "version": "2.6.2",
4
4
  "description": "Gcore JavaScript video player",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",