shaka-player 4.11.13 → 4.11.15
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/.csslintrc +2 -1
- package/.eslintrc.js +1 -0
- package/AUTHORS +1 -0
- package/CONTRIBUTORS +1 -0
- package/dist/controls.css +3 -3
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +3 -2
- package/dist/locales.js +36 -36
- package/dist/shaka-player.compiled.d.ts +7 -7
- package/dist/shaka-player.compiled.debug.d.ts +7 -7
- package/dist/shaka-player.compiled.debug.js +326 -324
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.js +1317 -1313
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +7 -7
- package/dist/shaka-player.ui.debug.d.ts +7 -7
- package/dist/shaka-player.ui.debug.js +328 -326
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.js +1520 -1516
- package/dist/shaka-player.ui.map +4 -4
- package/externs/managedmediasource.js +6 -0
- package/externs/shaka/abortable.js +36 -36
- package/lib/ads/interstitial_ad_manager.js +41 -15
- package/lib/cast/cast_utils.js +4 -2
- package/lib/hls/hls_parser.js +1 -1
- package/lib/media/drm_engine.js +2 -0
- package/lib/media/media_source_capabilities.js +6 -8
- package/lib/media/media_source_engine.js +61 -4
- package/lib/media/preload_manager.js +6 -1
- package/lib/media/segment_reference.js +1 -1
- package/lib/media/segment_utils.js +7 -3
- package/lib/media/streaming_engine.js +9 -11
- package/lib/net/http_xhr_plugin.js +1 -0
- package/lib/player.js +42 -36
- package/lib/polyfill/media_capabilities.js +46 -8
- package/lib/text/vtt_text_parser.js +9 -10
- package/lib/util/abortable_operation.js +11 -6
- package/lib/util/buffer_utils.js +10 -8
- package/lib/util/mime_utils.js +2 -0
- package/lib/util/number_utils.js +37 -0
- package/lib/util/object_utils.js +1 -1
- package/lib/util/platform.js +18 -7
- package/lib/util/uint8array_utils.js +3 -2
- package/package.json +3 -3
- package/ui/chapter_selection.js +6 -2
- package/ui/language_utils.js +3 -1
- package/ui/less/ad_controls.less +3 -3
- package/ui/less/buttons.less +4 -4
- package/ui/less/containers.less +7 -7
- package/ui/less/overflow_menu.less +4 -4
- package/ui/less/thumbnails.less +3 -3
- package/ui/less/tooltip.less +1 -1
|
@@ -18,39 +18,39 @@
|
|
|
18
18
|
* @template T
|
|
19
19
|
* @exportDoc
|
|
20
20
|
*/
|
|
21
|
-
shaka.extern.IAbortableOperation =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
21
|
+
shaka.extern.IAbortableOperation = class {
|
|
22
|
+
constructor() {
|
|
23
|
+
/**
|
|
24
|
+
* A Promise which represents the underlying operation. It is resolved when
|
|
25
|
+
* the operation is complete, and rejected if the operation fails or is
|
|
26
|
+
* aborted. Aborted operations should be rejected with a shaka.util.Error
|
|
27
|
+
* object using the error code OPERATION_ABORTED.
|
|
28
|
+
*
|
|
29
|
+
* @const {!Promise.<T>}
|
|
30
|
+
* @exportDoc
|
|
31
|
+
*/
|
|
32
|
+
this.promise;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Can be called by anyone holding this object to abort the underlying
|
|
37
|
+
* operation. This is not cancelation, and will not necessarily result in
|
|
38
|
+
* any work being undone. abort() should return a Promise which is resolved
|
|
39
|
+
* when the underlying operation has been aborted. The returned Promise
|
|
40
|
+
* should never be rejected.
|
|
41
|
+
*
|
|
42
|
+
* @return {!Promise}
|
|
43
|
+
* @exportDoc
|
|
44
|
+
*/
|
|
45
|
+
abort() {}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {function(boolean)} onFinal A callback to be invoked after the
|
|
50
|
+
* operation succeeds or fails. The boolean argument is true
|
|
51
|
+
* if the operation succeeded and false if it failed.
|
|
52
|
+
* @return {!shaka.extern.IAbortableOperation.<T>} Returns this.
|
|
53
|
+
* @exportDoc
|
|
54
|
+
*/
|
|
55
|
+
finally(onFinal) {}
|
|
56
|
+
};
|
|
@@ -102,7 +102,7 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
102
102
|
}
|
|
103
103
|
this.lastTime_ = this.baseVideo_.currentTime;
|
|
104
104
|
const currentInterstitial = this.getCurrentInterstitial_(
|
|
105
|
-
/* needPreRoll= */ true
|
|
105
|
+
/* needPreRoll= */ true);
|
|
106
106
|
if (currentInterstitial) {
|
|
107
107
|
this.setupAd_(currentInterstitial, /* sequenceLength= */ 1,
|
|
108
108
|
/* adPosition= */ 1, /* initialTime= */ Date.now());
|
|
@@ -121,14 +121,17 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
121
121
|
this.lastTime_ < this.lastPlayedAd_.startTime) {
|
|
122
122
|
this.lastPlayedAd_ = null;
|
|
123
123
|
}
|
|
124
|
-
const currentInterstitial = this.getCurrentInterstitial_(
|
|
125
|
-
/* needPreRoll= */ false, /* numberToSkip= */ 0, this.lastPlayedAd_);
|
|
124
|
+
const currentInterstitial = this.getCurrentInterstitial_();
|
|
126
125
|
if (currentInterstitial) {
|
|
127
126
|
this.setupAd_(currentInterstitial, /* sequenceLength= */ 1,
|
|
128
127
|
/* adPosition= */ 1, /* initialTime= */ Date.now());
|
|
129
128
|
}
|
|
130
129
|
};
|
|
131
130
|
|
|
131
|
+
this.eventManager_.listen(this.baseVideo_, 'ended', () => {
|
|
132
|
+
checkForInterstitials();
|
|
133
|
+
});
|
|
134
|
+
|
|
132
135
|
/** @private {shaka.util.Timer} */
|
|
133
136
|
this.timeUpdateTimer_ = new shaka.util.Timer(checkForInterstitials);
|
|
134
137
|
|
|
@@ -320,7 +323,7 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
320
323
|
return;
|
|
321
324
|
}
|
|
322
325
|
const interstitial = {
|
|
323
|
-
id:
|
|
326
|
+
id: region.id,
|
|
324
327
|
startTime: region.startTime,
|
|
325
328
|
endTime: region.endTime,
|
|
326
329
|
uri: alternativeMPDUri,
|
|
@@ -433,13 +436,12 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
433
436
|
|
|
434
437
|
|
|
435
438
|
/**
|
|
436
|
-
* @param {boolean} needPreRoll
|
|
437
|
-
* @param {number} numberToSkip
|
|
438
|
-
* @param {?shaka.extern.AdInterstitial=} lastPlayedAd
|
|
439
|
+
* @param {boolean=} needPreRoll
|
|
440
|
+
* @param {?number=} numberToSkip
|
|
439
441
|
* @return {?shaka.extern.AdInterstitial}
|
|
440
442
|
* @private
|
|
441
443
|
*/
|
|
442
|
-
getCurrentInterstitial_(needPreRoll, numberToSkip
|
|
444
|
+
getCurrentInterstitial_(needPreRoll = false, numberToSkip = null) {
|
|
443
445
|
let skipped = 0;
|
|
444
446
|
let currentInterstitial = null;
|
|
445
447
|
if (this.interstitials_.size && this.lastTime_ != null) {
|
|
@@ -450,7 +452,15 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
450
452
|
const roundDecimals = (number) => {
|
|
451
453
|
return Math.round(number * 1000) / 1000;
|
|
452
454
|
};
|
|
453
|
-
|
|
455
|
+
let interstitialsToCheck = interstitials;
|
|
456
|
+
if (needPreRoll) {
|
|
457
|
+
interstitialsToCheck = interstitials.filter((i) => i.pre);
|
|
458
|
+
} else if (isEnded) {
|
|
459
|
+
interstitialsToCheck = interstitials.filter((i) => i.post);
|
|
460
|
+
} else {
|
|
461
|
+
interstitialsToCheck = interstitials.filter((i) => !i.pre && !i.post);
|
|
462
|
+
}
|
|
463
|
+
for (const interstitial of interstitialsToCheck) {
|
|
454
464
|
let isValid = false;
|
|
455
465
|
if (needPreRoll) {
|
|
456
466
|
isValid = interstitial.pre;
|
|
@@ -461,18 +471,28 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
461
471
|
this.lastTime_ - roundDecimals(interstitial.startTime);
|
|
462
472
|
if (difference > 0 &&
|
|
463
473
|
(difference <= 1 || !interstitial.canJump)) {
|
|
464
|
-
if (
|
|
465
|
-
|
|
474
|
+
if (numberToSkip == null && this.lastPlayedAd_ &&
|
|
475
|
+
!this.lastPlayedAd_.pre && !this.lastPlayedAd_.post &&
|
|
476
|
+
this.lastPlayedAd_.startTime >= interstitial.startTime) {
|
|
466
477
|
isValid = false;
|
|
467
478
|
} else {
|
|
468
479
|
isValid = true;
|
|
469
480
|
}
|
|
470
481
|
}
|
|
471
482
|
}
|
|
472
|
-
if (isValid
|
|
473
|
-
|
|
483
|
+
if (isValid && (!this.lastPlayedAd_ ||
|
|
484
|
+
interstitial.startTime >= this.lastPlayedAd_.startTime)) {
|
|
485
|
+
if (skipped == (numberToSkip || 0)) {
|
|
474
486
|
currentInterstitial = interstitial;
|
|
475
|
-
|
|
487
|
+
} else if (currentInterstitial && !interstitial.canJump) {
|
|
488
|
+
const currentStartTime =
|
|
489
|
+
roundDecimals(currentInterstitial.startTime);
|
|
490
|
+
const newStartTime =
|
|
491
|
+
roundDecimals(interstitial.startTime);
|
|
492
|
+
if (newStartTime - currentStartTime > 0.001) {
|
|
493
|
+
currentInterstitial = interstitial;
|
|
494
|
+
skipped = 0;
|
|
495
|
+
}
|
|
476
496
|
}
|
|
477
497
|
skipped++;
|
|
478
498
|
}
|
|
@@ -517,7 +537,7 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
517
537
|
}).length;
|
|
518
538
|
}
|
|
519
539
|
|
|
520
|
-
if (interstitial.once
|
|
540
|
+
if (interstitial.once) {
|
|
521
541
|
oncePlayed++;
|
|
522
542
|
this.interstitials_.delete(interstitial);
|
|
523
543
|
this.cuepointsChanged_();
|
|
@@ -591,6 +611,10 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
591
611
|
this.setupAd_(nextCurrentInterstitial, sequenceLength,
|
|
592
612
|
++adPosition, initialTime, oncePlayed);
|
|
593
613
|
} else {
|
|
614
|
+
if (interstitial.post) {
|
|
615
|
+
this.lastTime_ = null;
|
|
616
|
+
this.lastPlayedAd_ = null;
|
|
617
|
+
}
|
|
594
618
|
if (this.usingBaseVideo_) {
|
|
595
619
|
await this.player_.detach();
|
|
596
620
|
} else {
|
|
@@ -955,6 +979,8 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
955
979
|
goog.asserts.assert(this.player_, 'Must have player');
|
|
956
980
|
goog.asserts.assert(this.basePlayer_, 'Must have base player');
|
|
957
981
|
this.player_.configure(this.basePlayer_.getNonDefaultConfiguration());
|
|
982
|
+
this.player_.configure('ads.disableHLSInterstitial', true);
|
|
983
|
+
this.player_.configure('ads.disableDASHInterstitial', true);
|
|
958
984
|
const netEngine = this.player_.getNetworkingEngine();
|
|
959
985
|
goog.asserts.assert(netEngine, 'Need networking engine');
|
|
960
986
|
netEngine.clearAllRequestFilters();
|
package/lib/cast/cast_utils.js
CHANGED
|
@@ -66,10 +66,12 @@ shaka.cast.CastUtils = class {
|
|
|
66
66
|
return shaka.cast.CastUtils.unpackTimeRanges_(value);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
if (value
|
|
69
|
+
if (ArrayBuffer.isView(value) &&
|
|
70
|
+
/** @type {TypedArray} */(value).BYTES_PER_ELEMENT === 1) {
|
|
70
71
|
// Some of our code cares about Uint8Arrays actually being Uint8Arrays,
|
|
71
72
|
// so this gives them special treatment.
|
|
72
|
-
return shaka.cast.CastUtils.unpackUint8Array_(
|
|
73
|
+
return shaka.cast.CastUtils.unpackUint8Array_(
|
|
74
|
+
/** @type {!Uint8Array} */(value));
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
if (typeof value == 'number') {
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -4122,7 +4122,7 @@ shaka.hls.HlsParser = class {
|
|
|
4122
4122
|
let aesKey = undefined;
|
|
4123
4123
|
|
|
4124
4124
|
let discontinuitySequence = shaka.hls.Utils.getFirstTagWithNameAsNumber(
|
|
4125
|
-
playlist.tags, 'EXT-X-DISCONTINUITY-SEQUENCE',
|
|
4125
|
+
playlist.tags, 'EXT-X-DISCONTINUITY-SEQUENCE', -1);
|
|
4126
4126
|
const mediaSequenceNumber = shaka.hls.Utils.getFirstTagWithNameAsNumber(
|
|
4127
4127
|
playlist.tags, 'EXT-X-MEDIA-SEQUENCE', 0);
|
|
4128
4128
|
const skipTag = shaka.hls.Utils.getFirstTagWithName(
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -1715,6 +1715,7 @@ shaka.media.DrmEngine = class {
|
|
|
1715
1715
|
const testKeySystems = [
|
|
1716
1716
|
'org.w3.clearkey',
|
|
1717
1717
|
'com.widevine.alpha',
|
|
1718
|
+
'com.widevine.alpha.experiment', // Widevine L1 in Windows
|
|
1718
1719
|
'com.microsoft.playready',
|
|
1719
1720
|
'com.microsoft.playready.hardware',
|
|
1720
1721
|
'com.microsoft.playready.recommendation',
|
|
@@ -1739,6 +1740,7 @@ shaka.media.DrmEngine = class {
|
|
|
1739
1740
|
|
|
1740
1741
|
const testRobustness = {
|
|
1741
1742
|
'com.widevine.alpha': widevineRobustness,
|
|
1743
|
+
'com.widevine.alpha.experiment': widevineRobustness,
|
|
1742
1744
|
'com.microsoft.playready.recommendation': playreadyRobustness,
|
|
1743
1745
|
};
|
|
1744
1746
|
|
|
@@ -23,12 +23,9 @@ shaka.media.Capabilities = class {
|
|
|
23
23
|
if (supportMap.has(type)) {
|
|
24
24
|
return supportMap.get(type);
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return currentSupport;
|
|
30
|
-
} else if (window.MediaSource) {
|
|
31
|
-
const currentSupport = MediaSource.isTypeSupported(type);
|
|
26
|
+
const mediaSource = window.ManagedMediaSource || window.MediaSource;
|
|
27
|
+
if (mediaSource) {
|
|
28
|
+
const currentSupport = mediaSource.isTypeSupported(type);
|
|
32
29
|
supportMap.set(type, currentSupport);
|
|
33
30
|
return currentSupport;
|
|
34
31
|
}
|
|
@@ -40,9 +37,10 @@ shaka.media.Capabilities = class {
|
|
|
40
37
|
* @return {boolean}
|
|
41
38
|
*/
|
|
42
39
|
static isChangeTypeSupported() {
|
|
43
|
-
|
|
40
|
+
const sourceBuffer = window.ManagedSourceBuffer || window.SourceBuffer;
|
|
41
|
+
return !!sourceBuffer &&
|
|
44
42
|
// eslint-disable-next-line no-restricted-syntax
|
|
45
|
-
!!
|
|
43
|
+
!!sourceBuffer.prototype && !!sourceBuffer.prototype.changeType;
|
|
46
44
|
}
|
|
47
45
|
};
|
|
48
46
|
|
|
@@ -800,7 +800,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
800
800
|
return frame.description ===
|
|
801
801
|
'com.apple.streaming.transportStreamTimestamp';
|
|
802
802
|
});
|
|
803
|
-
if (metadataTimestamp
|
|
803
|
+
if (metadataTimestamp) {
|
|
804
804
|
timestamp = Math.round(metadataTimestamp.data) / 1000;
|
|
805
805
|
}
|
|
806
806
|
/** @private {shaka.extern.ID3Metadata} */
|
|
@@ -883,7 +883,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
883
883
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
884
884
|
|
|
885
885
|
if (contentType == ContentType.TEXT) {
|
|
886
|
-
if (this.
|
|
886
|
+
if (this.manifestType_ == shaka.media.ManifestParser.HLS) {
|
|
887
887
|
// This won't be known until the first video segment is appended.
|
|
888
888
|
const offset = await this.textSequenceModeOffset_;
|
|
889
889
|
this.textEngine_.setTimestampOffset(offset);
|
|
@@ -977,7 +977,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
977
977
|
const isBestSourceBufferForTimestamps =
|
|
978
978
|
contentType == ContentType.VIDEO ||
|
|
979
979
|
!(ContentType.VIDEO in this.sourceBuffers_);
|
|
980
|
-
if (
|
|
980
|
+
if (isBestSourceBufferForTimestamps) {
|
|
981
981
|
this.textSequenceModeOffset_.resolve(timestampOffset);
|
|
982
982
|
}
|
|
983
983
|
}
|
|
@@ -1306,6 +1306,10 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1306
1306
|
this.textSequenceModeOffset_ = new shaka.util.PublicPromise();
|
|
1307
1307
|
}
|
|
1308
1308
|
|
|
1309
|
+
if (!this.sequenceMode_) {
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1309
1313
|
// Queue an abort() to help MSE splice together overlapping segments.
|
|
1310
1314
|
// We set appendWindowEnd when we change periods in DASH content, and the
|
|
1311
1315
|
// period transition may result in overlap.
|
|
@@ -1839,6 +1843,48 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1839
1843
|
null);
|
|
1840
1844
|
}
|
|
1841
1845
|
|
|
1846
|
+
/**
|
|
1847
|
+
* Returns the source buffer parameters
|
|
1848
|
+
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
1849
|
+
* @return {?shaka.media.MediaSourceEngine.SourceBufferParams}
|
|
1850
|
+
* @private
|
|
1851
|
+
*/
|
|
1852
|
+
getSourceBufferParams_(contentType) {
|
|
1853
|
+
if (!this.sourceBuffers_[contentType]) {
|
|
1854
|
+
return null;
|
|
1855
|
+
}
|
|
1856
|
+
return {
|
|
1857
|
+
timestampOffset: this.sourceBuffers_[contentType].timestampOffset,
|
|
1858
|
+
appendWindowStart: this.sourceBuffers_[contentType].appendWindowStart,
|
|
1859
|
+
appendWindowEnd: this.sourceBuffers_[contentType].appendWindowEnd,
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
/**
|
|
1864
|
+
* Restore source buffer parameters
|
|
1865
|
+
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
1866
|
+
* @param {?shaka.media.MediaSourceEngine.SourceBufferParams} params
|
|
1867
|
+
* @private
|
|
1868
|
+
*/
|
|
1869
|
+
restoreSourceBufferParams_(contentType, params) {
|
|
1870
|
+
if (!params) {
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
if (!this.sourceBuffers_[contentType]) {
|
|
1875
|
+
shaka.log.warning('Attempted to restore a non-existent source buffer');
|
|
1876
|
+
return;
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
this.sourceBuffers_[contentType].timestampOffset =
|
|
1880
|
+
params.timestampOffset;
|
|
1881
|
+
// `end` needs to be set before `start`
|
|
1882
|
+
this.sourceBuffers_[contentType].appendWindowEnd =
|
|
1883
|
+
params.appendWindowEnd;
|
|
1884
|
+
this.sourceBuffers_[contentType].appendWindowStart =
|
|
1885
|
+
params.appendWindowStart;
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1842
1888
|
/**
|
|
1843
1889
|
* Resets the MediaSource and re-adds source buffers due to codec mismatch
|
|
1844
1890
|
*
|
|
@@ -1899,7 +1945,6 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1899
1945
|
}
|
|
1900
1946
|
await Promise.all(cleanup);
|
|
1901
1947
|
this.transmuxers_ = {};
|
|
1902
|
-
this.sourceBuffers_ = {};
|
|
1903
1948
|
|
|
1904
1949
|
const previousDuration = this.mediaSource_.duration;
|
|
1905
1950
|
this.mediaSourceOpen_ = new shaka.util.PublicPromise();
|
|
@@ -1930,6 +1975,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1930
1975
|
onSourceBufferAdded);
|
|
1931
1976
|
|
|
1932
1977
|
for (const contentType of streamsByType.keys()) {
|
|
1978
|
+
const previousParams = this.getSourceBufferParams_(contentType);
|
|
1933
1979
|
const stream = streamsByType.get(contentType);
|
|
1934
1980
|
// eslint-disable-next-line no-await-in-loop
|
|
1935
1981
|
await this.initSourceBuffer_(contentType, stream, stream.codecs);
|
|
@@ -1939,6 +1985,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1939
1985
|
} else {
|
|
1940
1986
|
this.queues_[contentType] = [];
|
|
1941
1987
|
}
|
|
1988
|
+
|
|
1989
|
+
this.restoreSourceBufferParams_(contentType, previousParams);
|
|
1942
1990
|
}
|
|
1943
1991
|
|
|
1944
1992
|
// Fake a seek to catchup the playhead.
|
|
@@ -2226,3 +2274,12 @@ shaka.media.MediaSourceEngine.SourceBufferMode_ = {
|
|
|
2226
2274
|
* Callback to use when metadata arrives.
|
|
2227
2275
|
*/
|
|
2228
2276
|
shaka.media.MediaSourceEngine.PlayerInterface;
|
|
2277
|
+
|
|
2278
|
+
/**
|
|
2279
|
+
* @typedef {{
|
|
2280
|
+
* timestampOffset: number,
|
|
2281
|
+
* appendWindowStart: number,
|
|
2282
|
+
* appendWindowEnd: number
|
|
2283
|
+
* }}
|
|
2284
|
+
*/
|
|
2285
|
+
shaka.media.MediaSourceEngine.SourceBufferParams;
|
|
@@ -403,7 +403,12 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
403
403
|
|
|
404
404
|
this.successPromise_.resolve();
|
|
405
405
|
} catch (error) {
|
|
406
|
-
|
|
406
|
+
// Ignore OPERATION_ABORTED and OBJECT_DESTROYED errors.
|
|
407
|
+
if (!(error instanceof shaka.util.Error) ||
|
|
408
|
+
(error.code != shaka.util.Error.Code.OPERATION_ABORTED &&
|
|
409
|
+
error.code != shaka.util.Error.Code.OBJECT_DESTROYED)) {
|
|
410
|
+
this.successPromise_.reject(error);
|
|
411
|
+
}
|
|
407
412
|
}
|
|
408
413
|
})();
|
|
409
414
|
}
|
|
@@ -295,7 +295,7 @@ shaka.media.SegmentReference = class {
|
|
|
295
295
|
this.thumbnailSprite = null;
|
|
296
296
|
|
|
297
297
|
/** @type {number} */
|
|
298
|
-
this.discontinuitySequence =
|
|
298
|
+
this.discontinuitySequence = -1;
|
|
299
299
|
|
|
300
300
|
/** @type {boolean} */
|
|
301
301
|
this.allPartialSegments = allPartialSegments;
|
|
@@ -417,9 +417,13 @@ shaka.media.SegmentUtils = class {
|
|
|
417
417
|
if (initData) {
|
|
418
418
|
captionParser.init(initData);
|
|
419
419
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
420
|
+
try {
|
|
421
|
+
captionParser.parseFrom(data);
|
|
422
|
+
for (const stream of captionParser.getStreams()) {
|
|
423
|
+
closedCaptions.set(stream, stream);
|
|
424
|
+
}
|
|
425
|
+
} catch (e) {
|
|
426
|
+
shaka.log.debug('Error detecting CC streams', e);
|
|
423
427
|
}
|
|
424
428
|
captionParser.reset();
|
|
425
429
|
}
|
|
@@ -2148,17 +2148,15 @@ shaka.media.StreamingEngine = class {
|
|
|
2148
2148
|
}
|
|
2149
2149
|
}
|
|
2150
2150
|
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
mediaState.type, reference.startTime));
|
|
2161
|
-
}
|
|
2151
|
+
const lastDiscontinuitySequence =
|
|
2152
|
+
mediaState.lastSegmentReference ?
|
|
2153
|
+
mediaState.lastSegmentReference.discontinuitySequence : null;
|
|
2154
|
+
// Across discontinuity bounds, we should resync timestamps. The next
|
|
2155
|
+
// segment appended should land at its theoretical timestamp from the
|
|
2156
|
+
// segment index.
|
|
2157
|
+
if (reference.discontinuitySequence != lastDiscontinuitySequence) {
|
|
2158
|
+
operations.push(this.playerInterface_.mediaSourceEngine.resync(
|
|
2159
|
+
mediaState.type, reference.startTime));
|
|
2162
2160
|
}
|
|
2163
2161
|
|
|
2164
2162
|
await Promise.all(operations);
|
|
@@ -64,6 +64,7 @@ shaka.net.HttpXHRPlugin = class {
|
|
|
64
64
|
};
|
|
65
65
|
xhr.onload = (event) => {
|
|
66
66
|
const headers = shaka.net.HttpXHRPlugin.headersToGenericObject_(xhr);
|
|
67
|
+
// eslint-disable-next-line shaka-rules/buffersource-no-instanceof
|
|
67
68
|
goog.asserts.assert(xhr.response instanceof ArrayBuffer,
|
|
68
69
|
'XHR should have a response by now!');
|
|
69
70
|
const xhrResponse = xhr.response;
|
package/lib/player.js
CHANGED
|
@@ -58,6 +58,7 @@ goog.require('shaka.util.ManifestParserUtils');
|
|
|
58
58
|
goog.require('shaka.util.MediaReadyState');
|
|
59
59
|
goog.require('shaka.util.MimeUtils');
|
|
60
60
|
goog.require('shaka.util.Mutex');
|
|
61
|
+
goog.require('shaka.util.NumberUtils');
|
|
61
62
|
goog.require('shaka.util.ObjectUtils');
|
|
62
63
|
goog.require('shaka.util.Platform');
|
|
63
64
|
goog.require('shaka.util.PlayerConfiguration');
|
|
@@ -740,7 +741,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
740
741
|
this.externalSrcEqualsThumbnailsStreams_ = [];
|
|
741
742
|
|
|
742
743
|
/** @private {number} */
|
|
743
|
-
this.completionPercent_ =
|
|
744
|
+
this.completionPercent_ = -1;
|
|
744
745
|
|
|
745
746
|
/** @private {?shaka.extern.PlayerConfiguration} */
|
|
746
747
|
this.config_ = this.defaultConfig_();
|
|
@@ -1510,7 +1511,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1510
1511
|
|
|
1511
1512
|
this.externalSrcEqualsThumbnailsStreams_ = [];
|
|
1512
1513
|
|
|
1513
|
-
this.completionPercent_ =
|
|
1514
|
+
this.completionPercent_ = -1;
|
|
1514
1515
|
|
|
1515
1516
|
// Make sure that the app knows of the new buffering state.
|
|
1516
1517
|
this.updateBufferState_();
|
|
@@ -6881,41 +6882,46 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6881
6882
|
if (!this.video_) {
|
|
6882
6883
|
return;
|
|
6883
6884
|
}
|
|
6884
|
-
|
|
6885
|
-
const
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
if (
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
if (this.completionPercent_ != newCompletionPercent) {
|
|
6894
|
-
this.completionPercent_ = newCompletionPercent;
|
|
6895
|
-
hasNewCompletionPercent = true;
|
|
6896
|
-
}
|
|
6885
|
+
|
|
6886
|
+
const isQuartile = (quartilePercent, currentPercent) => {
|
|
6887
|
+
const NumberUtils = shaka.util.NumberUtils;
|
|
6888
|
+
|
|
6889
|
+
if ((NumberUtils.isFloatEqual(quartilePercent, currentPercent) ||
|
|
6890
|
+
currentPercent > quartilePercent) &&
|
|
6891
|
+
this.completionPercent_ < quartilePercent) {
|
|
6892
|
+
this.completionPercent_ = quartilePercent;
|
|
6893
|
+
return true;
|
|
6897
6894
|
}
|
|
6895
|
+
return false;
|
|
6896
|
+
};
|
|
6897
|
+
|
|
6898
|
+
const completionRatio = this.video_.currentTime / this.video_.duration;
|
|
6899
|
+
|
|
6900
|
+
if (isNaN(completionRatio)) {
|
|
6901
|
+
return;
|
|
6898
6902
|
}
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6903
|
+
|
|
6904
|
+
const percent = completionRatio * 100;
|
|
6905
|
+
|
|
6906
|
+
let event;
|
|
6907
|
+
if (isQuartile(0, percent)) {
|
|
6908
|
+
event = shaka.Player.makeEvent_(shaka.util.FakeEvent.EventName.Started);
|
|
6909
|
+
} else if (isQuartile(25, percent)) {
|
|
6910
|
+
event = shaka.Player.makeEvent_(
|
|
6911
|
+
shaka.util.FakeEvent.EventName.FirstQuartile);
|
|
6912
|
+
} else if (isQuartile(50, percent)) {
|
|
6913
|
+
event = shaka.Player.makeEvent_(
|
|
6914
|
+
shaka.util.FakeEvent.EventName.Midpoint);
|
|
6915
|
+
} else if (isQuartile(75, percent)) {
|
|
6916
|
+
event = shaka.Player.makeEvent_(
|
|
6917
|
+
shaka.util.FakeEvent.EventName.ThirdQuartile);
|
|
6918
|
+
} else if (isQuartile(100, percent)) {
|
|
6919
|
+
event = shaka.Player.makeEvent_(
|
|
6920
|
+
shaka.util.FakeEvent.EventName.Complete);
|
|
6921
|
+
}
|
|
6922
|
+
|
|
6923
|
+
if (event) {
|
|
6924
|
+
this.dispatchEvent(event);
|
|
6919
6925
|
}
|
|
6920
6926
|
}
|
|
6921
6927
|
|
|
@@ -8123,7 +8129,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
8123
8129
|
* @export
|
|
8124
8130
|
*/
|
|
8125
8131
|
// eslint-disable-next-line no-useless-concat, max-len
|
|
8126
|
-
shaka.Player.version = 'v4.11.
|
|
8132
|
+
shaka.Player.version = 'v4.11.15' + '-uncompiled'; // x-release-please-version
|
|
8127
8133
|
|
|
8128
8134
|
// Initialize the deprecation system using the version string we just set
|
|
8129
8135
|
// on the player.
|