shaka-player 4.12.2 → 4.12.4
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/dist/controls.css +3 -3
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +5 -4
- package/dist/locales.js +35 -35
- package/dist/shaka-player.compiled.d.ts +1 -1
- package/dist/shaka-player.compiled.debug.d.ts +1 -1
- package/dist/shaka-player.compiled.debug.js +299 -297
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.js +1287 -1282
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +1 -1
- package/dist/shaka-player.ui.debug.d.ts +1 -1
- package/dist/shaka-player.ui.debug.js +302 -299
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.js +1515 -1510
- package/dist/shaka-player.ui.map +4 -4
- package/externs/managedmediasource.js +6 -0
- package/externs/shaka/ads.js +3 -0
- package/lib/ads/ad_utils.js +1 -0
- package/lib/ads/interstitial_ad.js +4 -2
- package/lib/ads/interstitial_ad_manager.js +79 -42
- package/lib/cast/cast_utils.js +4 -2
- package/lib/media/drm_engine.js +46 -6
- package/lib/media/media_source_capabilities.js +6 -8
- package/lib/media/media_source_engine.js +3 -4
- package/lib/media/preload_manager.js +9 -3
- package/lib/media/segment_utils.js +7 -3
- package/lib/net/http_xhr_plugin.js +1 -0
- package/lib/player.js +45 -39
- package/lib/text/vtt_text_parser.js +9 -4
- package/lib/util/abortable_operation.js +3 -0
- package/lib/util/buffer_utils.js +10 -8
- package/lib/util/functional.js +27 -0
- 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/stream_utils.js +8 -1
- package/lib/util/uint8array_utils.js +3 -2
- package/package.json +2 -2
- package/ui/ad_position.js +2 -2
- package/ui/controls.js +5 -3
- 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
- package/ui/play_button.js +5 -3
- package/ui/presentation_time.js +1 -1
package/externs/shaka/ads.js
CHANGED
|
@@ -63,6 +63,7 @@ shaka.extern.AdCuePoint;
|
|
|
63
63
|
* startTime: number,
|
|
64
64
|
* endTime: ?number,
|
|
65
65
|
* uri: string,
|
|
66
|
+
* mimeType: ?string,
|
|
66
67
|
* isSkippable: boolean,
|
|
67
68
|
* skipOffset: ?number,
|
|
68
69
|
* skipFor: ?number,
|
|
@@ -87,6 +88,8 @@ shaka.extern.AdCuePoint;
|
|
|
87
88
|
* @property {string} uri
|
|
88
89
|
* The uri of the interstitial, can be any type that
|
|
89
90
|
* ShakaPlayer supports (either in MSE or src=)
|
|
91
|
+
* @property {?string} mimeType
|
|
92
|
+
* The mimeType of the interstitial if known.
|
|
90
93
|
* @property {boolean} isSkippable
|
|
91
94
|
* Indicate if the interstitial is skippable.
|
|
92
95
|
* @property {?number} skipOffset
|
package/lib/ads/ad_utils.js
CHANGED
|
@@ -144,7 +144,7 @@ shaka.ads.InterstitialAd = class {
|
|
|
144
144
|
* @export
|
|
145
145
|
*/
|
|
146
146
|
canSkipNow() {
|
|
147
|
-
return this.getTimeUntilSkippable() == 0;
|
|
147
|
+
return this.isSkippable_ && this.getTimeUntilSkippable() == 0;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
/**
|
|
@@ -152,7 +152,9 @@ shaka.ads.InterstitialAd = class {
|
|
|
152
152
|
* @export
|
|
153
153
|
*/
|
|
154
154
|
skip() {
|
|
155
|
-
this.
|
|
155
|
+
if (this.canSkipNow()) {
|
|
156
|
+
this.onSkip_();
|
|
157
|
+
}
|
|
156
158
|
}
|
|
157
159
|
|
|
158
160
|
/**
|
|
@@ -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
|
|
|
@@ -181,7 +184,10 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
181
184
|
if (difference > 0 && difference <= 10) {
|
|
182
185
|
if (!this.preloadManagerInterstitials_.has(interstitial)) {
|
|
183
186
|
this.preloadManagerInterstitials_.set(
|
|
184
|
-
interstitial, this.player_.preload(
|
|
187
|
+
interstitial, this.player_.preload(
|
|
188
|
+
interstitial.uri,
|
|
189
|
+
/* startTime= */ null,
|
|
190
|
+
interstitial.mimeType || undefined));
|
|
185
191
|
}
|
|
186
192
|
}
|
|
187
193
|
}
|
|
@@ -322,10 +328,11 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
322
328
|
|
|
323
329
|
/** @type {!shaka.extern.AdInterstitial} */
|
|
324
330
|
const interstitial = {
|
|
325
|
-
id:
|
|
331
|
+
id: region.id,
|
|
326
332
|
startTime: region.startTime,
|
|
327
333
|
endTime: region.endTime,
|
|
328
334
|
uri: alternativeMPDUri,
|
|
335
|
+
mimeType: null,
|
|
329
336
|
isSkippable: false,
|
|
330
337
|
skipOffset: null,
|
|
331
338
|
skipFor: null,
|
|
@@ -407,7 +414,10 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
407
414
|
if (shouldPreload) {
|
|
408
415
|
if (!this.preloadManagerInterstitials_.has(interstitial)) {
|
|
409
416
|
this.preloadManagerInterstitials_.set(
|
|
410
|
-
interstitial, this.player_.preload(
|
|
417
|
+
interstitial, this.player_.preload(
|
|
418
|
+
interstitial.uri,
|
|
419
|
+
/* startTime= */ null,
|
|
420
|
+
interstitial.mimeType || undefined));
|
|
411
421
|
}
|
|
412
422
|
}
|
|
413
423
|
}
|
|
@@ -436,13 +446,12 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
436
446
|
|
|
437
447
|
|
|
438
448
|
/**
|
|
439
|
-
* @param {boolean} needPreRoll
|
|
440
|
-
* @param {number} numberToSkip
|
|
441
|
-
* @param {?shaka.extern.AdInterstitial=} lastPlayedAd
|
|
449
|
+
* @param {boolean=} needPreRoll
|
|
450
|
+
* @param {?number=} numberToSkip
|
|
442
451
|
* @return {?shaka.extern.AdInterstitial}
|
|
443
452
|
* @private
|
|
444
453
|
*/
|
|
445
|
-
getCurrentInterstitial_(needPreRoll, numberToSkip
|
|
454
|
+
getCurrentInterstitial_(needPreRoll = false, numberToSkip = null) {
|
|
446
455
|
let skipped = 0;
|
|
447
456
|
let currentInterstitial = null;
|
|
448
457
|
if (this.interstitials_.size && this.lastTime_ != null) {
|
|
@@ -453,7 +462,15 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
453
462
|
const roundDecimals = (number) => {
|
|
454
463
|
return Math.round(number * 1000) / 1000;
|
|
455
464
|
};
|
|
456
|
-
|
|
465
|
+
let interstitialsToCheck = interstitials;
|
|
466
|
+
if (needPreRoll) {
|
|
467
|
+
interstitialsToCheck = interstitials.filter((i) => i.pre);
|
|
468
|
+
} else if (isEnded) {
|
|
469
|
+
interstitialsToCheck = interstitials.filter((i) => i.post);
|
|
470
|
+
} else {
|
|
471
|
+
interstitialsToCheck = interstitials.filter((i) => !i.pre && !i.post);
|
|
472
|
+
}
|
|
473
|
+
for (const interstitial of interstitialsToCheck) {
|
|
457
474
|
let isValid = false;
|
|
458
475
|
if (needPreRoll) {
|
|
459
476
|
isValid = interstitial.pre;
|
|
@@ -464,18 +481,28 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
464
481
|
this.lastTime_ - roundDecimals(interstitial.startTime);
|
|
465
482
|
if (difference > 0 &&
|
|
466
483
|
(difference <= 1 || !interstitial.canJump)) {
|
|
467
|
-
if (
|
|
468
|
-
|
|
484
|
+
if (numberToSkip == null && this.lastPlayedAd_ &&
|
|
485
|
+
!this.lastPlayedAd_.pre && !this.lastPlayedAd_.post &&
|
|
486
|
+
this.lastPlayedAd_.startTime >= interstitial.startTime) {
|
|
469
487
|
isValid = false;
|
|
470
488
|
} else {
|
|
471
489
|
isValid = true;
|
|
472
490
|
}
|
|
473
491
|
}
|
|
474
492
|
}
|
|
475
|
-
if (isValid
|
|
476
|
-
|
|
493
|
+
if (isValid && (!this.lastPlayedAd_ ||
|
|
494
|
+
interstitial.startTime >= this.lastPlayedAd_.startTime)) {
|
|
495
|
+
if (skipped == (numberToSkip || 0)) {
|
|
477
496
|
currentInterstitial = interstitial;
|
|
478
|
-
|
|
497
|
+
} else if (currentInterstitial && !interstitial.canJump) {
|
|
498
|
+
const currentStartTime =
|
|
499
|
+
roundDecimals(currentInterstitial.startTime);
|
|
500
|
+
const newStartTime =
|
|
501
|
+
roundDecimals(interstitial.startTime);
|
|
502
|
+
if (newStartTime - currentStartTime > 0.001) {
|
|
503
|
+
currentInterstitial = interstitial;
|
|
504
|
+
skipped = 0;
|
|
505
|
+
}
|
|
479
506
|
}
|
|
480
507
|
skipped++;
|
|
481
508
|
}
|
|
@@ -520,7 +547,7 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
520
547
|
}).length;
|
|
521
548
|
}
|
|
522
549
|
|
|
523
|
-
if (interstitial.once
|
|
550
|
+
if (interstitial.once) {
|
|
524
551
|
oncePlayed++;
|
|
525
552
|
this.interstitials_.delete(interstitial);
|
|
526
553
|
this.cuepointsChanged_();
|
|
@@ -594,6 +621,10 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
594
621
|
this.setupAd_(nextCurrentInterstitial, sequenceLength,
|
|
595
622
|
++adPosition, initialTime, oncePlayed);
|
|
596
623
|
} else {
|
|
624
|
+
if (interstitial.post) {
|
|
625
|
+
this.lastTime_ = null;
|
|
626
|
+
this.lastPlayedAd_ = null;
|
|
627
|
+
}
|
|
597
628
|
if (this.usingBaseVideo_) {
|
|
598
629
|
await this.player_.detach();
|
|
599
630
|
} else {
|
|
@@ -673,7 +704,6 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
673
704
|
this.onEvent_(new shaka.util.FakeEvent(
|
|
674
705
|
shaka.ads.Utils.AD_SKIP_STATE_CHANGED));
|
|
675
706
|
}
|
|
676
|
-
const eventsSent = new Set();
|
|
677
707
|
this.adEventManager_.listenOnce(this.player_, 'error', error);
|
|
678
708
|
this.adEventManager_.listen(this.video_, 'timeupdate', () => {
|
|
679
709
|
const duration = this.video_.duration;
|
|
@@ -687,23 +717,21 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
687
717
|
new shaka.util.FakeEvent(shaka.ads.Utils.AD_SKIP_STATE_CHANGED));
|
|
688
718
|
}
|
|
689
719
|
prevCanSkipNow = currentCanSkipNow;
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
eventsSent.add('thirdquartile');
|
|
706
|
-
}
|
|
720
|
+
});
|
|
721
|
+
this.adEventManager_.listenOnce(this.player_, 'firstquartile', () => {
|
|
722
|
+
updateBaseVideoTime();
|
|
723
|
+
this.onEvent_(
|
|
724
|
+
new shaka.util.FakeEvent(shaka.ads.Utils.AD_FIRST_QUARTILE));
|
|
725
|
+
});
|
|
726
|
+
this.adEventManager_.listenOnce(this.player_, 'midpoint', () => {
|
|
727
|
+
updateBaseVideoTime();
|
|
728
|
+
this.onEvent_(
|
|
729
|
+
new shaka.util.FakeEvent(shaka.ads.Utils.AD_MIDPOINT));
|
|
730
|
+
});
|
|
731
|
+
this.adEventManager_.listenOnce(this.player_, 'thirdquartile', () => {
|
|
732
|
+
updateBaseVideoTime();
|
|
733
|
+
this.onEvent_(
|
|
734
|
+
new shaka.util.FakeEvent(shaka.ads.Utils.AD_THIRD_QUARTILE));
|
|
707
735
|
});
|
|
708
736
|
this.adEventManager_.listenOnce(this.player_, 'complete', complete);
|
|
709
737
|
this.adEventManager_.listen(this.video_, 'play', () => {
|
|
@@ -754,10 +782,16 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
754
782
|
if (preloadManager) {
|
|
755
783
|
await this.player_.load(preloadManager);
|
|
756
784
|
} else {
|
|
757
|
-
await this.player_.load(
|
|
785
|
+
await this.player_.load(
|
|
786
|
+
interstitial.uri,
|
|
787
|
+
/* startTime= */ null,
|
|
788
|
+
interstitial.mimeType || undefined);
|
|
758
789
|
}
|
|
759
790
|
} else {
|
|
760
|
-
await this.player_.load(
|
|
791
|
+
await this.player_.load(
|
|
792
|
+
interstitial.uri,
|
|
793
|
+
/* startTime= */ null,
|
|
794
|
+
interstitial.mimeType || undefined);
|
|
761
795
|
}
|
|
762
796
|
if (interstitial.playoutLimit) {
|
|
763
797
|
if (playoutLimitTimer) {
|
|
@@ -887,6 +921,7 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
887
921
|
startTime,
|
|
888
922
|
endTime,
|
|
889
923
|
uri,
|
|
924
|
+
mimeType: null,
|
|
890
925
|
isSkippable,
|
|
891
926
|
skipOffset,
|
|
892
927
|
skipFor,
|
|
@@ -916,27 +951,29 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
916
951
|
const skipControl = dataAsJson['SKIP-CONTROL'];
|
|
917
952
|
if (skipControl) {
|
|
918
953
|
const enableSkipAfterValue = skipControl['ENABLE-SKIP-AFTER'];
|
|
919
|
-
if (enableSkipAfterValue
|
|
954
|
+
if ((typeof enableSkipAfterValue) == 'number') {
|
|
920
955
|
skipOffset = parseFloat(enableSkipAfterValue);
|
|
921
956
|
if (isNaN(enableSkipAfterValue)) {
|
|
922
957
|
skipOffset = isSkippable ? 0 : null;
|
|
923
958
|
}
|
|
924
959
|
}
|
|
925
|
-
const enableSkipForValue = skipControl['
|
|
926
|
-
if (enableSkipForValue
|
|
960
|
+
const enableSkipForValue = skipControl['ENABLE-SKIP-FOR'];
|
|
961
|
+
if ((typeof enableSkipForValue) == 'number') {
|
|
927
962
|
skipFor = parseFloat(enableSkipForValue);
|
|
928
963
|
if (isNaN(enableSkipForValue)) {
|
|
929
964
|
skipFor = null;
|
|
930
965
|
}
|
|
931
966
|
}
|
|
932
967
|
}
|
|
933
|
-
for (
|
|
968
|
+
for (let i = 0; i < dataAsJson['ASSETS'].length; i++) {
|
|
969
|
+
const asset = dataAsJson['ASSETS'][i];
|
|
934
970
|
if (asset['URI']) {
|
|
935
971
|
interstitialsAd.push({
|
|
936
|
-
id,
|
|
972
|
+
id: id + '_asset_' + i,
|
|
937
973
|
startTime,
|
|
938
974
|
endTime,
|
|
939
975
|
uri: asset['URI'],
|
|
976
|
+
mimeType: null,
|
|
940
977
|
isSkippable,
|
|
941
978
|
skipOffset,
|
|
942
979
|
skipFor,
|
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/media/drm_engine.js
CHANGED
|
@@ -9,12 +9,14 @@ goog.provide('shaka.media.DrmEngine');
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
10
|
goog.require('shaka.log');
|
|
11
11
|
goog.require('shaka.net.NetworkingEngine');
|
|
12
|
+
goog.require('shaka.util.ArrayUtils');
|
|
12
13
|
goog.require('shaka.util.BufferUtils');
|
|
13
14
|
goog.require('shaka.util.Destroyer');
|
|
14
15
|
goog.require('shaka.util.DrmUtils');
|
|
15
16
|
goog.require('shaka.util.Error');
|
|
16
17
|
goog.require('shaka.util.EventManager');
|
|
17
18
|
goog.require('shaka.util.FakeEvent');
|
|
19
|
+
goog.require('shaka.util.Functional');
|
|
18
20
|
goog.require('shaka.util.IDestroyable');
|
|
19
21
|
goog.require('shaka.util.Iterables');
|
|
20
22
|
goog.require('shaka.util.ManifestParserUtils');
|
|
@@ -66,12 +68,18 @@ shaka.media.DrmEngine = class {
|
|
|
66
68
|
*/
|
|
67
69
|
this.activeSessions_ = new Map();
|
|
68
70
|
|
|
71
|
+
/** @private {!Array.<!shaka.net.NetworkingEngine.PendingRequest>} */
|
|
72
|
+
this.activeRequests_ = [];
|
|
73
|
+
|
|
69
74
|
/**
|
|
70
75
|
* @private {!Map<string,
|
|
71
76
|
* {initData: ?Uint8Array, initDataType: ?string}>}
|
|
72
77
|
*/
|
|
73
78
|
this.storedPersistentSessions_ = new Map();
|
|
74
79
|
|
|
80
|
+
/** @private {boolean} */
|
|
81
|
+
this.hasInitData_ = false;
|
|
82
|
+
|
|
75
83
|
/** @private {!shaka.util.PublicPromise} */
|
|
76
84
|
this.allSessionsLoaded_ = new shaka.util.PublicPromise();
|
|
77
85
|
|
|
@@ -705,6 +713,7 @@ shaka.media.DrmEngine = class {
|
|
|
705
713
|
|
|
706
714
|
// Reset the promise for the next sessions to come if key needs aren't
|
|
707
715
|
// satisfied with persistent sessions
|
|
716
|
+
this.hasInitData_ = false;
|
|
708
717
|
this.allSessionsLoaded_ = new shaka.util.PublicPromise();
|
|
709
718
|
this.allSessionsLoaded_.catch(() => {});
|
|
710
719
|
}
|
|
@@ -766,11 +775,16 @@ shaka.media.DrmEngine = class {
|
|
|
766
775
|
}
|
|
767
776
|
}
|
|
768
777
|
|
|
778
|
+
// Mark that there is init data, so that the preloader will know to wait
|
|
779
|
+
// for sessions to be loaded.
|
|
780
|
+
this.hasInitData_ = true;
|
|
781
|
+
|
|
769
782
|
// If there are pre-existing sessions that have all been loaded
|
|
770
783
|
// then reset the allSessionsLoaded_ promise, which can now be
|
|
771
784
|
// used to wait for new sesssions to be loaded
|
|
772
785
|
if (this.activeSessions_.size > 0 && this.areAllSessionsLoaded_()) {
|
|
773
786
|
this.allSessionsLoaded_.resolve();
|
|
787
|
+
this.hasInitData_ = false;
|
|
774
788
|
this.allSessionsLoaded_ = new shaka.util.PublicPromise();
|
|
775
789
|
this.allSessionsLoaded_.catch(() => {});
|
|
776
790
|
}
|
|
@@ -1380,6 +1394,14 @@ shaka.media.DrmEngine = class {
|
|
|
1380
1394
|
this.video_.paused && !this.initialRequestsSent_);
|
|
1381
1395
|
}
|
|
1382
1396
|
|
|
1397
|
+
/** @return {!Promise} */
|
|
1398
|
+
async waitForActiveRequests() {
|
|
1399
|
+
if (this.hasInitData_) {
|
|
1400
|
+
await this.allSessionsLoaded_;
|
|
1401
|
+
await Promise.all(this.activeRequests_.map((req) => req.promise));
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1383
1405
|
/**
|
|
1384
1406
|
* Sends a license request.
|
|
1385
1407
|
* @param {!MediaKeyMessageEvent} event
|
|
@@ -1439,7 +1461,9 @@ shaka.media.DrmEngine = class {
|
|
|
1439
1461
|
try {
|
|
1440
1462
|
const req = this.playerInterface_.netEngine.request(
|
|
1441
1463
|
requestType, request, {isPreload: this.isPreload_()});
|
|
1464
|
+
this.activeRequests_.push(req);
|
|
1442
1465
|
response = await req.promise;
|
|
1466
|
+
shaka.util.ArrayUtils.remove(this.activeRequests_, req);
|
|
1443
1467
|
} catch (error) {
|
|
1444
1468
|
if (this.destroyer_.destroyed()) {
|
|
1445
1469
|
return;
|
|
@@ -1859,9 +1883,16 @@ shaka.media.DrmEngine = class {
|
|
|
1859
1883
|
offlineConfig.sessionTypes = ['persistent-license'];
|
|
1860
1884
|
|
|
1861
1885
|
const configs = [offlineConfig, basicConfig];
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1886
|
+
// On some (Android) WebView environments,
|
|
1887
|
+
// requestMediaKeySystemAccess will
|
|
1888
|
+
// not resolve or reject, at least if RESOURCE_PROTECTED_MEDIA_ID
|
|
1889
|
+
// is not set. This is a workaround for that issue.
|
|
1890
|
+
const TIMEOUT_FOR_CHECKACCESS_IN_SECONDS = 1;
|
|
1891
|
+
const access =
|
|
1892
|
+
await shaka.util.Functional.promiseWithTimeout(
|
|
1893
|
+
TIMEOUT_FOR_CHECKACCESS_IN_SECONDS,
|
|
1894
|
+
navigator.requestMediaKeySystemAccess(keySystem, configs),
|
|
1895
|
+
);
|
|
1865
1896
|
await processMediaKeySystemAccess(keySystem, access);
|
|
1866
1897
|
} catch (error) {} // Ignore errors.
|
|
1867
1898
|
};
|
|
@@ -1896,13 +1927,22 @@ shaka.media.DrmEngine = class {
|
|
|
1896
1927
|
},
|
|
1897
1928
|
},
|
|
1898
1929
|
};
|
|
1899
|
-
|
|
1930
|
+
// On some (Android) WebView environments, decodingInfo will
|
|
1931
|
+
// not resolve or reject, at least if RESOURCE_PROTECTED_MEDIA_ID
|
|
1932
|
+
// is not set. This is a workaround for that issue.
|
|
1933
|
+
const TIMEOUT_FOR_DECODING_INFO_IN_SECONDS = 1;
|
|
1900
1934
|
const decodingInfo =
|
|
1901
|
-
|
|
1935
|
+
await shaka.util.Functional.promiseWithTimeout(
|
|
1936
|
+
TIMEOUT_FOR_DECODING_INFO_IN_SECONDS,
|
|
1937
|
+
navigator.mediaCapabilities.decodingInfo(decodingConfig),
|
|
1938
|
+
);
|
|
1902
1939
|
|
|
1903
1940
|
const access = decodingInfo.keySystemAccess;
|
|
1904
1941
|
await processMediaKeySystemAccess(keySystem, access);
|
|
1905
|
-
} catch (error) {
|
|
1942
|
+
} catch (error) {
|
|
1943
|
+
// Ignore errors.
|
|
1944
|
+
shaka.log.v2('Failed to probe support for', keySystem, error);
|
|
1945
|
+
}
|
|
1906
1946
|
};
|
|
1907
1947
|
|
|
1908
1948
|
// Initialize the support structure for each key system.
|
|
@@ -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
|
|
|
@@ -271,7 +271,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
271
271
|
* @param {string} mimeType
|
|
272
272
|
*/
|
|
273
273
|
addSecondarySource(uri, mimeType) {
|
|
274
|
-
if (!this.video_ || !
|
|
274
|
+
if (!this.video_ || !window.ManagedMediaSource || !this.mediaSource_) {
|
|
275
275
|
shaka.log.warning(
|
|
276
276
|
'Secondary source is used only with ManagedMediaSource');
|
|
277
277
|
return;
|
|
@@ -882,7 +882,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
882
882
|
return frame.description ===
|
|
883
883
|
'com.apple.streaming.transportStreamTimestamp';
|
|
884
884
|
});
|
|
885
|
-
if (metadataTimestamp
|
|
885
|
+
if (metadataTimestamp) {
|
|
886
886
|
timestamp = Math.round(metadataTimestamp.data) / 1000;
|
|
887
887
|
}
|
|
888
888
|
/** @private {shaka.extern.ID3Metadata} */
|
|
@@ -1139,8 +1139,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1139
1139
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
1140
1140
|
|
|
1141
1141
|
if (contentType == ContentType.TEXT) {
|
|
1142
|
-
if (this.manifestType_ == shaka.media.ManifestParser.HLS
|
|
1143
|
-
reference.discontinuitySequence >= 0) {
|
|
1142
|
+
if (this.manifestType_ == shaka.media.ManifestParser.HLS) {
|
|
1144
1143
|
// This won't be known until the first video segment is appended.
|
|
1145
1144
|
const offset = await this.textSequenceModeOffset_;
|
|
1146
1145
|
this.textEngine_.setTimestampOffset(offset);
|
|
@@ -398,7 +398,13 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
398
398
|
await this.initializeDrmInner_();
|
|
399
399
|
this.throwIfDestroyed_();
|
|
400
400
|
|
|
401
|
-
await this.
|
|
401
|
+
await this.chooseInitialVariantAndPrefetchInner_();
|
|
402
|
+
this.throwIfDestroyed_();
|
|
403
|
+
|
|
404
|
+
// We don't need the drm keys to load completely for the initial variant
|
|
405
|
+
// to be chosen, but we won't mark the load as a success until it has
|
|
406
|
+
// been loaded. So wait for it here, not inside initializeDrmInner_.
|
|
407
|
+
await this.drmEngine_.waitForActiveRequests();
|
|
402
408
|
this.throwIfDestroyed_();
|
|
403
409
|
|
|
404
410
|
this.successPromise_.resolve();
|
|
@@ -610,12 +616,12 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
|
|
|
610
616
|
|
|
611
617
|
/**
|
|
612
618
|
* Performs a final filtering of the manifest, and chooses the initial
|
|
613
|
-
* variant.
|
|
619
|
+
* variant. Also prefetches segments.
|
|
614
620
|
*
|
|
615
621
|
* @return {!Promise}
|
|
616
622
|
* @private
|
|
617
623
|
*/
|
|
618
|
-
async
|
|
624
|
+
async chooseInitialVariantAndPrefetchInner_() {
|
|
619
625
|
goog.asserts.assert(
|
|
620
626
|
this.manifest_, 'The manifest should already be parsed.');
|
|
621
627
|
|
|
@@ -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
|
}
|
|
@@ -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;
|