shaka-player 4.7.13 → 4.8.0

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.
Files changed (114) hide show
  1. package/AUTHORS +1 -0
  2. package/CONTRIBUTORS +1 -0
  3. package/LICENSE +54 -0
  4. package/README.md +22 -1
  5. package/dist/controls.css +1 -1
  6. package/dist/controls.css.map +1 -1
  7. package/dist/deps.js +34 -23
  8. package/dist/locales.js +44 -34
  9. package/dist/shaka-player.compiled.d.ts +194 -44
  10. package/dist/shaka-player.compiled.debug.d.ts +194 -44
  11. package/dist/shaka-player.compiled.debug.externs.js +474 -337
  12. package/dist/shaka-player.compiled.debug.js +949 -832
  13. package/dist/shaka-player.compiled.debug.map +4 -4
  14. package/dist/shaka-player.compiled.externs.js +474 -337
  15. package/dist/shaka-player.compiled.js +1237 -1171
  16. package/dist/shaka-player.compiled.map +4 -4
  17. package/dist/shaka-player.ui.d.ts +257 -47
  18. package/dist/shaka-player.ui.debug.d.ts +257 -47
  19. package/dist/shaka-player.ui.debug.externs.js +591 -376
  20. package/dist/shaka-player.ui.debug.js +1165 -965
  21. package/dist/shaka-player.ui.debug.map +4 -4
  22. package/dist/shaka-player.ui.externs.js +591 -376
  23. package/dist/shaka-player.ui.js +1521 -1404
  24. package/dist/shaka-player.ui.map +4 -4
  25. package/externs/device_sensor_event.js +18 -0
  26. package/externs/hisense.js +16 -0
  27. package/externs/playstation.js +31 -0
  28. package/externs/shaka/abr_manager.js +3 -1
  29. package/externs/shaka/ads.js +5 -0
  30. package/externs/shaka/codecs.js +13 -0
  31. package/externs/shaka/manifest.js +58 -6
  32. package/externs/shaka/net.js +13 -1
  33. package/externs/shaka/player.js +184 -13
  34. package/externs/shaka/text.js +19 -0
  35. package/externs/tizen.js +41 -0
  36. package/externs/webos.js +19 -0
  37. package/externs/xbox.js +43 -0
  38. package/lib/abr/simple_abr_manager.js +9 -1
  39. package/lib/ads/ad_manager.js +19 -2
  40. package/lib/ads/client_side_ad_manager.js +5 -3
  41. package/lib/ads/media_tailor_ad_manager.js +9 -0
  42. package/lib/cast/cast_receiver.js +0 -14
  43. package/lib/cast/cast_utils.js +1 -0
  44. package/lib/cea/mp4_cea_parser.js +6 -1
  45. package/lib/dash/content_protection.js +97 -53
  46. package/lib/dash/dash_parser.js +230 -176
  47. package/lib/dash/mpd_utils.js +72 -65
  48. package/lib/dash/segment_base.js +27 -21
  49. package/lib/dash/segment_list.js +18 -16
  50. package/lib/dash/segment_template.js +26 -21
  51. package/lib/hls/hls_parser.js +358 -164
  52. package/lib/media/buffering_observer.js +25 -1
  53. package/lib/media/drm_engine.js +91 -71
  54. package/lib/media/manifest_filterer.js +220 -0
  55. package/lib/media/media_source_engine.js +34 -5
  56. package/lib/media/preload_manager.js +827 -0
  57. package/lib/media/presentation_timeline.js +11 -0
  58. package/lib/media/segment_index.js +40 -30
  59. package/lib/media/segment_prefetch.js +140 -43
  60. package/lib/media/segment_reference.js +31 -8
  61. package/lib/media/segment_utils.js +208 -25
  62. package/lib/media/streaming_engine.js +319 -63
  63. package/lib/mss/content_protection.js +31 -25
  64. package/lib/mss/mss_parser.js +74 -55
  65. package/lib/net/networking_engine.js +49 -4
  66. package/lib/offline/storage.js +3 -3
  67. package/lib/player.js +882 -673
  68. package/lib/polyfill/media_capabilities.js +16 -1
  69. package/lib/text/simple_text_displayer.js +9 -0
  70. package/lib/text/stub_text_displayer.js +7 -0
  71. package/lib/text/text_engine.js +16 -3
  72. package/lib/text/ttml_text_parser.js +116 -114
  73. package/lib/text/ui_text_displayer.js +28 -11
  74. package/lib/text/vtt_text_parser.js +54 -115
  75. package/lib/transmuxer/opus.js +91 -0
  76. package/lib/transmuxer/ts_transmuxer.js +115 -0
  77. package/lib/util/cmcd_manager.js +152 -3
  78. package/lib/util/dom_utils.js +11 -0
  79. package/lib/util/error.js +5 -0
  80. package/lib/util/fake_event.js +2 -0
  81. package/lib/util/manifest_parser_utils.js +97 -3
  82. package/lib/util/mp4_box_parsers.js +346 -17
  83. package/lib/util/mp4_generator.js +23 -0
  84. package/lib/util/periods.js +19 -0
  85. package/lib/util/platform.js +161 -9
  86. package/lib/util/player_configuration.js +61 -3
  87. package/lib/util/stats.js +16 -0
  88. package/lib/util/stream_utils.js +16 -6
  89. package/lib/util/string_utils.js +36 -0
  90. package/lib/util/tXml.js +814 -0
  91. package/lib/util/ts_parser.js +50 -0
  92. package/lib/util/xml_utils.js +10 -338
  93. package/package.json +2 -2
  94. package/shaka-player.uncompiled.js +8 -0
  95. package/ui/controls.js +187 -5
  96. package/ui/enums.js +2 -0
  97. package/ui/externs/ui.js +30 -3
  98. package/ui/gl_matrix/matrix_4x4.js +568 -0
  99. package/ui/gl_matrix/matrix_quaternion.js +45 -0
  100. package/ui/less/containers.less +11 -0
  101. package/ui/locales/en-GB.json +2 -0
  102. package/ui/locales/en.json +2 -0
  103. package/ui/locales/es-419.json +2 -0
  104. package/ui/locales/es.json +2 -0
  105. package/ui/locales/source.json +8 -0
  106. package/ui/recenter_vr.js +126 -0
  107. package/ui/resolution_selection.js +25 -5
  108. package/ui/statistics_button.js +12 -0
  109. package/ui/text_selection.js +1 -1
  110. package/ui/toggle_stereoscopic.js +127 -0
  111. package/ui/ui.js +74 -38
  112. package/ui/vr_manager.js +557 -0
  113. package/ui/vr_utils.js +232 -0
  114. package/ui/vr_webgl.js +697 -0
