shaka-player 4.9.26 → 4.9.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.
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +1 -1
- package/dist/locales.js +54 -54
- package/dist/shaka-player.compiled.d.ts +5 -1
- package/dist/shaka-player.compiled.debug.d.ts +5 -1
- package/dist/shaka-player.compiled.debug.externs.js +6 -0
- package/dist/shaka-player.compiled.debug.js +124 -115
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +6 -0
- package/dist/shaka-player.compiled.js +1113 -1105
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +5 -1
- package/dist/shaka-player.ui.debug.d.ts +5 -1
- package/dist/shaka-player.ui.debug.externs.js +6 -0
- package/dist/shaka-player.ui.debug.js +367 -355
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +6 -0
- package/dist/shaka-player.ui.js +1285 -1276
- package/dist/shaka-player.ui.map +4 -4
- package/externs/ima.js +22 -2
- package/externs/shaka/player.js +13 -2
- package/lib/dash/dash_parser.js +17 -9
- package/lib/dash/mpd_utils.js +0 -3
- package/lib/hls/hls_parser.js +18 -4
- package/lib/media/gap_jumping_controller.js +4 -2
- package/lib/media/segment_index.js +18 -6
- package/lib/media/streaming_engine.js +22 -9
- package/lib/net/networking_utils.js +5 -0
- package/lib/offline/storage.js +12 -10
- package/lib/player.js +13 -4
- package/lib/text/simple_text_displayer.js +1 -1
- package/lib/text/text_utils.js +4 -0
- package/lib/text/ttml_text_parser.js +26 -5
- package/lib/util/periods.js +60 -4
- package/lib/util/player_configuration.js +5 -0
- package/lib/util/tXml.js +17 -9
- package/package.json +1 -1
- package/ui/controls.js +14 -2
- package/ui/less/overflow_menu.less +1 -0
- package/ui/less/tooltip.less +1 -1
- package/ui/locales/README.md +16 -0
- package/ui/locales/ar-XB.json +1 -1
- package/ui/locales/ar.json +1 -1
- package/ui/locales/bg.json +1 -1
- package/ui/locales/ca.json +5 -5
- package/ui/locales/cs.json +1 -1
- package/ui/locales/da.json +1 -1
- package/ui/locales/de.json +1 -1
- package/ui/locales/el.json +1 -1
- package/ui/locales/en-GB.json +1 -1
- package/ui/locales/en-XA.json +1 -1
- package/ui/locales/es-419.json +4 -4
- package/ui/locales/es.json +3 -3
- package/ui/locales/fa.json +1 -1
- package/ui/locales/fi.json +1 -1
- package/ui/locales/fil.json +1 -1
- package/ui/locales/fr.json +6 -6
- package/ui/locales/hi.json +1 -1
- package/ui/locales/hr.json +1 -1
- package/ui/locales/hu.json +1 -1
- package/ui/locales/id.json +1 -1
- package/ui/locales/it.json +1 -1
- package/ui/locales/iw.json +1 -1
- package/ui/locales/ja.json +1 -1
- package/ui/locales/ko.json +1 -1
- package/ui/locales/lt.json +1 -1
- package/ui/locales/lv.json +1 -1
- package/ui/locales/nl.json +1 -1
- package/ui/locales/no.json +1 -1
- package/ui/locales/pl.json +6 -6
- package/ui/locales/pt-BR.json +6 -6
- package/ui/locales/pt-PT.json +7 -7
- package/ui/locales/ro.json +1 -1
- package/ui/locales/ru.json +1 -1
- package/ui/locales/sjn-translations.yaml +50 -4
- package/ui/locales/sjn.json +8 -1
- package/ui/locales/sk.json +1 -1
- package/ui/locales/sl.json +1 -1
- package/ui/locales/sr.json +1 -1
- package/ui/locales/sv.json +1 -1
- package/ui/locales/sync-sjn.py +41 -0
- package/ui/locales/th.json +1 -1
- package/ui/locales/tr.json +1 -1
- package/ui/locales/uk.json +1 -1
- package/ui/locales/vi.json +1 -1
- package/ui/locales/zh-HK.json +1 -1
- package/ui/locales/zh-TW.json +1 -1
- package/ui/locales/zh.json +1 -1
package/externs/ima.js
CHANGED
|
@@ -269,7 +269,6 @@ google.ima.Ad = class {
|
|
|
269
269
|
getMediaUrl() {}
|
|
270
270
|
};
|
|
271
271
|
|
|
272
|
-
|
|
273
272
|
/** @const */
|
|
274
273
|
google.ima.AdPodInfo = class {
|
|
275
274
|
/** @return {number} */
|
|
@@ -366,7 +365,7 @@ google.ima.AdEvent.Type = {
|
|
|
366
365
|
* @description Request for the ad server
|
|
367
366
|
* @property {string|undefined} adTagUrl
|
|
368
367
|
* Specifies the ad tag url that is requested from the ad server.
|
|
369
|
-
* This parameter is optional if
|
|
368
|
+
* This parameter is optional if adsResponse is given.
|
|
370
369
|
* @property {string|undefined} adsResponse
|
|
371
370
|
* Specifies a VAST 2.0 document to be used as the ads response instead of
|
|
372
371
|
* making a request via an ad tag url. This can be useful for debugging
|
|
@@ -518,6 +517,9 @@ google.ima.dai.api.Ad = class {
|
|
|
518
517
|
|
|
519
518
|
/** @return {string} */
|
|
520
519
|
getCreativeAdId() {}
|
|
520
|
+
|
|
521
|
+
/** @return {!Array.<!google.ima.dai.api.CompanionAd>} */
|
|
522
|
+
getCompanionAds() {}
|
|
521
523
|
};
|
|
522
524
|
|
|
523
525
|
|
|
@@ -536,6 +538,24 @@ google.ima.dai.api.AdPodInfo = class {
|
|
|
536
538
|
getPodIndex() {}
|
|
537
539
|
};
|
|
538
540
|
|
|
541
|
+
/** @const */
|
|
542
|
+
google.ima.dai.api.CompanionAd = class {
|
|
543
|
+
/** @return {?string} */
|
|
544
|
+
getAdSlotId() {}
|
|
545
|
+
|
|
546
|
+
/** @return {string} */
|
|
547
|
+
getContent() {}
|
|
548
|
+
|
|
549
|
+
/** @return {?string} */
|
|
550
|
+
getContentType() {}
|
|
551
|
+
|
|
552
|
+
/** @return {number} */
|
|
553
|
+
getHeight() {}
|
|
554
|
+
|
|
555
|
+
/** @return {?number} */
|
|
556
|
+
getWidth() {}
|
|
557
|
+
};
|
|
558
|
+
|
|
539
559
|
|
|
540
560
|
/** @const */
|
|
541
561
|
google.ima.dai.api.CuePoint = class {};
|
package/externs/shaka/player.js
CHANGED
|
@@ -1239,6 +1239,7 @@ shaka.extern.ManifestConfiguration;
|
|
|
1239
1239
|
* alwaysStreamText: boolean,
|
|
1240
1240
|
* startAtSegmentBoundary: boolean,
|
|
1241
1241
|
* gapDetectionThreshold: number,
|
|
1242
|
+
* gapPadding: number,
|
|
1242
1243
|
* gapJumpTimerTime: number,
|
|
1243
1244
|
* durationBackoff: number,
|
|
1244
1245
|
* safeSeekOffset: number,
|
|
@@ -1323,7 +1324,16 @@ shaka.extern.ManifestConfiguration;
|
|
|
1323
1324
|
* to <code>false</code>.
|
|
1324
1325
|
* @property {number} gapDetectionThreshold
|
|
1325
1326
|
* The maximum distance (in seconds) before a gap when we'll automatically
|
|
1326
|
-
* jump.
|
|
1327
|
+
* jump.
|
|
1328
|
+
* <br>
|
|
1329
|
+
* Defaults to <code>0.5</code>.
|
|
1330
|
+
* @property {number} gapPadding
|
|
1331
|
+
* Padding added only for Xbox, Legacy Edge and Tizen.
|
|
1332
|
+
* Based on our research (specific to Tizen), the gapPadding value must be
|
|
1333
|
+
* greater than your GOP length.
|
|
1334
|
+
* It’s crucial to verify this value according to your actual stream.
|
|
1335
|
+
* <br>
|
|
1336
|
+
* Defaults to <code>0.01</code> for Xbox and Legacy Edge, Tizen at 2.
|
|
1327
1337
|
* @property {number} gapJumpTimerTime
|
|
1328
1338
|
* The polling time in seconds to check for gaps in the media. This value
|
|
1329
1339
|
* defaults to <code>0.25</code>.
|
|
@@ -1837,7 +1847,8 @@ shaka.extern.LcevcConfiguration;
|
|
|
1837
1847
|
* view.
|
|
1838
1848
|
* Defaults to <code>true</code>.
|
|
1839
1849
|
* @property {number} numberOfParallelDownloads
|
|
1840
|
-
* Number of parallel downloads.
|
|
1850
|
+
* Number of parallel downloads. If the value is 0, downloads will be
|
|
1851
|
+
* sequential for each stream.
|
|
1841
1852
|
* Note: normally browsers limit to 5 request in parallel, so putting a
|
|
1842
1853
|
* number higher than this will not help it download faster.
|
|
1843
1854
|
* Defaults to <code>5</code>.
|
package/lib/dash/dash_parser.js
CHANGED
|
@@ -163,6 +163,9 @@ shaka.dash.DashParser = class {
|
|
|
163
163
|
|
|
164
164
|
/** @private {boolean} */
|
|
165
165
|
this.isTransitionFromDynamicToStatic_ = false;
|
|
166
|
+
|
|
167
|
+
/** @private {?Array.<string>} */
|
|
168
|
+
this.lastCalculatedBaseUris_ = [];
|
|
166
169
|
}
|
|
167
170
|
|
|
168
171
|
/**
|
|
@@ -551,7 +554,6 @@ shaka.dash.DashParser = class {
|
|
|
551
554
|
}
|
|
552
555
|
|
|
553
556
|
const uriObjs = TXml.findChildren(mpd, 'BaseURL');
|
|
554
|
-
let calculatedBaseUris;
|
|
555
557
|
let someLocationValid = false;
|
|
556
558
|
if (this.contentSteeringManager_) {
|
|
557
559
|
for (const uriObj of uriObjs) {
|
|
@@ -564,9 +566,10 @@ shaka.dash.DashParser = class {
|
|
|
564
566
|
}
|
|
565
567
|
}
|
|
566
568
|
}
|
|
569
|
+
this.lastCalculatedBaseUris_ = null;
|
|
567
570
|
if (!someLocationValid || !this.contentSteeringManager_) {
|
|
568
571
|
const uris = uriObjs.map(TXml.getContents);
|
|
569
|
-
|
|
572
|
+
this.lastCalculatedBaseUris_ = shaka.util.ManifestParserUtils.resolveUris(
|
|
570
573
|
manifestBaseUris, uris);
|
|
571
574
|
}
|
|
572
575
|
|
|
@@ -574,8 +577,8 @@ shaka.dash.DashParser = class {
|
|
|
574
577
|
if (this.contentSteeringManager_ && someLocationValid) {
|
|
575
578
|
return this.contentSteeringManager_.getLocations('BaseURL');
|
|
576
579
|
}
|
|
577
|
-
if (
|
|
578
|
-
return
|
|
580
|
+
if (this.lastCalculatedBaseUris_) {
|
|
581
|
+
return this.lastCalculatedBaseUris_;
|
|
579
582
|
}
|
|
580
583
|
return [];
|
|
581
584
|
};
|
|
@@ -1430,14 +1433,14 @@ shaka.dash.DashParser = class {
|
|
|
1430
1433
|
*/
|
|
1431
1434
|
cleanStreamMap_() {
|
|
1432
1435
|
const oldPeriodIds = Object.keys(this.indexStreamMap_);
|
|
1433
|
-
if (oldPeriodIds.length === this.lastManifestUpdatePeriodIds_.length) {
|
|
1434
|
-
return;
|
|
1435
|
-
}
|
|
1436
1436
|
const diffPeriodsIDs = oldPeriodIds.filter((pId) => {
|
|
1437
1437
|
return !this.lastManifestUpdatePeriodIds_.includes(pId);
|
|
1438
1438
|
});
|
|
1439
1439
|
for (const pId of diffPeriodsIDs) {
|
|
1440
1440
|
for (const contextId of this.indexStreamMap_[pId]) {
|
|
1441
|
+
if (this.periodCombiner_) {
|
|
1442
|
+
this.periodCombiner_.deleteStream(this.streamMap_[contextId], pId);
|
|
1443
|
+
}
|
|
1441
1444
|
delete this.streamMap_[contextId];
|
|
1442
1445
|
}
|
|
1443
1446
|
delete this.indexStreamMap_[pId];
|
|
@@ -2804,6 +2807,8 @@ shaka.dash.DashParser = class {
|
|
|
2804
2807
|
const schemeIdUri = elem.attributes['schemeIdUri'] || '';
|
|
2805
2808
|
const value = elem.attributes['value'] || '';
|
|
2806
2809
|
const timescale = TXml.parseAttr(elem, 'timescale', parseNumber) || 1;
|
|
2810
|
+
const presentationTimeOffset =
|
|
2811
|
+
TXml.parseAttr(elem, 'presentationTimeOffset', parseNumber) || 0;
|
|
2807
2812
|
|
|
2808
2813
|
for (const eventNode of TXml.findChildren(elem, 'Event')) {
|
|
2809
2814
|
const presentationTime =
|
|
@@ -2811,7 +2816,10 @@ shaka.dash.DashParser = class {
|
|
|
2811
2816
|
const duration =
|
|
2812
2817
|
TXml.parseAttr(eventNode, 'duration', parseNumber) || 0;
|
|
2813
2818
|
|
|
2814
|
-
|
|
2819
|
+
// Ensure start time won't be lower than period start.
|
|
2820
|
+
let startTime = Math.max(
|
|
2821
|
+
(presentationTime - presentationTimeOffset) / timescale + periodStart,
|
|
2822
|
+
periodStart);
|
|
2815
2823
|
let endTime = startTime + (duration / timescale);
|
|
2816
2824
|
if (periodDuration != null) {
|
|
2817
2825
|
// An event should not go past the Period, even if the manifest says so.
|
|
@@ -2833,7 +2841,7 @@ shaka.dash.DashParser = class {
|
|
|
2833
2841
|
endTime: endTime,
|
|
2834
2842
|
id: eventNode.attributes['id'] || '',
|
|
2835
2843
|
eventElement: TXml.txmlNodeToDomElement(eventNode),
|
|
2836
|
-
eventNode: eventNode,
|
|
2844
|
+
eventNode: TXml.cloneNode(eventNode),
|
|
2837
2845
|
};
|
|
2838
2846
|
|
|
2839
2847
|
this.playerInterface_.onTimelineRegionAdded(region);
|
package/lib/dash/mpd_utils.js
CHANGED
|
@@ -481,9 +481,6 @@ shaka.dash.MpdUtils = class {
|
|
|
481
481
|
// Move the children of the loaded xml into the current element.
|
|
482
482
|
while (rootElem.children.length) {
|
|
483
483
|
const child = rootElem.children.shift();
|
|
484
|
-
if (TXml.isNode(child)) {
|
|
485
|
-
child.parent = element;
|
|
486
|
-
}
|
|
487
484
|
element.children.push(child);
|
|
488
485
|
}
|
|
489
486
|
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -147,6 +147,14 @@ shaka.hls.HlsParser = class {
|
|
|
147
147
|
*/
|
|
148
148
|
this.lowestSyncTime_ = Infinity;
|
|
149
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Flag to indicate if any of the media playlists use
|
|
152
|
+
* EXT-X-PROGRAM-DATE-TIME.
|
|
153
|
+
*
|
|
154
|
+
* @private {boolean}
|
|
155
|
+
*/
|
|
156
|
+
this.usesProgramDateTime_ = false;
|
|
157
|
+
|
|
150
158
|
/**
|
|
151
159
|
* Whether the streams have previously been "finalized"; that is to say,
|
|
152
160
|
* whether we have loaded enough streams to know information about the asset
|
|
@@ -545,9 +553,10 @@ shaka.hls.HlsParser = class {
|
|
|
545
553
|
* Align the streams by sequence number by dropping early segments. Then
|
|
546
554
|
* offset the streams to begin at presentation time 0.
|
|
547
555
|
* @param {!Array.<!shaka.hls.HlsParser.StreamInfo>} streamInfos
|
|
556
|
+
* @param {boolean=} force
|
|
548
557
|
* @private
|
|
549
558
|
*/
|
|
550
|
-
syncStreamsWithSequenceNumber_(streamInfos) {
|
|
559
|
+
syncStreamsWithSequenceNumber_(streamInfos, force = false) {
|
|
551
560
|
// We assume that, when this is first called, we have enough info to
|
|
552
561
|
// determine how to use the program date times (e.g. we have both a video
|
|
553
562
|
// and an audio, and all other videos and audios match those).
|
|
@@ -602,7 +611,7 @@ shaka.hls.HlsParser = class {
|
|
|
602
611
|
this.minSequenceNumber_);
|
|
603
612
|
|
|
604
613
|
for (const streamInfo of streamInfos) {
|
|
605
|
-
if (!this.ignoreManifestProgramDateTimeFor_(streamInfo.type)) {
|
|
614
|
+
if (!this.ignoreManifestProgramDateTimeFor_(streamInfo.type) && !force) {
|
|
606
615
|
continue;
|
|
607
616
|
}
|
|
608
617
|
const segmentIndex = streamInfo.stream.segmentIndex;
|
|
@@ -2573,8 +2582,12 @@ shaka.hls.HlsParser = class {
|
|
|
2573
2582
|
}
|
|
2574
2583
|
}
|
|
2575
2584
|
this.notifySegmentsForStreams_(streamInfos.map((s) => s.stream));
|
|
2576
|
-
|
|
2577
|
-
|
|
2585
|
+
const liveWithNoProgramaDateTime =
|
|
2586
|
+
this.isLive_() && !this.usesProgramDateTime_;
|
|
2587
|
+
if (this.config_.hls.ignoreManifestProgramDateTime ||
|
|
2588
|
+
liveWithNoProgramaDateTime) {
|
|
2589
|
+
this.syncStreamsWithSequenceNumber_(
|
|
2590
|
+
streamInfos, liveWithNoProgramaDateTime);
|
|
2578
2591
|
} else {
|
|
2579
2592
|
this.syncStreamsWithProgramDateTime_(streamInfos);
|
|
2580
2593
|
if (this.config_.hls.ignoreManifestProgramDateTimeForTypes.length > 0) {
|
|
@@ -3367,6 +3380,7 @@ shaka.hls.HlsParser = class {
|
|
|
3367
3380
|
syncTime = shaka.util.TXml.parseDate(dateTimeTag.value);
|
|
3368
3381
|
goog.asserts.assert(syncTime != null,
|
|
3369
3382
|
'EXT-X-PROGRAM-DATE-TIME format not valid');
|
|
3383
|
+
this.usesProgramDateTime_ = true;
|
|
3370
3384
|
}
|
|
3371
3385
|
}
|
|
3372
3386
|
|
|
@@ -223,8 +223,10 @@ shaka.media.GapJumpingController = class {
|
|
|
223
223
|
// often rounds value we want to set as currentTime and we are not able
|
|
224
224
|
// to jump over the gap.
|
|
225
225
|
if (shaka.util.Platform.isLegacyEdge() ||
|
|
226
|
-
shaka.util.Platform.isXboxOne()
|
|
227
|
-
|
|
226
|
+
shaka.util.Platform.isXboxOne() ||
|
|
227
|
+
shaka.util.Platform.isTizen()) {
|
|
228
|
+
const gapPadding = this.config_.gapPadding;
|
|
229
|
+
jumpTo = Math.ceil((jumpTo + gapPadding) * 100) / 100;
|
|
228
230
|
}
|
|
229
231
|
const seekEnd = this.timeline_.getSeekRangeEnd();
|
|
230
232
|
if (jumpTo >= seekEnd) {
|
|
@@ -700,6 +700,17 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
700
700
|
this.indexes_ = [];
|
|
701
701
|
}
|
|
702
702
|
|
|
703
|
+
/** Evicts all old SegmentIndexes in this MetaSegmentIndex that are empty. */
|
|
704
|
+
evictEmpty() {
|
|
705
|
+
while (this.indexes_.length > 1 && this.indexes_[0].isEmpty()) {
|
|
706
|
+
const index = this.indexes_.shift();
|
|
707
|
+
// In the case of this class, this.numEvicted_ represents the evicted
|
|
708
|
+
// segments that were in indexes that were entirely evicted.
|
|
709
|
+
this.numEvicted_ += index.getNumEvicted();
|
|
710
|
+
index.release();
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
703
714
|
/**
|
|
704
715
|
* Append a SegmentIndex to this MetaSegmentIndex. This effectively stitches
|
|
705
716
|
* the underlying Stream onto the end of the multi-Period Stream represented
|
|
@@ -724,6 +735,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
724
735
|
// Be careful to clone the Array. We don't want to share the reference with
|
|
725
736
|
// our clone and affect each other accidentally.
|
|
726
737
|
clone.indexes_ = this.indexes_.slice();
|
|
738
|
+
clone.numEvicted_ = this.numEvicted_;
|
|
727
739
|
return clone;
|
|
728
740
|
}
|
|
729
741
|
|
|
@@ -754,7 +766,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
754
766
|
* @export
|
|
755
767
|
*/
|
|
756
768
|
find(time) {
|
|
757
|
-
let numPassedInEarlierIndexes =
|
|
769
|
+
let numPassedInEarlierIndexes = this.numEvicted_;
|
|
758
770
|
|
|
759
771
|
for (const index of this.indexes_) {
|
|
760
772
|
const position = index.find(time);
|
|
@@ -775,7 +787,7 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
775
787
|
* @export
|
|
776
788
|
*/
|
|
777
789
|
get(position) {
|
|
778
|
-
let numPassedInEarlierIndexes =
|
|
790
|
+
let numPassedInEarlierIndexes = this.numEvicted_;
|
|
779
791
|
let sawSegments = false;
|
|
780
792
|
|
|
781
793
|
for (const index of this.indexes_) {
|
|
@@ -822,10 +834,10 @@ shaka.media.MetaSegmentIndex = class extends shaka.media.SegmentIndex {
|
|
|
822
834
|
* @export
|
|
823
835
|
*/
|
|
824
836
|
evict(time) {
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
837
|
+
for (const index of this.indexes_) {
|
|
838
|
+
index.evict(time);
|
|
839
|
+
}
|
|
840
|
+
this.evictEmpty();
|
|
829
841
|
}
|
|
830
842
|
|
|
831
843
|
/**
|
|
@@ -15,6 +15,7 @@ goog.require('shaka.log');
|
|
|
15
15
|
goog.require('shaka.media.InitSegmentReference');
|
|
16
16
|
goog.require('shaka.media.ManifestParser');
|
|
17
17
|
goog.require('shaka.media.MediaSourceEngine');
|
|
18
|
+
goog.require('shaka.media.MetaSegmentIndex');
|
|
18
19
|
goog.require('shaka.media.SegmentIterator');
|
|
19
20
|
goog.require('shaka.media.SegmentReference');
|
|
20
21
|
goog.require('shaka.media.SegmentPrefetch');
|
|
@@ -1513,9 +1514,11 @@ shaka.media.StreamingEngine = class {
|
|
|
1513
1514
|
logPrefix, 'looking up segment from new stream endTime:', time);
|
|
1514
1515
|
|
|
1515
1516
|
const reverse = this.playerInterface_.getPlaybackRate() < 0;
|
|
1516
|
-
mediaState.
|
|
1517
|
-
|
|
1518
|
-
|
|
1517
|
+
if (mediaState.stream.segmentIndex) {
|
|
1518
|
+
mediaState.segmentIterator =
|
|
1519
|
+
mediaState.stream.segmentIndex.getIteratorForTime(
|
|
1520
|
+
time, /* allowNonIndepedent= */ false, reverse);
|
|
1521
|
+
}
|
|
1519
1522
|
const ref = mediaState.segmentIterator &&
|
|
1520
1523
|
mediaState.segmentIterator.next().value;
|
|
1521
1524
|
if (ref == null) {
|
|
@@ -1539,18 +1542,22 @@ shaka.media.StreamingEngine = class {
|
|
|
1539
1542
|
const reverse = this.playerInterface_.getPlaybackRate() < 0;
|
|
1540
1543
|
let ref = null;
|
|
1541
1544
|
if (inaccurateTolerance) {
|
|
1542
|
-
mediaState.
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
+
if (mediaState.stream.segmentIndex) {
|
|
1546
|
+
mediaState.segmentIterator =
|
|
1547
|
+
mediaState.stream.segmentIndex.getIteratorForTime(
|
|
1548
|
+
lookupTime, /* allowNonIndepedent= */ false, reverse);
|
|
1549
|
+
}
|
|
1545
1550
|
ref = mediaState.segmentIterator &&
|
|
1546
1551
|
mediaState.segmentIterator.next().value;
|
|
1547
1552
|
}
|
|
1548
1553
|
if (!ref) {
|
|
1549
1554
|
// If we can't find a valid segment with the drifted time, look for a
|
|
1550
1555
|
// segment with the presentation time.
|
|
1551
|
-
mediaState.
|
|
1552
|
-
|
|
1553
|
-
|
|
1556
|
+
if (mediaState.stream.segmentIndex) {
|
|
1557
|
+
mediaState.segmentIterator =
|
|
1558
|
+
mediaState.stream.segmentIndex.getIteratorForTime(
|
|
1559
|
+
presentationTime, /* allowNonIndepedent= */ false, reverse);
|
|
1560
|
+
}
|
|
1554
1561
|
ref = mediaState.segmentIterator &&
|
|
1555
1562
|
mediaState.segmentIterator.next().value;
|
|
1556
1563
|
}
|
|
@@ -2465,6 +2472,12 @@ shaka.media.StreamingEngine = class {
|
|
|
2465
2472
|
* @private
|
|
2466
2473
|
*/
|
|
2467
2474
|
async evict_(mediaState, presentationTime) {
|
|
2475
|
+
const segmentIndex = mediaState.stream.segmentIndex;
|
|
2476
|
+
if (segmentIndex instanceof shaka.media.MetaSegmentIndex) {
|
|
2477
|
+
segmentIndex.evict(
|
|
2478
|
+
this.manifest_.presentationTimeline.getSeekRangeStart());
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2468
2481
|
const logPrefix = shaka.media.StreamingEngine.logPrefix_(mediaState);
|
|
2469
2482
|
shaka.log.v2(logPrefix, 'checking buffer length');
|
|
2470
2483
|
|
|
@@ -103,4 +103,9 @@ shaka.net.NetworkingUtils.EXTENSIONS_TO_MIME_TYPES_ = {
|
|
|
103
103
|
'lrc': 'application/x-subtitle-lrc',
|
|
104
104
|
'ssa': 'text/x-ssa',
|
|
105
105
|
'ass': 'text/x-ssa',
|
|
106
|
+
'jpg': 'image/jpeg',
|
|
107
|
+
'png': 'image/png',
|
|
108
|
+
'svg': 'image/svg+xml',
|
|
109
|
+
'webp': 'image/webp',
|
|
110
|
+
'avif': 'image/avif',
|
|
106
111
|
};
|
package/lib/offline/storage.js
CHANGED
|
@@ -1343,7 +1343,7 @@ shaka.offline.Storage = class {
|
|
|
1343
1343
|
manifest.presentationTimeline.getSegmentAvailabilityStart();
|
|
1344
1344
|
|
|
1345
1345
|
const numberOfParallelDownloads = config.offline.numberOfParallelDownloads;
|
|
1346
|
-
let groupId = 0;
|
|
1346
|
+
let groupId = numberOfParallelDownloads === 0 ? stream.id : 0;
|
|
1347
1347
|
|
|
1348
1348
|
shaka.offline.Storage.forEachSegment_(stream, startTime, (segment) => {
|
|
1349
1349
|
const pendingSegmentRefId =
|
|
@@ -1395,7 +1395,9 @@ shaka.offline.Storage = class {
|
|
|
1395
1395
|
codecs: segment.codecs,
|
|
1396
1396
|
};
|
|
1397
1397
|
streamDb.segments.push(segmentDB);
|
|
1398
|
-
|
|
1398
|
+
if (numberOfParallelDownloads !== 0) {
|
|
1399
|
+
groupId = (groupId + 1) % numberOfParallelDownloads;
|
|
1400
|
+
}
|
|
1399
1401
|
});
|
|
1400
1402
|
|
|
1401
1403
|
return streamDb;
|
|
@@ -1590,14 +1592,6 @@ shaka.offline.Storage = class {
|
|
|
1590
1592
|
/** @type {!Set.<shaka.extern.Stream>} */
|
|
1591
1593
|
const set = new Set();
|
|
1592
1594
|
|
|
1593
|
-
for (const text of manifest.textStreams) {
|
|
1594
|
-
set.add(text);
|
|
1595
|
-
}
|
|
1596
|
-
|
|
1597
|
-
for (const image of manifest.imageStreams) {
|
|
1598
|
-
set.add(image);
|
|
1599
|
-
}
|
|
1600
|
-
|
|
1601
1595
|
for (const variant of manifest.variants) {
|
|
1602
1596
|
if (variant.audio) {
|
|
1603
1597
|
set.add(variant.audio);
|
|
@@ -1607,6 +1601,14 @@ shaka.offline.Storage = class {
|
|
|
1607
1601
|
}
|
|
1608
1602
|
}
|
|
1609
1603
|
|
|
1604
|
+
for (const text of manifest.textStreams) {
|
|
1605
|
+
set.add(text);
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
for (const image of manifest.imageStreams) {
|
|
1609
|
+
set.add(image);
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1610
1612
|
return set;
|
|
1611
1613
|
}
|
|
1612
1614
|
|
package/lib/player.js
CHANGED
|
@@ -5566,6 +5566,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5566
5566
|
references.push(reference);
|
|
5567
5567
|
}
|
|
5568
5568
|
|
|
5569
|
+
let segmentMimeType = mimeType;
|
|
5570
|
+
if (references.length) {
|
|
5571
|
+
segmentMimeType = await shaka.net.NetworkingUtils.getMimeType(
|
|
5572
|
+
references[0].getUris()[0],
|
|
5573
|
+
this.networkingEngine_, this.config_.manifest.retryParameters);
|
|
5574
|
+
}
|
|
5575
|
+
|
|
5569
5576
|
/** @type {shaka.extern.Stream} */
|
|
5570
5577
|
const stream = {
|
|
5571
5578
|
id: this.nextExternalStreamId_++,
|
|
@@ -5573,7 +5580,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5573
5580
|
groupId: null,
|
|
5574
5581
|
createSegmentIndex: () => Promise.resolve(),
|
|
5575
5582
|
segmentIndex: new shaka.media.SegmentIndex(references),
|
|
5576
|
-
mimeType:
|
|
5583
|
+
mimeType: segmentMimeType || '',
|
|
5577
5584
|
codecs: '',
|
|
5578
5585
|
kind: '',
|
|
5579
5586
|
encrypted: false,
|
|
@@ -5597,7 +5604,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5597
5604
|
external: true,
|
|
5598
5605
|
fastSwitching: false,
|
|
5599
5606
|
fullMimeTypes: new Set([shaka.util.MimeUtils.getFullType(
|
|
5600
|
-
|
|
5607
|
+
segmentMimeType || '', '')]),
|
|
5601
5608
|
};
|
|
5602
5609
|
|
|
5603
5610
|
if (this.loadMode_ == shaka.Player.LoadMode.SRC_EQUALS) {
|
|
@@ -6740,11 +6747,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6740
6747
|
this.playhead_.notifyOfBufferingChange();
|
|
6741
6748
|
// Skip the initial buffer gap
|
|
6742
6749
|
const startTime = this.mediaSourceEngine_.bufferStart(contentType);
|
|
6750
|
+
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
6743
6751
|
if (
|
|
6744
6752
|
!this.isLive() &&
|
|
6745
6753
|
// If not paused then GapJumpingController will handle this gap.
|
|
6746
6754
|
this.video_.paused &&
|
|
6747
6755
|
startTime != null &&
|
|
6756
|
+
contentType != ContentType.TEXT &&
|
|
6748
6757
|
startTime > 0 &&
|
|
6749
6758
|
this.playhead_.getTime() < startTime
|
|
6750
6759
|
) {
|
|
@@ -7517,8 +7526,8 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
7517
7526
|
* @define {string} A version number taken from git at compile time.
|
|
7518
7527
|
* @export
|
|
7519
7528
|
*/
|
|
7520
|
-
// eslint-disable-next-line no-useless-concat
|
|
7521
|
-
shaka.Player.version = 'v4.9.
|
|
7529
|
+
// eslint-disable-next-line no-useless-concat, max-len
|
|
7530
|
+
shaka.Player.version = 'v4.9.28' + '-uncompiled'; // x-release-please-version
|
|
7522
7531
|
|
|
7523
7532
|
// Initialize the deprecation system using the version string we just set
|
|
7524
7533
|
// on the player.
|
package/lib/text/text_utils.js
CHANGED
|
@@ -65,7 +65,7 @@ shaka.text.TtmlTextParser = class {
|
|
|
65
65
|
return cues;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
const tt = TXml.parseXmlString(str, 'tt');
|
|
68
|
+
const tt = TXml.parseXmlString(str, 'tt', /* includeParent= */ true);
|
|
69
69
|
if (!tt) {
|
|
70
70
|
throw new shaka.util.Error(
|
|
71
71
|
shaka.util.Error.Severity.CRITICAL,
|
|
@@ -108,7 +108,8 @@ shaka.text.TtmlTextParser = class {
|
|
|
108
108
|
TtmlTextParser.getCellResolution_(cellResolution);
|
|
109
109
|
|
|
110
110
|
const metadata = TXml.getElementsByTagName(tt, 'metadata')[0];
|
|
111
|
-
const metadataElements =
|
|
111
|
+
const metadataElements =
|
|
112
|
+
(metadata ? metadata.children : []).filter((c) => c != '\n');
|
|
112
113
|
const styles = TXml.getElementsByTagName(tt, 'style');
|
|
113
114
|
const regionElements = TXml.getElementsByTagName(tt, 'region');
|
|
114
115
|
|
|
@@ -508,6 +509,24 @@ shaka.text.TtmlTextParser = class {
|
|
|
508
509
|
return region;
|
|
509
510
|
}
|
|
510
511
|
|
|
512
|
+
/**
|
|
513
|
+
* Ensures any TTML RGBA's alpha range of 0-255 is converted to 0-1.
|
|
514
|
+
* @param {string} color
|
|
515
|
+
* @return {string}
|
|
516
|
+
* @private
|
|
517
|
+
*/
|
|
518
|
+
static convertTTMLrgbaToHTMLrgba_(color) {
|
|
519
|
+
const rgba = color.match(/rgba\(([^)]+)\)/);
|
|
520
|
+
if (rgba) {
|
|
521
|
+
const values = rgba[1].split(',');
|
|
522
|
+
if (values.length == 4) {
|
|
523
|
+
values[3] = String(Number(values[3]) / 255);
|
|
524
|
+
return 'rgba(' + values.join(',') + ')';
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
return color;
|
|
528
|
+
}
|
|
529
|
+
|
|
511
530
|
/**
|
|
512
531
|
* Adds applicable style properties to a cue.
|
|
513
532
|
*
|
|
@@ -586,7 +605,7 @@ shaka.text.TtmlTextParser = class {
|
|
|
586
605
|
const color = TtmlTextParser.getStyleAttribute_(
|
|
587
606
|
cueElement, region, styles, 'color', shouldInheritRegionStyles);
|
|
588
607
|
if (color) {
|
|
589
|
-
cue.color = color;
|
|
608
|
+
cue.color = TtmlTextParser.convertTTMLrgbaToHTMLrgba_(color);
|
|
590
609
|
}
|
|
591
610
|
|
|
592
611
|
// Background color should not be set on a container. If this is a nested
|
|
@@ -600,7 +619,8 @@ shaka.text.TtmlTextParser = class {
|
|
|
600
619
|
cueElement, region, styles, 'backgroundColor',
|
|
601
620
|
shouldInheritRegionStyles);
|
|
602
621
|
if (backgroundColor) {
|
|
603
|
-
cue.backgroundColor =
|
|
622
|
+
cue.backgroundColor =
|
|
623
|
+
TtmlTextParser.convertTTMLrgbaToHTMLrgba_(backgroundColor);
|
|
604
624
|
}
|
|
605
625
|
|
|
606
626
|
const border = TtmlTextParser.getStyleAttribute_(
|
|
@@ -709,7 +729,8 @@ shaka.text.TtmlTextParser = class {
|
|
|
709
729
|
// There is no defined color, so default to the text color.
|
|
710
730
|
cue.textStrokeColor = cue.color;
|
|
711
731
|
} else {
|
|
712
|
-
cue.textStrokeColor =
|
|
732
|
+
cue.textStrokeColor =
|
|
733
|
+
TtmlTextParser.convertTTMLrgbaToHTMLrgba_(split[0]);
|
|
713
734
|
split.shift();
|
|
714
735
|
}
|
|
715
736
|
if (split[0] && split[0].match(TtmlTextParser.unitValues_)) {
|