shaka-player 4.12.3 → 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/dist/deps.js +2 -2
- package/dist/locales.js +35 -35
- package/dist/shaka-player.compiled.debug.js +183 -180
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.js +1192 -1192
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.debug.js +219 -215
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.js +1383 -1383
- package/dist/shaka-player.ui.map +2 -2
- package/lib/ads/interstitial_ad.js +4 -2
- package/lib/ads/interstitial_ad_manager.js +15 -18
- package/lib/media/drm_engine.js +46 -6
- package/lib/media/preload_manager.js +9 -3
- package/lib/player.js +4 -4
- package/lib/util/functional.js +27 -0
- package/lib/util/stream_utils.js +8 -1
- package/package.json +1 -1
- package/ui/ad_position.js +2 -2
- package/ui/controls.js +5 -3
- package/ui/play_button.js +5 -3
- package/ui/presentation_time.js +1 -1
|
@@ -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
|
/**
|
|
@@ -704,7 +704,6 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
704
704
|
this.onEvent_(new shaka.util.FakeEvent(
|
|
705
705
|
shaka.ads.Utils.AD_SKIP_STATE_CHANGED));
|
|
706
706
|
}
|
|
707
|
-
const eventsSent = new Set();
|
|
708
707
|
this.adEventManager_.listenOnce(this.player_, 'error', error);
|
|
709
708
|
this.adEventManager_.listen(this.video_, 'timeupdate', () => {
|
|
710
709
|
const duration = this.video_.duration;
|
|
@@ -718,23 +717,21 @@ shaka.ads.InterstitialAdManager = class {
|
|
|
718
717
|
new shaka.util.FakeEvent(shaka.ads.Utils.AD_SKIP_STATE_CHANGED));
|
|
719
718
|
}
|
|
720
719
|
prevCanSkipNow = currentCanSkipNow;
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
eventsSent.add('thirdquartile');
|
|
737
|
-
}
|
|
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));
|
|
738
735
|
});
|
|
739
736
|
this.adEventManager_.listenOnce(this.player_, 'complete', complete);
|
|
740
737
|
this.adEventManager_.listen(this.video_, 'play', () => {
|
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.
|
|
@@ -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
|
|
package/lib/player.js
CHANGED
|
@@ -1508,7 +1508,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1508
1508
|
// after several playbacks, and they are not able anymore to properly
|
|
1509
1509
|
// create MediaKeys objects. To prevent it, clear the cache after
|
|
1510
1510
|
// each playback.
|
|
1511
|
-
if (this.config_.streaming.clearDecodingCache) {
|
|
1511
|
+
if (this.config_ && this.config_.streaming.clearDecodingCache) {
|
|
1512
1512
|
shaka.util.StreamUtils.clearDecodingConfigCache();
|
|
1513
1513
|
shaka.util.DrmUtils.clearMediaKeySystemAccessMap();
|
|
1514
1514
|
}
|
|
@@ -6984,7 +6984,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6984
6984
|
's). Updating playbackRate to ' + minPlaybackRate);
|
|
6985
6985
|
this.trickPlay(minPlaybackRate, /* useTrickPlayTrack= */ false);
|
|
6986
6986
|
}
|
|
6987
|
-
} else if (maxLatency && maxPlaybackRate &&
|
|
6987
|
+
} else if (maxLatency != undefined && maxPlaybackRate &&
|
|
6988
6988
|
(latency - offset) > maxLatency) {
|
|
6989
6989
|
if (playbackRate != maxPlaybackRate) {
|
|
6990
6990
|
shaka.log.debug('Latency (' + latency + 's) is greater than ' +
|
|
@@ -6993,7 +6993,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6993
6993
|
this.trickPlay(maxPlaybackRate, /* useTrickPlayTrack= */ false);
|
|
6994
6994
|
}
|
|
6995
6995
|
this.targetLatencyReached_ = null;
|
|
6996
|
-
} else if (minLatency && minPlaybackRate &&
|
|
6996
|
+
} else if (minLatency != undefined && minPlaybackRate &&
|
|
6997
6997
|
(latency - offset) < minLatency) {
|
|
6998
6998
|
if (playbackRate != minPlaybackRate) {
|
|
6999
6999
|
shaka.log.debug('Latency (' + latency + 's) is smaller than ' +
|
|
@@ -8275,7 +8275,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
8275
8275
|
* @export
|
|
8276
8276
|
*/
|
|
8277
8277
|
// eslint-disable-next-line no-useless-concat, max-len
|
|
8278
|
-
shaka.Player.version = 'v4.12.
|
|
8278
|
+
shaka.Player.version = 'v4.12.4' + '-uncompiled'; // x-release-please-version
|
|
8279
8279
|
|
|
8280
8280
|
// Initialize the deprecation system using the version string we just set
|
|
8281
8281
|
// on the player.
|
package/lib/util/functional.js
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.util.Functional');
|
|
8
8
|
|
|
9
|
+
goog.require('shaka.util.Timer');
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* @summary A set of functional utility functions.
|
|
11
13
|
*/
|
|
@@ -67,4 +69,29 @@ shaka.util.Functional = class {
|
|
|
67
69
|
static isNotNull(value) {
|
|
68
70
|
return value != null;
|
|
69
71
|
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Returns a Promise which is resolved only if |asyncProcess| is resolved, and
|
|
75
|
+
* only if it is resolved in less than |seconds| seconds.
|
|
76
|
+
*
|
|
77
|
+
* If the returned Promise is resolved, it returns the same value as
|
|
78
|
+
* |asyncProcess|.
|
|
79
|
+
*
|
|
80
|
+
* If |asyncProcess| fails, the returned Promise is rejected.
|
|
81
|
+
* If |asyncProcess| takes too long, the returned Promise is rejected, but
|
|
82
|
+
* |asyncProcess| is still allowed to complete.
|
|
83
|
+
*
|
|
84
|
+
* @param {number} seconds
|
|
85
|
+
* @param {!Promise.<T>} asyncProcess
|
|
86
|
+
* @return {!Promise.<T>}
|
|
87
|
+
* @template T
|
|
88
|
+
*/
|
|
89
|
+
static promiseWithTimeout(seconds, asyncProcess) {
|
|
90
|
+
return Promise.race([
|
|
91
|
+
asyncProcess,
|
|
92
|
+
new Promise(((_, reject) => {
|
|
93
|
+
new shaka.util.Timer(reject).tickAfter(seconds);
|
|
94
|
+
})),
|
|
95
|
+
]);
|
|
96
|
+
}
|
|
70
97
|
};
|
package/lib/util/stream_utils.js
CHANGED
|
@@ -727,7 +727,14 @@ shaka.util.StreamUtils = class {
|
|
|
727
727
|
mimeType, audioCodec);
|
|
728
728
|
}
|
|
729
729
|
promises.push(new Promise((resolve, reject) => {
|
|
730
|
-
|
|
730
|
+
// On some (Android) WebView environments, decodingInfo will
|
|
731
|
+
// not resolve or reject, at least if RESOURCE_PROTECTED_MEDIA_ID
|
|
732
|
+
// is not set. This is a workaround for that issue.
|
|
733
|
+
const TIMEOUT_FOR_DECODING_INFO_IN_SECONDS = 1;
|
|
734
|
+
shaka.util.Functional.promiseWithTimeout(
|
|
735
|
+
TIMEOUT_FOR_DECODING_INFO_IN_SECONDS,
|
|
736
|
+
navigator.mediaCapabilities.decodingInfo(copy),
|
|
737
|
+
).then((res) => {
|
|
731
738
|
resolve(res);
|
|
732
739
|
}).catch(reject);
|
|
733
740
|
}));
|
package/package.json
CHANGED
package/ui/ad_position.js
CHANGED
|
@@ -91,9 +91,9 @@ shaka.ui.AdPosition = class extends shaka.ui.Element {
|
|
|
91
91
|
*/
|
|
92
92
|
setPosition_() {
|
|
93
93
|
const adsInAdPod = this.ad.getSequenceLength();
|
|
94
|
-
if (adsInAdPod > 1) {
|
|
94
|
+
if (adsInAdPod > 1 && this.ad.isLinear()) {
|
|
95
95
|
// If it's a single ad, showing 'Ad 1 of 1' isn't helpful.
|
|
96
|
-
// Only show this element if there's more than 1 ad.
|
|
96
|
+
// Only show this element if there's more than 1 ad and it's a linear ad.
|
|
97
97
|
const LocIds = shaka.ui.Locales.Ids;
|
|
98
98
|
const adPosition = this.ad.getPositionInSequence();
|
|
99
99
|
this.span_.textContent = this.localization.resolve(LocIds.AD_PROGRESS)
|
package/ui/controls.js
CHANGED
|
@@ -1638,11 +1638,13 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
|
|
|
1638
1638
|
|
|
1639
1639
|
/** @private */
|
|
1640
1640
|
onPlayPauseClick_() {
|
|
1641
|
-
if (this.ad_
|
|
1641
|
+
if (this.ad_) {
|
|
1642
1642
|
this.playPauseAd();
|
|
1643
|
-
|
|
1644
|
-
|
|
1643
|
+
if (this.ad_.isLinear()) {
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1645
1646
|
}
|
|
1647
|
+
this.playPausePresentation();
|
|
1646
1648
|
}
|
|
1647
1649
|
|
|
1648
1650
|
/** @private */
|
package/ui/play_button.js
CHANGED
|
@@ -77,11 +77,13 @@ shaka.ui.PlayButton = class extends shaka.ui.Element {
|
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
this.eventManager.listen(this.button, 'click', () => {
|
|
80
|
-
if (this.ad
|
|
80
|
+
if (this.ad) {
|
|
81
81
|
this.controls.playPauseAd();
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
if (this.ad.isLinear()) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
84
85
|
}
|
|
86
|
+
this.controls.playPausePresentation();
|
|
85
87
|
});
|
|
86
88
|
|
|
87
89
|
if (this.ad) {
|
package/ui/presentation_time.js
CHANGED
|
@@ -55,7 +55,7 @@ shaka.ui.PresentationTimeTracker = class extends shaka.ui.Element {
|
|
|
55
55
|
|
|
56
56
|
this.eventManager.listen(
|
|
57
57
|
this.adManager, shaka.ads.Utils.AD_STARTED, () => {
|
|
58
|
-
shaka.ui.Utils.setDisplay(this.currentTime_,
|
|
58
|
+
shaka.ui.Utils.setDisplay(this.currentTime_, !this.ad.isLinear());
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
this.eventManager.listen(
|