@@ -198,6 +198,17 @@ shaka.media.PresentationTimeline = class {
198
198
  }
199
199
 
200
200
 
201
+ /**
202
+ * Gets the presentation's segment availability duration.
203
+ *
204
+ * @return {number}
205
+ * @export
206
+ */
207
+ getSegmentAvailabilityDuration() {
208
+ return this.segmentAvailabilityDuration_;
209
+ }
210
+
211
+
201
212
  /**
202
213
  * Sets the presentation delay in seconds.
203
214
  *
@@ -18,6 +18,7 @@ goog.require('shaka.util.Timer');
18
18
  /**
19
19
  * SegmentIndex.
20
20
  *
21
+ * @implements {shaka.extern.SegmentIndex}
21
22
  * @implements {shaka.util.IReleasable}
22
23
  * @implements {Iterable.<!shaka.media.SegmentReference>}
23
24
  * @export
@@ -61,14 +62,21 @@ shaka.media.SegmentIndex = class {
61
62
  }
62
63
 
63
64
  /**
64
- * Get number of references
65
- * @protected
66
- * @return {number}
65
+ * @override
66
+ * @export
67
67
  */
68
68
  getNumReferences() {
69
69
  return this.references.length;
70
70
  }
71
71
 
72
+ /**
73
+ * @override
74
+ * @export
75
+ */
76
+ getNumEvicted() {
77
+ return this.numEvicted_;
78
+ }
79
+
72
80
  /**
73
81
  * @override
74
82
  * @export
@@ -132,14 +140,7 @@ shaka.media.SegmentIndex = class {
132
140
 
133
141
 
134
142
  /**
135
- * Finds the position of the segment for the given time, in seconds, relative
136
- * to the start of the presentation. Returns the position of the segment
137
- * with the largest end time if more than one segment is known for the given
138
- * time.
139
- *
140
- * @param {number} time
141
- * @return {?number} The position of the segment, or null if the position of
142
- * the segment could not be determined.
143
+ * @override
143
144
  * @export
144
145
  */
