shaka-player 4.7.8 → 4.7.10

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.
@@ -1685,7 +1685,7 @@ shaka.dash.DashParser = class {
1685
1685
  // An attribute which is present and set to 0 should still result in
1686
1686
  // periodic updates. For more, see:
1687
1687
  // https://github.com/Dash-Industry-Forum/Guidelines-TimingModel/issues/48
1688
- if (this.updatePeriod_ <= 0) {
1688
+ if (this.updatePeriod_ < 0) {
1689
1689
  return;
1690
1690
  }
1691
1691
 
@@ -755,16 +755,10 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
755
755
 
756
756
  this.evict(this.periodStart_);
757
757
 
758
- if (timeline.length === 0) {
759
- return;
760
- }
761
-
762
- if (this.periodEnd_ !== Infinity) {
763
- // Adjust the last timeline entry to match the period end
764
- const lastTimePeriod = timeline[timeline.length - 1];
765
- // NOTE: end should be relative to period start
766
- lastTimePeriod.end = this.periodEnd_ - this.periodStart_;
767
- }
758
+ // Do NOT adjust last range to match period end! With high precision
759
+ // timestamps several recalculations may give wrong results on less precise
760
+ // platforms. To mitigate that, we're using cached |periodEnd_| value in
761
+ // find/get() methods whenever possible.
768
762
  }
769
763
 
770
764
  /**
@@ -784,7 +778,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
784
778
  const timeline = this.templateInfo_.timeline;
785
779
 
786
780
  // Early exit if the time isn't within this period
787
- if (time < this.periodStart_ || time > this.periodEnd_) {
781
+ if (time < this.periodStart_ || time >= this.periodEnd_) {
788
782
  return null;
789
783
  }
790
784
 
@@ -797,10 +791,14 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
797
791
  // the references by a fraction of a second. To account for this, we use
798
792
  // the start of the next segment as /end/, unless this is the last
799
793
  // reference, in which case we use the period end as the /end/
800
- let end = range.end + this.periodStart_;
794
+ let end;
801
795
 
802
796
  if (i < lastIndex) {
803
797
  end = timeline[i + 1].start + this.periodStart_;
798
+ } else if (this.periodEnd_ === Infinity) {
799
+ end = range.end + this.periodStart_;
800
+ } else {
801
+ end = this.periodEnd_;
804
802
  }
805
803
 
806
804
  if ((time >= start) && (time < end)) {
@@ -831,6 +829,12 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
831
829
  .unscaledPresentationTimeOffset + range.unscaledStart;
832
830
  const timestampOffset = this.periodStart_ -
833
831
  this.templateInfo_.scaledPresentationTimeOffset;
832
+ const trueSegmentEnd = this.periodStart_ + range.end;
833
+ let segmentEnd = trueSegmentEnd;
834
+ if (correctedPosition === this.getNumReferences() - 1 &&
835
+ this.periodEnd_ !== Infinity) {
836
+ segmentEnd = this.periodEnd_;
837
+ }
834
838
 
835
839
  const partialSegmentRefs = [];
836
840
 
@@ -901,7 +905,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
901
905
 
902
906
  ref = new shaka.media.SegmentReference(
903
907
  this.periodStart_ + range.start,
904
- this.periodStart_ + range.end,
908
+ segmentEnd,
905
909
  createUrisCb,
906
910
  /* startByte= */ 0,
907
911
  /* endByte= */ null,
@@ -916,6 +920,7 @@ shaka.dash.TimelineSegmentIndex = class extends shaka.media.SegmentIndex {
916
920
  shaka.media.SegmentReference.Status.AVAILABLE,
917
921
  this.aes128Key_,
918
922
  /* allPartialSegments= */ range.partialSegments > 0);
923
+ ref.trueEndTime = trueSegmentEnd;
919
924
  this.references[correctedPosition] = ref;
920
925
  }
921
926
 
