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.
- package/AUTHORS +1 -0
- package/CONTRIBUTORS +1 -0
- package/LICENSE +54 -0
- package/README.md +22 -1
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +34 -23
- package/dist/locales.js +44 -34
- package/dist/shaka-player.compiled.d.ts +194 -44
- package/dist/shaka-player.compiled.debug.d.ts +194 -44
- package/dist/shaka-player.compiled.debug.externs.js +474 -337
- package/dist/shaka-player.compiled.debug.js +949 -832
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +474 -337
- package/dist/shaka-player.compiled.js +1237 -1171
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +257 -47
- package/dist/shaka-player.ui.debug.d.ts +257 -47
- package/dist/shaka-player.ui.debug.externs.js +591 -376
- package/dist/shaka-player.ui.debug.js +1165 -965
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +591 -376
- package/dist/shaka-player.ui.js +1521 -1404
- package/dist/shaka-player.ui.map +4 -4
- package/externs/device_sensor_event.js +18 -0
- package/externs/hisense.js +16 -0
- package/externs/playstation.js +31 -0
- package/externs/shaka/abr_manager.js +3 -1
- package/externs/shaka/ads.js +5 -0
- package/externs/shaka/codecs.js +13 -0
- package/externs/shaka/manifest.js +58 -6
- package/externs/shaka/net.js +13 -1
- package/externs/shaka/player.js +184 -13
- package/externs/shaka/text.js +19 -0
- package/externs/tizen.js +41 -0
- package/externs/webos.js +19 -0
- package/externs/xbox.js +43 -0
- package/lib/abr/simple_abr_manager.js +9 -1
- package/lib/ads/ad_manager.js +19 -2
- package/lib/ads/client_side_ad_manager.js +5 -3
- package/lib/ads/media_tailor_ad_manager.js +9 -0
- package/lib/cast/cast_receiver.js +0 -14
- package/lib/cast/cast_utils.js +1 -0
- package/lib/cea/mp4_cea_parser.js +6 -1
- package/lib/dash/content_protection.js +97 -53
- package/lib/dash/dash_parser.js +230 -176
- package/lib/dash/mpd_utils.js +72 -65
- package/lib/dash/segment_base.js +27 -21
- package/lib/dash/segment_list.js +18 -16
- package/lib/dash/segment_template.js +26 -21
- package/lib/hls/hls_parser.js +358 -164
- package/lib/media/buffering_observer.js +25 -1
- package/lib/media/drm_engine.js +91 -71
- package/lib/media/manifest_filterer.js +220 -0
- package/lib/media/media_source_engine.js +34 -5
- package/lib/media/preload_manager.js +827 -0
- package/lib/media/presentation_timeline.js +11 -0
- package/lib/media/segment_index.js +40 -30
- package/lib/media/segment_prefetch.js +140 -43
- package/lib/media/segment_reference.js +31 -8
- package/lib/media/segment_utils.js +208 -25
- package/lib/media/streaming_engine.js +319 -63
- package/lib/mss/content_protection.js +31 -25
- package/lib/mss/mss_parser.js +74 -55
- package/lib/net/networking_engine.js +49 -4
- package/lib/offline/storage.js +3 -3
- package/lib/player.js +882 -673
- package/lib/polyfill/media_capabilities.js +16 -1
- package/lib/text/simple_text_displayer.js +9 -0
- package/lib/text/stub_text_displayer.js +7 -0
- package/lib/text/text_engine.js +16 -3
- package/lib/text/ttml_text_parser.js +116 -114
- package/lib/text/ui_text_displayer.js +28 -11
- package/lib/text/vtt_text_parser.js +54 -115
- package/lib/transmuxer/opus.js +91 -0
- package/lib/transmuxer/ts_transmuxer.js +115 -0
- package/lib/util/cmcd_manager.js +152 -3
- package/lib/util/dom_utils.js +11 -0
- package/lib/util/error.js +5 -0
- package/lib/util/fake_event.js +2 -0
- package/lib/util/manifest_parser_utils.js +97 -3
- package/lib/util/mp4_box_parsers.js +346 -17
- package/lib/util/mp4_generator.js +23 -0
- package/lib/util/periods.js +19 -0
- package/lib/util/platform.js +161 -9
- package/lib/util/player_configuration.js +61 -3
- package/lib/util/stats.js +16 -0
- package/lib/util/stream_utils.js +16 -6
- package/lib/util/string_utils.js +36 -0
- package/lib/util/tXml.js +814 -0
- package/lib/util/ts_parser.js +50 -0
- package/lib/util/xml_utils.js +10 -338
- package/package.json +2 -2
- package/shaka-player.uncompiled.js +8 -0
- package/ui/controls.js +187 -5
- package/ui/enums.js +2 -0
- package/ui/externs/ui.js +30 -3
- package/ui/gl_matrix/matrix_4x4.js +568 -0
- package/ui/gl_matrix/matrix_quaternion.js +45 -0
- package/ui/less/containers.less +11 -0
- package/ui/locales/en-GB.json +2 -0
- package/ui/locales/en.json +2 -0
- package/ui/locales/es-419.json +2 -0
- package/ui/locales/es.json +2 -0
- package/ui/locales/source.json +8 -0
- package/ui/recenter_vr.js +126 -0
- package/ui/resolution_selection.js +25 -5
- package/ui/statistics_button.js +12 -0
- package/ui/text_selection.js +1 -1
- package/ui/toggle_stereoscopic.js +127 -0
- package/ui/ui.js +74 -38
- package/ui/vr_manager.js +557 -0
- package/ui/vr_utils.js +232 -0
- 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
|
-
*
|
|
65
|
-
* @
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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.
|
|
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
|
-
|
|
463
|
-
|
|
464
|
-
i
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
*
|
|
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 {
|
|
77
|
+
* @param {number} currTime
|
|
54
78
|
* @param {boolean=} skipFirst
|
|
55
79
|
* @public
|
|
56
80
|
*/
|
|
57
|
-
|
|
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.
|
|
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(
|
|
91
|
+
const iterator = this.stream_.segmentIndex.getIteratorForTime(
|
|
92
|
+
maxTime, /* allowNonIndepedent= */ true);
|
|
69
93
|
if (!iterator) {
|
|
70
94
|
return;
|
|
71
95
|
}
|
|
72
|
-
let reference =
|
|
96
|
+
let reference = iterator.next().value;
|
|
73
97
|
if (skipFirst) {
|
|
74
98
|
reference = iterator.next().value;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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.
|
|
145
|
+
shaka.log.debug(logPrefix, 'missing segmentIndex');
|
|
121
146
|
return;
|
|
122
147
|
}
|
|
123
148
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
151
|
-
|
|
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',
|
|
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
|
-
|
|
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',
|
|
201
|
+
'mapSize', prefetchMap.size);
|
|
174
202
|
} else {
|
|
175
203
|
shaka.log.debug(
|
|
176
204
|
logPrefix,
|
|
177
205
|
'missed init segment at time, mapSize',
|
|
178
|
-
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
229
|
+
this.clearMap_(this.segmentPrefetchMap_);
|
|
230
|
+
this.clearMap_(this.initSegmentPrefetchMap_);
|
|
192
231
|
const logPrefix = shaka.media.SegmentPrefetch.logPrefix_(this.stream_);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
-
|
|
242
|
-
this.segmentPrefetchMap_
|
|
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.
|
|
336
|
+
shaka.log.debug(
|
|
247
337
|
logPrefix,
|
|
248
338
|
'pop and abort prefetched segment at time:', reference.startTime);
|
|
249
339
|
} else {
|
|
250
|
-
shaka.log.
|
|
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.
|
|
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,
|
|
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.
|
|
59
|
-
this.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
292
|
-
this.
|
|
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
|
|