145
146
  find(time) {
@@ -170,11 +171,7 @@ shaka.media.SegmentIndex = class {
170
171
 
171
172
 
172
173
  /**
173
- * Gets the SegmentReference for the segment at the given position.
174
- *
175
- * @param {number} position The position of the segment as returned by find().
176
- * @return {shaka.media.SegmentReference} The SegmentReference, or null if
177
- * no such SegmentReference exists.
174
+ * @override
178
175
  * @export
179
176
  */
180
177
  get(position) {
@@ -378,7 +375,7 @@ shaka.media.SegmentIndex = class {
378
375
  lastReference.tileDuration,
379
376
  lastReference.syncTime,
380
377
  lastReference.status,
381
- lastReference.aes128Key,
378
+ lastReference.aesKey,
382
379
  );
383
380
  newReference.mimeType = lastReference.mimeType;
384
381
  newReference.codecs = lastReference.codecs;
@@ -438,10 +435,11 @@ shaka.media.SegmentIndex = class {
438
435
  * Playlist will contain at least one independent frame."
439
436
  *
440
437
  * @param {number} time
438
+ * @param {boolean=} allowNonIndepedent
441
439
  * @return {?shaka.media.SegmentIterator}
442
440
  * @export
443
441
  */
444
- getIteratorForTime(time) {
442
+ getIteratorForTime(time, allowNonIndepedent = false) {
445
443
  let index = this.find(time);
446
444
  if (index == null) {
447
445
  return null;
@@ -459,14 +457,16 @@ shaka.media.SegmentIndex = class {
459
457
  let r = ref.partialReferences[i];
460
458
  // Note that a segment ends immediately before the end time.
461
459
  if ((time >= r.startTime) && (time < r.endTime)) {
462
- // Find an independent partial segment by moving backwards.
463
- while (i && !r.isIndependent()) {
464
- i--;
465
- r = ref.partialReferences[i];
466
- }
467
- if (!r.isIndependent()) {
468
- shaka.log.alwaysError('No independent partial segment found!');
469
- return null;
460
+ if (!allowNonIndepedent) {
461
+ // Find an independent partial segment by moving backwards.
462
+ while (i && (!r.isIndependent())) {
463
+ i--;
464
+ r = ref.partialReferences[i];
465
+ }
466
+ if (!r.isIndependent()) {
467
+ shaka.log.alwaysError('No independent partial segment found!');
468
+ return null;
469
+ }
470
470
  }
471
471
  // Call to next() should move the partial segment, not the full
472
472
  // segment.
@@ -664,7 +664,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
664
664
  */
665
665
  appendSegmentIndex(segmentIndex) {
666
666
  goog.asserts.assert(
667
- this.indexes_.length == 0 || segmentIndex.numEvicted_ == 0,
667
+ this.indexes_.length == 0 || segmentIndex.getNumEvicted() == 0,
668
668
  'Should not append a new segment index with already-evicted segments');
669
669
  this.indexes_.push(segmentIndex);
670
670
  }
@@ -694,6 +694,16 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
694
694
  this.indexes_ = [];
695
695
  }
696
696
 
697
+ /**
698
+ * @override
699
+ * @export
700
+ */
701
+ forEachTopLevelReference(fn) {
702
+ for (const index of this.indexes_) {
703
+ index.forEachTopLevelReference(fn);
704
+ }
705
+ }
706
+
697
707
  /**
698
708
  * @override
699
709
  * @export
@@ -708,7 +718,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
708
718
  return position + numPassedInEarlierIndexes;
709
719
  }
710
720
 
711
- numPassedInEarlierIndexes += index.numEvicted_ +
721
+ numPassedInEarlierIndexes += index.getNumEvicted() +
712
722
  index.getNumReferences();
713
723
  }
714
724
 
@@ -725,7 +735,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
725
735
 
726
736
  for (const index of this.indexes_) {
727
737
  goog.asserts.assert(
728
- !sawSegments || index.numEvicted_ == 0,
738
+ !sawSegments || index.getNumEvicted() == 0,
729
739
  'Should not see evicted segments after available segments');
730
740
  const reference = index.get(position - numPassedInEarlierIndexes);
731
741
 
@@ -734,7 +744,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
734
744
  }
735
745
 
736
746
  const num = index.getNumReferences();
737
- numPassedInEarlierIndexes += index.numEvicted_ + num;
747
+ numPassedInEarlierIndexes += index.getNumEvicted() + num;
738
748
  sawSegments = sawSegments || num != 0;
739
749
  }
740
750
 
@@ -41,42 +41,64 @@ shaka.media.SegmentPrefetch = class {
41
41
 
42
42
  /**
43
43
  * @private {!Map.<
44
- * !(shaka.media.SegmentReference|shaka.media.InitSegmentReference),
44
+ * !(shaka.media.SegmentReference),
45
45
  * !shaka.media.SegmentPrefetchOperation>}
46
46
  */
47
47
  this.segmentPrefetchMap_ = new Map();
48
+
49
+ /**
50
+ * @private {!Map.<
51
+ * !(shaka.media.InitSegmentReference),
52
+ * !shaka.media.SegmentPrefetchOperation>}
53
+ */
54
+ this.initSegmentPrefetchMap_ = new Map();
55
+ }
56
+
57
+ /**
58
+ * @param {shaka.media.SegmentPrefetch.FetchDispatcher} fetchDispatcher
59
+ */
60
+ replaceFetchDispatcher(fetchDispatcher) {
61
+ this.fetchDispatcher_ = fetchDispatcher;
62
+ for (const operation of this.segmentPrefetchMap_.values()) {
63
+ operation.replaceFetchDispatcher(fetchDispatcher);
64
+ }
48
65
  }
49
66
 
50
67
  /**
51
- * Fetch next segments ahead of current segment.
68
+ * @return {number}
69
+ */
70
+ getLastKnownPosition() {
71
+ return this.prefetchPosTime_;
72
+ }
73
+
74
+ /**
75
+ * Fetch next segments ahead of current time.
52
76
  *
53
- * @param {(!shaka.media.SegmentReference)} startReference
77
+ * @param {number} currTime
54
78
  * @param {boolean=} skipFirst
55
79
  * @public
56
80
  */
57
- prefetchSegments(startReference, skipFirst = false) {
81
+ prefetchSegmentsByTime(currTime, skipFirst = false) {
58
82
  goog.asserts.assert(this.prefetchLimit_ > 0,
59
83
  'SegmentPrefetch can not be used when prefetchLimit <= 0.');
60
84
 
61
85
  const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
62
86
  if (!this.stream_.segmentIndex) {
63
- shaka.log.info(logPrefix, 'missing segmentIndex');
87
+ shaka.log.debug(logPrefix, 'missing segmentIndex');
64
88
  return;
65
89
  }
66
- const currTime = startReference.startTime;
67
90
  const maxTime = Math.max(currTime, this.prefetchPosTime_);
68
- const iterator = this.stream_.segmentIndex.getIteratorForTime(maxTime);
91
+ const iterator = this.stream_.segmentIndex.getIteratorForTime(
92
+ maxTime, /* allowNonIndepedent= */ true);
69
93
  if (!iterator) {
70
94
  return;
71
95
  }
72
- let reference = startReference;
96
+ let reference = iterator.next().value;
73
97
  if (skipFirst) {
74
98
  reference = iterator.next().value;
75
- if (reference &&
76
- reference.startTime == startReference.startTime &&
77
- reference.endTime == startReference.endTime) {
78
- reference = null;
79
- }
99
+ }
100
+ if (!reference) {
101
+ return;
80
102
  }
81
103
  while (this.segmentPrefetchMap_.size < this.prefetchLimit_ &&
82
104
  reference != null) {
@@ -90,6 +112,9 @@ shaka.media.SegmentPrefetch = class {
90
112
  shaka.media.SegmentReference.Status.MISSING) {
91
113
  prefetchAllowed = false;
92
114
  }
115
+ if (prefetchAllowed && reference.initSegmentReference) {
116
+ this.prefetchInitSegment(reference.initSegmentReference);
117
+ }
93
118
  if (prefetchAllowed && !this.segmentPrefetchMap_.has(reference)) {
94
119
  const segmentPrefetchOperation =
95
120
  new shaka.media.SegmentPrefetchOperation(this.fetchDispatcher_);
@@ -103,13 +128,13 @@ shaka.media.SegmentPrefetch = class {
103
128
  }
104
129
  reference = iterator.next().value;
105
130
  }
131
+ this.clearInitSegments_();
106
132
  }
107
133
 
108
134
  /**
109
135
  * Fetch init segment.
110
136
  *
111
137
  * @param {!shaka.media.InitSegmentReference} initSegmentReference
112
- * @public
113
138
  */
114
139
  prefetchInitSegment(initSegmentReference) {
115
140
  goog.asserts.assert(this.prefetchLimit_ > 0,
@@ -117,19 +142,18 @@ shaka.media.SegmentPrefetch = class {
117
142
 
118
143
  const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
119
144
  if (!this.stream_.segmentIndex) {
120
- shaka.log.info(logPrefix, 'missing segmentIndex');
145
+ shaka.log.debug(logPrefix, 'missing segmentIndex');
121
146
  return;
122
147
  }
123
148
 
124
- if (this.segmentPrefetchMap_.size < this.prefetchLimit_) {
125
- if (!this.segmentPrefetchMap_.has(initSegmentReference)) {
126
- const segmentPrefetchOperation =
127
- new shaka.media.SegmentPrefetchOperation(this.fetchDispatcher_);
128
- segmentPrefetchOperation.dispatchFetch(
129
- initSegmentReference, this.stream_);
130
- this.segmentPrefetchMap_.set(
131
- initSegmentReference, segmentPrefetchOperation);
132
- }
149
+ // init segments are ignored from the prefetch limit
150
+ if (!this.initSegmentPrefetchMap_.has(initSegmentReference)) {
151
+ const segmentPrefetchOperation =
152
+ new shaka.media.SegmentPrefetchOperation(this.fetchDispatcher_);
153
+ segmentPrefetchOperation.dispatchFetch(
154
+ initSegmentReference, this.stream_);
155
+ this.initSegmentPrefetchMap_.set(
156
+ initSegmentReference, segmentPrefetchOperation);
133
157
  }
134
158
  }
135
159
 
@@ -147,22 +171,26 @@ shaka.media.SegmentPrefetch = class {
147
171
 
148
172
  const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
149
173
 
150
- if (this.segmentPrefetchMap_.has(reference)) {
151
- const segmentPrefetchOperation = this.segmentPrefetchMap_.get(reference);
174
+ let prefetchMap = this.segmentPrefetchMap_;
175
+ if (reference instanceof shaka.media.InitSegmentReference) {
176
+ prefetchMap = this.initSegmentPrefetchMap_;
177
+ }
178
+
179
+ if (prefetchMap.has(reference)) {
180
+ const segmentPrefetchOperation = prefetchMap.get(reference);
152
181
  if (streamDataCallback) {
153
182
  segmentPrefetchOperation.setStreamDataCallback(streamDataCallback);
154
183
  }
155
- this.segmentPrefetchMap_.delete(reference);
156
184
  if (reference instanceof shaka.media.SegmentReference) {
157
185
  shaka.log.debug(
158
186
  logPrefix,
159
187
  'reused prefetched segment at time:', reference.startTime,
160
- 'mapSize', this.segmentPrefetchMap_.size);
188
+ 'mapSize', prefetchMap.size);
161
189
  } else {
162
190
  shaka.log.debug(
163
191
  logPrefix,
164
192
  'reused prefetched init segment at time, mapSize',
165
- this.segmentPrefetchMap_.size);
193
+ prefetchMap.size);
166
194
  }
167
195
  return segmentPrefetchOperation.getOperation();
168
196
  } else {
@@ -170,33 +198,75 @@ shaka.media.SegmentPrefetch = class {
170
198
  shaka.log.debug(
171
199
  logPrefix,
172
200
  'missed segment at time:', reference.startTime,
173
- 'mapSize', this.segmentPrefetchMap_.size);
201
+ 'mapSize', prefetchMap.size);
174
202
  } else {
175
203
  shaka.log.debug(
176
204
  logPrefix,
177
205
  'missed init segment at time, mapSize',
178
- this.segmentPrefetchMap_.size);
206
+ prefetchMap.size);
179
207
  }
180
208
  return null;
181
209
  }
182
210
  }
183
211
 
212
+ /**
213
+ * Clear All Helper
214
+ * @private
215
+ */
216
+ clearMap_(map) {
217
+ for (const reference of map.keys()) {
218
+ if (reference) {
219
+ this.abortPrefetchedSegment_(reference);
220
+ }
221
+ }
222
+ }
223
+
184
224
  /**
185
225
  * Clear all segment data.
186
226
  * @public
187
227
  */
188
228
  clearAll() {
189
- if (this.segmentPrefetchMap_.size === 0) {
190
- return;
191
- }
229
+ this.clearMap_(this.segmentPrefetchMap_);
230
+ this.clearMap_(this.initSegmentPrefetchMap_);
192
231
  const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
193
- for (const reference of this.segmentPrefetchMap_.keys()) {
194
- if (reference) {
195
- this.abortPrefetchedSegment_(reference);
232
+ shaka.log.debug(logPrefix, 'cleared all');
233
+ this.prefetchPosTime_ = 0;
234
+ }
235
+
236
+ /**
237
+ * @param {number} time
238
+ * @param {boolean=} clearInitSegments
239
+ */
240
+ evict(time, clearInitSegments = false) {
241
+ for (const ref of this.segmentPrefetchMap_.keys()) {
242
+ if (time > ref.endTime) {
243
+ this.abortPrefetchedSegment_(ref);
244
+ }
245
+ }
246
+ if (clearInitSegments) {
247
+ this.clearInitSegments_();
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Remove all init segments that don't have associated segments in
253
+ * the segment prefetch map.
254
+ * By default, with delete on get, the init segments should get removed as
255
+ * they are used. With deleteOnGet set to false, we need to clear them
256
+ * every so often once the segments that are associated with each init segment
257
+ * is no longer prefetched.
258
+ * @private
259
+ */
260
+ clearInitSegments_() {
261
+ const segmentReferences = Array.from(this.segmentPrefetchMap_.keys());
262
+ for (const initSegmentReference of this.initSegmentPrefetchMap_.keys()) {
263
+ // if no segment references this init segment, we should remove it.
264
+ if (!segmentReferences.some(
265
+ (segmentReference) =>
266
+ segmentReference.initSegmentReference === initSegmentReference)) {
267
+ this.abortPrefetchedSegment_(initSegmentReference);
196
268
  }
197
269
  }
198
- shaka.log.info(logPrefix, 'cleared all');
199
- this.prefetchPosTime_ = 0;
200
270
  }
201
271
 
202
272
  /**
@@ -208,6 +278,9 @@ shaka.media.SegmentPrefetch = class {
208
278
  resetLimit(newPrefetchLimit) {
209
279
  goog.asserts.assert(newPrefetchLimit >= 0,
210
280
  'The new prefetch limit must be >= 0.');
281
+
282
+ const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
283
+ shaka.log.debug(logPrefix, 'resetting prefetch limit to', newPrefetchLimit);
211
284
  this.prefetchLimit_ = newPrefetchLimit;
212
285
  const keyArr = Array.from(this.segmentPrefetchMap_.keys());
213
286
  while (keyArr.length > newPrefetchLimit) {
@@ -216,6 +289,7 @@ shaka.media.SegmentPrefetch = class {
216
289
  this.abortPrefetchedSegment_(reference);
217
290
  }
218
291
  }
292
+ this.clearInitSegments_();
219
293
  }
220
294
 
221
295
  /**
@@ -230,6 +304,15 @@ shaka.media.SegmentPrefetch = class {
230
304
  }
231
305
  }
232
306
 
307
+ /**
308
+ * Get the current stream.
309
+ * @public
310
+ * @return {shaka.extern.Stream}
311
+ */
312
+ getStream() {
313
+ return this.stream_;
314
+ }
315
+
233
316
  /**
234
317
  * Remove a segment from prefetch map and abort it.
235
318
  * @param {!(shaka.media.SegmentReference|shaka.media.InitSegmentReference)}
@@ -238,16 +321,23 @@ shaka.media.SegmentPrefetch = class {
238
321
  */
239
322
  abortPrefetchedSegment_(reference) {
240
323
  const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
241
- const segmentPrefetchOperation = this.segmentPrefetchMap_.get(reference);
242
- this.segmentPrefetchMap_.delete(reference);
324
+
325
+ let prefetchMap = this.segmentPrefetchMap_;
326
+ if (reference instanceof shaka.media.InitSegmentReference) {
327
+ prefetchMap = this.initSegmentPrefetchMap_;
328
+ }
329
+
330
+ const segmentPrefetchOperation = prefetchMap.get(reference);
331
+ prefetchMap.delete(reference);
332
+
243
333
  if (segmentPrefetchOperation) {
244
334
  segmentPrefetchOperation.abort();
245
335
  if (reference instanceof shaka.media.SegmentReference) {
246
- shaka.log.info(
336
+ shaka.log.debug(
247
337
  logPrefix,
248
338
  'pop and abort prefetched segment at time:', reference.startTime);
249
339
  } else {
250
- shaka.log.info(logPrefix, 'pop and abort prefetched init segment');
340
+ shaka.log.debug(logPrefix, 'pop and abort prefetched init segment');
251
341
  }
252
342
  }
253
343
  }
@@ -281,6 +371,13 @@ shaka.media.SegmentPrefetchOperation = class {
281
371
  this.operation_ = null;
282
372
  }
283
373
 
374
+ /**
375
+ * @param {shaka.media.SegmentPrefetch.FetchDispatcher} fetchDispatcher
376
+ */
377
+ replaceFetchDispatcher(fetchDispatcher) {
378
+ this.fetchDispatcher_ = fetchDispatcher;
379
+ }
380
+
284
381
  /**
285
382
  * Fetch a segments
286
383
  *
@@ -32,11 +32,11 @@ shaka.media.InitSegmentReference = class {
32
32
  * the quality of the media associated with this init segment.
33
33
  * @param {(null|number)=} timescale
34
34
  * @param {(null|BufferSource)=} segmentData
35
- * @param {?shaka.extern.aes128Key=} aes128Key
35
+ * @param {?shaka.extern.aesKey=} aesKey
36
36
  * The segment's AES-128-CBC full segment encryption key and iv.
37
37
  */
38
38
  constructor(uris, startByte, endByte, mediaQuality = null, timescale = null,
39
- segmentData = null, aes128Key = null) {
39
+ segmentData = null, aesKey = null) {
40
40
  /** @type {function():!Array.<string>} */
41
41
  this.getUris = uris;
42
42
 
@@ -55,8 +55,8 @@ shaka.media.InitSegmentReference = class {
55
55
  /** @type {BufferSource|null} */
56
56
  this.segmentData = segmentData;
57
57
 
58
- /** @type {?shaka.extern.aes128Key} */
59
- this.aes128Key = aes128Key;
58
+ /** @type {?shaka.extern.aesKey} */
59
+ this.aesKey = aesKey;
60
60
 
61
61
  /** @type {?string} */
62
62
  this.codecs = null;
@@ -206,7 +206,7 @@ shaka.media.SegmentReference = class {
206
206
  * @param {shaka.media.SegmentReference.Status=} status
207
207
  * The segment status is used to indicate that a segment does not exist or is
208
208
  * not available.
209
- * @param {?shaka.extern.aes128Key=} aes128Key
209
+ * @param {?shaka.extern.aesKey=} aesKey
210
210
  * The segment's AES-128-CBC full segment encryption key and iv.
211
211
  * @param {boolean=} allPartialSegments
212
212
  * Indicate if the segment has all partial segments
@@ -216,7 +216,7 @@ shaka.media.SegmentReference = class {
216
216
  timestampOffset, appendWindowStart, appendWindowEnd,
217
217
  partialReferences = [], tilesLayout = '', tileDuration = null,
218
218
  syncTime = null, status = shaka.media.SegmentReference.Status.AVAILABLE,
219
- aes128Key = null, allPartialSegments = false) {
219
+ aesKey = null, allPartialSegments = false) {
220
220
  // A preload hinted Partial Segment has the same startTime and endTime.
221
221
  goog.asserts.assert(startTime <= endTime,
222
222
  'startTime must be less than or equal to endTime');
@@ -288,8 +288,8 @@ shaka.media.SegmentReference = class {
288
288
  /** @type {boolean} */
289
289
  this.byterangeOptimization = false;
290
290
 
291
- /** @type {?shaka.extern.aes128Key} */
292
- this.aes128Key = aes128Key;
291
+ /** @type {?shaka.extern.aesKey} */
292
+ this.aesKey = aesKey;
293
293
 
294
294
  /** @type {?shaka.media.SegmentReference.ThumbnailSprite} */
295
295
  this.thumbnailSprite = null;
@@ -320,6 +320,9 @@ shaka.media.SegmentReference = class {
320
320
 
321
321
  /** @type {?string} */
322
322
  this.mimeType = null;
323
+
324
+ /** @type {BufferSource|null} */
325
+ this.segmentData = null;
323
326
  }
324
327
 
325
328
  /**
@@ -598,6 +601,26 @@ shaka.media.SegmentReference = class {
598
601
  this.offset(offset);
599
602
  }
600
603
  }
604
+
605
+ /**
606
+ * Set the segment data.
607
+ *
608
+ * @param {!BufferSource} segmentData
609
+ * @export
610
+ */
611
+ setSegmentData(segmentData) {
612
+ this.segmentData = segmentData;
613
+ }
614
+
615
+ /**
616
+ * Return the segment data.
617
+ *
618
+ * @return {?BufferSource}
619
+ * @export
620
+ */
621
+ getSegmentData() {
622
+ return this.segmentData;
623
+ }
601
624
  };
602
625
 
603
626