@@ -2839,12 +2839,12 @@ shaka.hls.HlsParser = class {
2839
2839
  // Don't download the key object until the segment is parsed, to avoid a
2840
2840
  // startup delay for long manifests with lots of keys.
2841
2841
  keyInfo.fetchKey = async () => {
2842
- const keyUri = shaka.hls.Utils.constructSegmentUris(
2842
+ const keyUris = shaka.hls.Utils.constructSegmentUris(
2843
2843
  getUris(), drmTag.getRequiredAttrValue('URI'), variables);
2844
2844
 
2845
2845
  const requestType = shaka.net.NetworkingEngine.RequestType.KEY;
2846
2846
  const request = shaka.net.NetworkingEngine.makeRequest(
2847
- [keyUri], this.config_.retryParameters);
2847
+ keyUris, this.config_.retryParameters);
2848
2848
  const keyResponse = await this.makeNetworkRequest_(request, requestType);
2849
2849
 
2850
2850
  // keyResponse.status is undefined when URI is "data:text/plain;base64,"
@@ -69,6 +69,30 @@ shaka.media.ContentWorkarounds = class {
69
69
  })
70
70
  .fullBox('encv', onEncryptionMetadataBox)
71
71
  .fullBox('enca', onEncryptionMetadataBox)
72
+ .fullBox('dvav', (box) => {
73
+ boxesToModify.push({
74
+ box,
75
+ newType: ContentWorkarounds.BOX_TYPE_ENCV_,
76
+ });
77
+ })
78
+ .fullBox('dva1', (box) => {
79
+ boxesToModify.push({
80
+ box,
81
+ newType: ContentWorkarounds.BOX_TYPE_ENCV_,
82
+ });
83
+ })
84
+ .fullBox('dvh1', (box) => {
85
+ boxesToModify.push({
86
+ box,
87
+ newType: ContentWorkarounds.BOX_TYPE_ENCV_,
88
+ });
89
+ })
90
+ .fullBox('dvhe', (box) => {
91
+ boxesToModify.push({
92
+ box,
93
+ newType: ContentWorkarounds.BOX_TYPE_ENCV_,
94
+ });
95
+ })
72
96
  .fullBox('hev1', (box) => {
73
97
  boxesToModify.push({
74
98
  box,
@@ -129,7 +129,10 @@ shaka.media.InitSegmentReference = class {
129
129
  static equal(reference1, reference2) {
130
130
  const ArrayUtils = shaka.util.ArrayUtils;
131
131
  const BufferUtils = shaka.util.BufferUtils;
132
- if (!reference1 || !reference2) {
132
+
133
+ if (reference1 === reference2) {
134
+ return true;
135
+ } else if (!reference1 || !reference2) {
133
136
  return reference1 == reference2;
134
137
  } else {
135
138
  return reference1.getStartByte() == reference2.getStartByte() &&
@@ -2163,8 +2163,8 @@ shaka.media.StreamingEngine = class {
2163
2163
  const bufferedBehind = presentationTime - startTime;
2164
2164
 
2165
2165
  const overflow = bufferedBehind - bufferBehind;
2166
- // See: https://github.com/shaka-project/shaka-player/issues/2982
2167
- if (overflow <= 0.01) {
2166
+ // See: https://github.com/shaka-project/shaka-player/issues/6240
2167
+ if (overflow <= 1) {
2168
2168
  shaka.log.v2(logPrefix,
2169
2169
  'buffer behind okay:',
2170
2170
  'presentationTime=' + presentationTime,
package/lib/player.js CHANGED
@@ -1795,8 +1795,17 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
1795
1795
 
1796
1796
  this.drmEngine_.configure(this.config_.drm);
1797
1797
 
1798
+ const tracksChanged = shaka.util.StreamUtils.applyRestrictions(
1799
+ this.manifest_.variants, this.config_.restrictions, this.maxHwRes_);
1800
+ if (tracksChanged && this.streamingEngine_) {
1801
+ this.onTracksChanged_();
1802
+ }
1803
+
1804
+ const playableVariants = shaka.util.StreamUtils.getPlayableVariants(
1805
+ this.manifest_.variants);
1806
+
1798
1807
  await this.drmEngine_.initForPlayback(
1799
- this.manifest_.variants,
1808
+ playableVariants,
1800
1809
  this.manifest_.offlineSessionIds);
1801
1810
 
1802
1811
  await this.drmEngine_.attach(this.video_);
@@ -6925,7 +6934,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
6925
6934
  * @export
6926
6935
  */
6927
6936
  // eslint-disable-next-line no-useless-concat
6928
- shaka.Player.version = 'v4.7.8' + '-uncompiled'; // x-release-please-version
6937
+ shaka.Player.version = 'v4.7.10' + '-uncompiled'; // x-release-please-version
6929
6938
 
6930
6939
  // Initialize the deprecation system using the version string we just set
6931
6940
  // on the player.
@@ -27,13 +27,6 @@ shaka.util.CmcdManager = class {
27
27
  /** @private {?shaka.extern.CmcdConfiguration} */
28
28
  this.config_ = config;
29
29
 
30
- /**
31
- * Session ID
32
- *
33
- * @private {string}
34
- */
35
- this.sid_ = '';
36
-
37
30
  /**
38
31
  * Streaming format
39
32
  *
@@ -65,9 +58,6 @@ shaka.util.CmcdManager = class {
65
58
  */
66
59
  configure(config) {
67
60
  this.config_ = config;
68
- if (this.config_.sessionId && this.config_.sessionId != this.sid_) {
69
- this.sid_ = '';
70
- }
71
61
  }
72
62
 
73
63
  /**
@@ -295,13 +285,13 @@ shaka.util.CmcdManager = class {
295
285
  * @private
296
286
  */
297
287
  createData_() {
298
- if (!this.sid_) {
299
- this.sid_ = this.config_.sessionId || window.crypto.randomUUID();
288
+ if (!this.config_.sessionId) {
289
+ this.config_.sessionId = window.crypto.randomUUID();
300
290
  }
301
291
  return {
302
292
  v: shaka.util.CmcdManager.Version,
303
293
  sf: this.sf_,
304
- sid: this.sid_,
294
+ sid: this.config_.sessionId,
305
295
  cid: this.config_.contentId,
306
296
  mtp: this.playerInterface_.getBandwidthEstimate() / 1000,
307
297
  };
@@ -1215,7 +1215,18 @@ shaka.util.PeriodCombiner = class {
1215
1215
  return false;
1216
1216
  }
1217
1217
 
1218
- // If language-based differences haven't decided this, look at roles. If
1218
+ // If language-based differences haven't decided this, look at labels.
1219
+ // If available options differ, look does any matches with output stream.
1220
+ if (best.label !== candidate.label) {
1221
+ if (outputStream.label === best.label) {
1222
+ return false;
1223
+ }
1224
+ if (outputStream.label === candidate.label) {
1225
+ return true;
1226
+ }
1227
+ }
1228
+
1229
+ // If label-based differences haven't decided this, look at roles. If
1219
1230
  // the candidate has more roles in common with the output, upgrade to the
1220
1231
  // candidate.
1221
1232
  if (outputStream.roles.length) {
@@ -1410,6 +1421,17 @@ shaka.util.PeriodCombiner = class {
1410
1421
  return false;
1411
1422
  }
1412
1423
 
1424
+ // If language-based differences haven't decided this, look at labels.
1425
+ // If available options differ, look does any matches with output stream.
1426
+ if (best.label !== candidate.label) {
1427
+ if (outputStream.label === best.label) {
1428
+ return false;
1429
+ }
1430
+ if (outputStream.label === candidate.label) {
1431
+ return true;
1432
+ }
1433
+ }
1434
+
1413
1435
  // If the candidate has more roles in common with the output, upgrade to the
1414
1436
  // candidate.
1415
1437
  if (outputStream.roles.length) {
@@ -908,7 +908,7 @@ shaka.util.StreamUtils = class {
908
908
  // currently don't support 'fLaC', while 'flac' is supported by most
909
909
  // major browsers.
910
910
  // See https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
911
- if (codecs === 'fLaC') {
911
+ if (codecs === 'fLaC' && !shaka.util.Platform.isSafari()) {
912
912
  return 'flac';
913
913
  }
914
914
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shaka-player",
3
3
  "description": "DASH/EME video player library",
4
- "version": "4.7.8",
4
+ "version": "4.7.10",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -43,7 +43,7 @@
43
43
  "karma-coverage": "^2.2.0",
44
44
  "karma-jasmine": "^4.0.1",
45
45
  "karma-jasmine-ajax": "^0.1.13",
46
- "karma-local-wd-launcher": "^1.6.6",
46
+ "karma-local-wd-launcher": "^1.6.7",
47
47
  "karma-opera-launcher": "^1.0.0",
48
48
  "karma-sourcemap-loader": "^0.3.8",
49
49
  "karma-spec-reporter": "^0.0.34",
package/ui/externs/ui.js CHANGED
@@ -21,9 +21,7 @@ shaka.extern = {};
21
21
  * base: string,
22
22
  * buffered: string,
23
23
  * played: string,
24
- * adBreaks: string,
25
- * chapterMarks: string,
26
- * chapterLabels: string
24
+ * adBreaks: string
27
25
  * }}
28
26
  *
29
27
  * @property {string} base
@@ -38,13 +36,6 @@ shaka.extern = {};
38
36
  * @property {string} adBreaks
39
37
  * The CSS background color applied to the portion of the seek bar showing
40
38
  * when the ad breaks are scheduled to occur on the timeline.
41
- * @property {string} chapterMarks
42
- * The CSS border color applied to sections of the seek bar showing
43
- * when the chapters start and end on the timeline.
44
- * Defaults to dark grey rgb(27, 27, 27).
45
- * @property {string} chapterLabels
46
- * The CSS text color applied to the chapter labels that appear above the
47
- * seek bar on hover. Defaults to white rgb(255, 255, 255).
48
39
  * @exportDoc
49
40
  */
50
41
  shaka.extern.UISeekBarColors;
@@ -154,36 +154,3 @@
154
154
  .shaka-ad-markers {
155
155
  .overlay-child();
156
156
  }
157
-
158
- #shaka-player-ui-chapters-container {
159
- width: 100%;
160
- height: 100%;
161
- display: flex;
162
- flex-direction: row;
163
- z-index: 0;
164
- }
165
-
166
- .shaka-chapter {
167
- height: 100%;
168
- position: relative;
169
- }
170
-
171
- .shaka-chapter-label {
172
- position: relative;
173
- top: -2.5em;
174
- width: 100%;
175
- text-align: center;
176
- text-shadow: 1px 1px gray;
177
- line-height: normal;
178
- }
179
-
180
- .shaka-chapter > div:first-child {
181
- width: 100%;
182
- height: 100%;
183
- border-right: 1px solid;
184
- position: absolute;
185
- }
186
-
187
- .shaka-chapter:last-child > div:first-child {
188
- border-right: none;
189
- }
package/ui/seek_bar.js CHANGED
@@ -16,7 +16,6 @@ goog.require('shaka.ui.RangeElement');
16
16
  goog.require('shaka.ui.Utils');
17
17
  goog.require('shaka.util.Dom');
18
18
  goog.require('shaka.util.Error');
19
- goog.require('shaka.util.EventManager');
20
19
  goog.require('shaka.util.Mp4Parser');
21
20
  goog.require('shaka.util.Networking');
22
21
  goog.require('shaka.util.Timer');
@@ -84,18 +83,6 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
84
83
  this.markAdBreaks_();
85
84
  });
86
85
 
87
- /**
88
- * @private {shaka.util.EventManager}
89
- */
90
- this.chaptersEventManager_ = new shaka.util.EventManager();
91
-
92
-
93
- /** @private {!HTMLElement} */
94
- this.chaptersContainer_ = shaka.util.Dom.createHTMLElement('div');
95
- this.chaptersContainer_.id = 'shaka-player-ui-chapters-container';
96
- this.container.appendChild(this.chaptersContainer_);
97
-
98
- this.setupChapters_();
99
86
 
100
87
  /**
101
88
  * When user is scrubbing the seek bar - we should pause the video - see
@@ -238,8 +225,6 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
238
225
  this.adBreaksTimer_ = null;
239
226
  }
240
227
 
241
- this.chaptersEventManager_.release();
242
-
243
228
  super.release();
244
229
  }
245
230
 
@@ -693,203 +678,6 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
693
678
  return minutes + ':' + seconds;
694
679
  }
695
680
  }
696
-
697
- /**
698
- * Sets up the chapter element creator and change handling.
699
- * @private
700
- */
701
- setupChapters_() {
702
- let language = 'und';
703
- /** @type {!Array<shaka.extern.Chapter>} */
704
- let chapters = [];
705
-
706
- /**
707
- * Does a value compare on chapters.
708
- * @param {shaka.extern.Chapter} a
709
- * @param {shaka.extern.Chapter} b
710
- * @return {boolean}
711
- */
712
- const chaptersEqual = (a, b) => {
713
- return (!a && !b) || (a.id === b.id && a.title === b.title &&
714
- a.startTime === b.startTime && a.endTime === b.endTime);
715
- };
716
-
717
- /** @type {function(): void} */
718
- const handleChapterTrackChange = () => {
719
- let nextLanguage = 'und';
720
- /** @type {!Array<shaka.extern.Chapter>} */
721
- let nextChapters = [];
722
-
723
- const currentLocales = this.localization.getCurrentLocales();
724
- for (const locale of Array.from(currentLocales)) {
725
- nextLanguage = locale;
726
- nextChapters = this.player.getChapters(nextLanguage);
727
- if (nextChapters.length) {
728
- break;
729
- }
730
- }
731
- if (!nextChapters.length) {
732
- nextLanguage = 'und';
733
- nextChapters = this.player.getChapters(nextLanguage);
734
- }
735
-
736
- const languageChanged = nextLanguage !== language;
737
- const chaptersChanged = chapters.length !== nextChapters.length ||
738
- !chapters.some((c, idx) => {
739
- const n = nextChapters.at(idx);
740
- return chaptersEqual(c, n) ||
741
- nextChapters.some((n) => chaptersEqual(c, n));
742
- });
743
-
744
- language = nextLanguage;
745
- chapters = nextChapters;
746
- if (!nextChapters.length) {
747
- this.deletePreviousChapters_();
748
- } else if (languageChanged || chaptersChanged) {
749
- this.createChapterElements_(this.container, chapters);
750
- }
751
- };
752
-
753
- handleChapterTrackChange();
754
-
755
- this.eventManager.listen(
756
- this.player, 'unloading', () => {
757
- this.deletePreviousChapters_();
758
- language = 'und';
759
- chapters = [];
760
- });
761
-
762
- this.eventManager.listen(
763
- this.player, 'trackschanged', handleChapterTrackChange);
764
-
765
- this.eventManager.listen(
766
- this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
767
- handleChapterTrackChange();
768
- });
769
-
770
- this.eventManager.listen(
771
- this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
772
- handleChapterTrackChange();
773
- });
774
- }
775
-
776
- /**
777
- * Builds and inserts ChaptersElement into dom container.
778
- * @param {!HTMLElement} container
779
- * @param {!Array<shaka.extern.Chapter>} chapterTracks
780
- * @private
781
- */
782
- createChapterElements_(container, chapterTracks) {
783
- this.deletePreviousChapters_();
784
-
785
- const hiddenClass = 'shaka-hidden';
786
-
787
- /** @type {{start: number, end: number}} */
788
- const seekRange = this.player.seekRange();
789
-
790
- /**
791
- * @type {!Array<{
792
- * start: number,
793
- * end: number,
794
- * size: number,
795
- * title: string,
796
- * id: string
797
- * }>}
798
- * */
799
- const chapters = [];
800
-
801
- for (const c of chapterTracks) {
802
- if (c.startTime >= seekRange.end) {
803
- continue;
804
- }
805
- const start = c.startTime > seekRange.start ?
806
- c.startTime : seekRange.start;
807
- const end = c.endTime < seekRange.end ?
808
- c.endTime : seekRange.end;
809
- const size = (end-start);
810
- chapters.push({start, end, size, title: c.title, id: c.id});
811
- }
812
-
813
- if (chapters.length < 2) {
814
- return;
815
- }
816
-
817
- const totalSize = chapters.reduce((t, c) => {
818
- t += c.size;
819
- return t;
820
- }, 0);
821
-
822
- /**
823
- * @type {!Array<{
824
- * start: number,
825
- * end: number,
826
- * el: HTMLElement
827
- * }>}
828
- * */
829
- const chapterElMap = [];
830
-
831
- for (const c of chapters) {
832
- /** @type {!HTMLElement} */
833
- const chapterEl = shaka.util.Dom.createHTMLElement('div');
834
- chapterEl.classList.add('shaka-chapter');
835
- chapterEl.style.width = `${c.size * 100 / totalSize}%`;
836
-
837
- this.chaptersContainer_.appendChild(chapterEl);
838
-
839
- /** @type {!HTMLElement} */
840
- const chapterMarker = shaka.util.Dom.createHTMLElement('div');
841
- chapterMarker.style.borderColor =
842
- this.config_.seekBarColors.chapterMarks;
843
- chapterEl.appendChild(chapterMarker);
844
-
845
- /** @type {!HTMLElement} */
846
- const chapterLabel = shaka.util.Dom.createHTMLElement('p');
847
- chapterLabel.classList.add('shaka-chapter-label', hiddenClass);
848
- chapterLabel.style.color =
849
- this.config_.seekBarColors.chapterLabels;
850
- chapterLabel.innerText = c.title;
851
- chapterEl.appendChild(chapterLabel);
852
-
853
- chapterElMap.push(
854
- {start: c.start, end: c.end, el: chapterLabel});
855
- }
856
-
857
- // Add chapter event listeners
858
- this.chaptersEventManager_.listen(this.bar, 'pointermove', (e) => {
859
- if (!e.target) {
860
- return;
861
- }
862
- const target = /** @type {HTMLElement} */(e.target);
863
-
864
- const screenXDiff = e.offsetX / target.clientWidth;
865
- const rangeMax = parseInt(target.getAttribute('max'), 10);
866
- const hoverVal = screenXDiff * rangeMax;
867
-
868
- for (const c of chapterElMap) {
869
- const hidden = c.el.classList.contains(hiddenClass);
870
- const inChapter = c.start <= hoverVal && hoverVal < c.end;
871
- if (inChapter === hidden) {
872
- c.el.classList.toggle(hiddenClass);
873
- }
874
- }
875
- }, {passive: true});
876
-
877
- this.chaptersEventManager_.listen(this.bar, 'pointerout', () => {
878
- for (const c of chapterElMap) {
879
- if (!c.el.classList.contains(hiddenClass)) {
880
- c.el.classList.add(hiddenClass);
881
- }
882
- }
883
- }, {passive: true});
884
- }
885
-
886
- /**
887
- * @private
888
- */
889
- deletePreviousChapters_() {
890
- this.chaptersEventManager_.removeAll();
891
- shaka.util.Dom.removeAllChildren(this.chaptersContainer_);
892
- }
893
681
  };
894
682
 
895
683
 
package/ui/ui.js CHANGED
@@ -229,8 +229,6 @@ shaka.ui.Overlay = class {
229
229
  buffered: 'rgba(255, 255, 255, 0.54)',
230
230
  played: 'rgb(255, 255, 255)',
231
231
  adBreaks: 'rgb(255, 204, 0)',
232
- chapterMarks: 'rgb(27, 27, 27)',
233
- chapterLabels: 'rgb(255, 255, 255)',
234
232
  },
235
233
  volumeBarColors: {
236
234
  base: 'rgba(255, 255, 255, 0.54)',