shaka-player 4.8.10 → 4.9.1
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/README.md +5 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +5 -5
- package/dist/locales.js +34 -34
- package/dist/shaka-player.compiled.d.ts +39 -18
- package/dist/shaka-player.compiled.debug.d.ts +39 -18
- package/dist/shaka-player.compiled.debug.externs.js +32 -12
- package/dist/shaka-player.compiled.debug.js +638 -579
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +32 -12
- package/dist/shaka-player.compiled.js +1272 -1237
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +39 -18
- package/dist/shaka-player.ui.debug.d.ts +39 -18
- package/dist/shaka-player.ui.debug.externs.js +43 -23
- package/dist/shaka-player.ui.debug.js +668 -609
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +43 -23
- package/dist/shaka-player.ui.js +1487 -1451
- package/dist/shaka-player.ui.map +4 -4
- package/externs/shaka/manifest.js +11 -1
- package/externs/shaka/offline.js +3 -0
- package/externs/shaka/player.js +105 -12
- package/externs/tizen.js +1 -1
- package/lib/abr/simple_abr_manager.js +5 -0
- package/lib/ads/media_tailor_ad.js +11 -0
- package/lib/ads/media_tailor_ad_manager.js +37 -3
- package/lib/dash/dash_parser.js +655 -46
- package/lib/dash/mpd_utils.js +7 -8
- package/lib/dash/segment_template.js +65 -10
- package/lib/hls/hls_parser.js +92 -34
- package/lib/media/content_workarounds.js +4 -2
- package/lib/media/drm_engine.js +274 -40
- package/lib/media/manifest_filterer.js +2 -2
- package/lib/media/media_source_engine.js +66 -31
- package/lib/media/segment_utils.js +14 -3
- package/lib/mss/mss_parser.js +2 -0
- package/lib/net/http_plugin_utils.js +2 -1
- package/lib/net/networking_engine.js +14 -0
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/manifest_converter.js +2 -0
- package/lib/offline/storage.js +1 -0
- package/lib/player.js +220 -14
- package/lib/polyfill/media_capabilities.js +10 -35
- package/lib/transmuxer/aac_transmuxer.js +4 -2
- package/lib/transmuxer/ac3_transmuxer.js +2 -1
- package/lib/transmuxer/ec3_transmuxer.js +2 -1
- package/lib/transmuxer/mp3_transmuxer.js +4 -2
- package/lib/transmuxer/mpeg_ts_transmuxer.js +2 -1
- package/lib/transmuxer/mss_transmuxer.js +4 -2
- package/lib/transmuxer/ts_transmuxer.js +44 -24
- package/lib/util/config_utils.js +74 -6
- package/lib/util/error.js +17 -8
- package/lib/util/mp4_box_parsers.js +23 -2
- package/lib/util/periods.js +51 -28
- package/lib/util/platform.js +3 -1
- package/lib/util/player_configuration.js +20 -8
- package/lib/util/stream_utils.js +62 -30
- package/lib/util/tXml.js +74 -6
- package/package.json +2 -2
- package/support.html +1 -0
- package/ui/controls.js +4 -0
- package/ui/less/ad_controls.less +2 -1
- package/ui/resolution_selection.js +12 -3
|
@@ -41,6 +41,7 @@ shaka.media.SegmentUtils = class {
|
|
|
41
41
|
sampleRate: null,
|
|
42
42
|
closedCaptions: new Map(),
|
|
43
43
|
videoRange: null,
|
|
44
|
+
colorGamut: null,
|
|
44
45
|
};
|
|
45
46
|
}
|
|
46
47
|
|
|
@@ -125,6 +126,7 @@ shaka.media.SegmentUtils = class {
|
|
|
125
126
|
sampleRate: null,
|
|
126
127
|
closedCaptions: closedCaptions,
|
|
127
128
|
videoRange: null,
|
|
129
|
+
colorGamut: null,
|
|
128
130
|
};
|
|
129
131
|
}
|
|
130
132
|
|
|
@@ -199,6 +201,8 @@ shaka.media.SegmentUtils = class {
|
|
|
199
201
|
let sampleRate = null;
|
|
200
202
|
/** @type {?string} */
|
|
201
203
|
let realVideoRange = null;
|
|
204
|
+
/** @type {?string} */
|
|
205
|
+
let realColorGamut = null;
|
|
202
206
|
|
|
203
207
|
/** @type {?string} */
|
|
204
208
|
let baseBox;
|
|
@@ -371,8 +375,10 @@ shaka.media.SegmentUtils = class {
|
|
|
371
375
|
})
|
|
372
376
|
|
|
373
377
|
.box('colr', (box) => {
|
|
374
|
-
const {videoRange} =
|
|
378
|
+
const {videoRange, colorGamut} =
|
|
379
|
+
shaka.util.Mp4BoxParsers.parseCOLR(box.reader);
|
|
375
380
|
realVideoRange = videoRange;
|
|
381
|
+
realColorGamut = colorGamut;
|
|
376
382
|
})
|
|
377
383
|
|
|
378
384
|
.parse(initData || data, /* partialOkay= */ true);
|
|
@@ -404,6 +410,7 @@ shaka.media.SegmentUtils = class {
|
|
|
404
410
|
sampleRate: sampleRate,
|
|
405
411
|
closedCaptions: closedCaptions,
|
|
406
412
|
videoRange: realVideoRange,
|
|
413
|
+
colorGamut: realColorGamut,
|
|
407
414
|
};
|
|
408
415
|
}
|
|
409
416
|
|
|
@@ -465,7 +472,9 @@ shaka.media.SegmentUtils = class {
|
|
|
465
472
|
return codecs;
|
|
466
473
|
}
|
|
467
474
|
const dolbyVision = codecs.find((codec) => {
|
|
468
|
-
return codec.startsWith('dvh1.') ||
|
|
475
|
+
return codec.startsWith('dvh1.') ||
|
|
476
|
+
codec.startsWith('dvhe.') ||
|
|
477
|
+
codec.startsWith('dav1.');
|
|
469
478
|
});
|
|
470
479
|
if (!dolbyVision) {
|
|
471
480
|
return codecs;
|
|
@@ -518,7 +527,8 @@ shaka.media.SegmentUtils = class {
|
|
|
518
527
|
* channelCount: ?number,
|
|
519
528
|
* sampleRate: ?number,
|
|
520
529
|
* closedCaptions: Map.<string, string>,
|
|
521
|
-
* videoRange: ?string
|
|
530
|
+
* videoRange: ?string,
|
|
531
|
+
* colorGamut: ?string
|
|
522
532
|
* }}
|
|
523
533
|
*
|
|
524
534
|
* @property {string} type
|
|
@@ -531,5 +541,6 @@ shaka.media.SegmentUtils = class {
|
|
|
531
541
|
* @property {?number} sampleRate
|
|
532
542
|
* @property {Map.<string, string>} closedCaptions
|
|
533
543
|
* @property {?string} videoRange
|
|
544
|
+
* @property {?string} colorGamut
|
|
534
545
|
*/
|
|
535
546
|
shaka.media.SegmentUtils.BasicInfo;
|
package/lib/mss/mss_parser.js
CHANGED
|
@@ -419,6 +419,7 @@ shaka.mss.MssParser = class {
|
|
|
419
419
|
ignoreManifestTimestampsInSegmentsMode: false,
|
|
420
420
|
type: shaka.media.ManifestParser.MSS,
|
|
421
421
|
serviceDescription: null,
|
|
422
|
+
nextUrl: null,
|
|
422
423
|
};
|
|
423
424
|
|
|
424
425
|
// This is the first point where we have a meaningful presentation start
|
|
@@ -570,6 +571,7 @@ shaka.mss.MssParser = class {
|
|
|
570
571
|
spatialAudio: false,
|
|
571
572
|
closedCaptions: null,
|
|
572
573
|
hdr: undefined,
|
|
574
|
+
colorGamut: undefined,
|
|
573
575
|
videoLayout: undefined,
|
|
574
576
|
tilesLayout: undefined,
|
|
575
577
|
matchedStreams: [],
|
|
@@ -96,10 +96,21 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
96
96
|
/** @private {?shaka.net.NetworkingEngine.OnResponse} */
|
|
97
97
|
this.onResponse_ = onResponse || null;
|
|
98
98
|
|
|
99
|
+
/** @private {boolean} */
|
|
100
|
+
this.forceHTTP_ = false;
|
|
101
|
+
|
|
99
102
|
/** @private {boolean} */
|
|
100
103
|
this.forceHTTPS_ = false;
|
|
101
104
|
}
|
|
102
105
|
|
|
106
|
+
/**
|
|
107
|
+
* @param {boolean} forceHTTP
|
|
108
|
+
* @export
|
|
109
|
+
*/
|
|
110
|
+
setForceHTTP(forceHTTP) {
|
|
111
|
+
this.forceHTTP_ = forceHTTP;
|
|
112
|
+
}
|
|
113
|
+
|
|
103
114
|
/**
|
|
104
115
|
* @param {boolean} forceHTTPS
|
|
105
116
|
* @export
|
|
@@ -463,6 +474,9 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
463
474
|
*/
|
|
464
475
|
send_(type, request, context, backoff, index, lastError,
|
|
465
476
|
numBytesRemainingObj) {
|
|
477
|
+
if (this.forceHTTP_) {
|
|
478
|
+
request.uris[index] = request.uris[index].replace('https://', 'http://');
|
|
479
|
+
}
|
|
466
480
|
if (this.forceHTTPS_) {
|
|
467
481
|
request.uris[index] = request.uris[index].replace('http://', 'https://');
|
|
468
482
|
}
|
|
@@ -93,6 +93,7 @@ shaka.offline.ManifestConverter = class {
|
|
|
93
93
|
ignoreManifestTimestampsInSegmentsMode: false,
|
|
94
94
|
type: manifestDB.type || shaka.media.ManifestParser.UNKNOWN,
|
|
95
95
|
serviceDescription: null,
|
|
96
|
+
nextUrl: null,
|
|
96
97
|
};
|
|
97
98
|
}
|
|
98
99
|
|
|
@@ -191,6 +192,7 @@ shaka.offline.ManifestConverter = class {
|
|
|
191
192
|
frameRate: streamDB.frameRate,
|
|
192
193
|
pixelAspectRatio: streamDB.pixelAspectRatio,
|
|
193
194
|
hdr: streamDB.hdr,
|
|
195
|
+
colorGamut: streamDB.colorGamut,
|
|
194
196
|
videoLayout: streamDB.videoLayout,
|
|
195
197
|
kind: streamDB.kind,
|
|
196
198
|
encrypted: streamDB.encrypted,
|
package/lib/offline/storage.js
CHANGED
|
@@ -1316,6 +1316,7 @@ shaka.offline.Storage = class {
|
|
|
1316
1316
|
frameRate: stream.frameRate,
|
|
1317
1317
|
pixelAspectRatio: stream.pixelAspectRatio,
|
|
1318
1318
|
hdr: stream.hdr,
|
|
1319
|
+
colorGamut: stream.colorGamut,
|
|
1319
1320
|
videoLayout: stream.videoLayout,
|
|
1320
1321
|
kind: stream.kind,
|
|
1321
1322
|
language: stream.language,
|
package/lib/player.js
CHANGED
|
@@ -582,6 +582,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
582
582
|
*/
|
|
583
583
|
this.trickPlayEventManager_ = new shaka.util.EventManager();
|
|
584
584
|
|
|
585
|
+
/**
|
|
586
|
+
* For listeners scoped to the lifetime of the ad manager.
|
|
587
|
+
* @private {shaka.util.EventManager}
|
|
588
|
+
*/
|
|
589
|
+
this.adManagerEventManager_ = new shaka.util.EventManager();
|
|
590
|
+
|
|
585
591
|
/** @private {shaka.net.NetworkingEngine} */
|
|
586
592
|
this.networkingEngine_ = null;
|
|
587
593
|
|
|
@@ -708,7 +714,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
708
714
|
*/
|
|
709
715
|
this.lastTextFactory_;
|
|
710
716
|
|
|
711
|
-
/** @private {
|
|
717
|
+
/** @private {shaka.extern.Resolution} */
|
|
712
718
|
this.maxHwRes_ = {width: Infinity, height: Infinity};
|
|
713
719
|
|
|
714
720
|
/** @private {!shaka.media.ManifestFilterer} */
|
|
@@ -758,14 +764,78 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
758
764
|
this.cmsdManager_ = this.createCmsd_();
|
|
759
765
|
|
|
760
766
|
this.networkingEngine_ = this.createNetworkingEngine();
|
|
767
|
+
this.networkingEngine_.setForceHTTP(this.config_.streaming.forceHTTP);
|
|
761
768
|
this.networkingEngine_.setForceHTTPS(this.config_.streaming.forceHTTPS);
|
|
762
769
|
|
|
763
770
|
/** @private {shaka.extern.IAdManager} */
|
|
764
771
|
this.adManager_ = null;
|
|
765
772
|
|
|
773
|
+
/** @private {?shaka.media.PreloadManager} */
|
|
774
|
+
this.preloadDueAdManager_ = null;
|
|
775
|
+
|
|
776
|
+
/** @private {HTMLMediaElement} */
|
|
777
|
+
this.preloadDueAdManagerVideo_ = null;
|
|
778
|
+
|
|
779
|
+
/** @private {shaka.util.Timer} */
|
|
780
|
+
this.preloadDueAdManagerTimer_ = new shaka.util.Timer(async () => {
|
|
781
|
+
if (this.preloadDueAdManager_) {
|
|
782
|
+
goog.asserts.assert(this.preloadDueAdManagerVideo_, 'Must have video');
|
|
783
|
+
await this.attach(
|
|
784
|
+
this.preloadDueAdManagerVideo_, /* initializeMediaSource= */ true);
|
|
785
|
+
await this.load(this.preloadDueAdManager_);
|
|
786
|
+
this.preloadDueAdManagerVideo_.play();
|
|
787
|
+
this.preloadDueAdManager_ = null;
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
|
|
766
791
|
if (shaka.Player.adManagerFactory_) {
|
|
767
792
|
this.adManager_ = shaka.Player.adManagerFactory_();
|
|
768
793
|
this.adManager_.configure(this.config_.ads);
|
|
794
|
+
|
|
795
|
+
// Note: we don't use shaka.ads.AdManager.AD_STARTED to avoid add a
|
|
796
|
+
// optional module in the player.
|
|
797
|
+
this.adManagerEventManager_.listen(
|
|
798
|
+
this.adManager_, 'ad-started', async (e) => {
|
|
799
|
+
if (this.config_.ads.supportsMultipleMediaElements) {
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
const event = /** @type {?google.ima.AdEvent} */
|
|
803
|
+
(e['originalEvent']);
|
|
804
|
+
if (!event) {
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
const contentPauseRequested =
|
|
808
|
+
google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED;
|
|
809
|
+
if (event.type != contentPauseRequested) {
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
this.preloadDueAdManagerTimer_.stop();
|
|
813
|
+
if (!this.preloadDueAdManager_) {
|
|
814
|
+
this.preloadDueAdManagerVideo_ = this.video_;
|
|
815
|
+
this.preloadDueAdManager_ =
|
|
816
|
+
await this.detachAndSavePreload(true);
|
|
817
|
+
}
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
// Note: we don't use shaka.ads.AdManager.AD_STOPPED to avoid add a
|
|
821
|
+
// optional module in the player.
|
|
822
|
+
this.adManagerEventManager_.listen(
|
|
823
|
+
this.adManager_, 'ad-stopped', (e) => {
|
|
824
|
+
if (this.config_.ads.supportsMultipleMediaElements) {
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
const event = /** @type {?google.ima.AdEvent} */
|
|
828
|
+
(e['originalEvent']);
|
|
829
|
+
if (!event) {
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
const contentResumeRequested =
|
|
833
|
+
google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED;
|
|
834
|
+
if (event.type != contentResumeRequested) {
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
this.preloadDueAdManagerTimer_.tickAfter(0.1);
|
|
838
|
+
});
|
|
769
839
|
}
|
|
770
840
|
|
|
771
841
|
// If the browser comes back online after being offline, then try to play
|
|
@@ -779,6 +849,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
779
849
|
this.checkVariantsTimer_ =
|
|
780
850
|
new shaka.util.Timer(() => this.checkVariants_());
|
|
781
851
|
|
|
852
|
+
/** @private {?shaka.media.PreloadManager} */
|
|
853
|
+
this.preloadNextUrl_ = null;
|
|
854
|
+
|
|
782
855
|
// Even though |attach| will start in later interpreter cycles, it should be
|
|
783
856
|
// the LAST thing we do in the constructor because conceptually it relies on
|
|
784
857
|
// player having been initialized.
|
|
@@ -913,6 +986,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
913
986
|
this.trickPlayEventManager_.release();
|
|
914
987
|
this.trickPlayEventManager_ = null;
|
|
915
988
|
}
|
|
989
|
+
if (this.adManagerEventManager_) {
|
|
990
|
+
this.adManagerEventManager_.release();
|
|
991
|
+
this.adManagerEventManager_ = null;
|
|
992
|
+
}
|
|
916
993
|
|
|
917
994
|
this.abrManagerFactory_ = null;
|
|
918
995
|
this.config_ = null;
|
|
@@ -1030,10 +1107,15 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1030
1107
|
}
|
|
1031
1108
|
const manifest = shaka.media.ManifestParser.probeSupport();
|
|
1032
1109
|
const media = shaka.media.MediaSourceEngine.probeSupport();
|
|
1110
|
+
const hardwareResolution =
|
|
1111
|
+
await shaka.util.Platform.detectMaxHardwareResolution();
|
|
1112
|
+
|
|
1113
|
+
/** @type {shaka.extern.SupportType} */
|
|
1033
1114
|
const ret = {
|
|
1034
|
-
manifest
|
|
1035
|
-
media
|
|
1036
|
-
drm
|
|
1115
|
+
manifest,
|
|
1116
|
+
media,
|
|
1117
|
+
drm,
|
|
1118
|
+
hardwareResolution,
|
|
1037
1119
|
};
|
|
1038
1120
|
|
|
1039
1121
|
const plugins = shaka.Player.supportPlugins_;
|
|
@@ -1301,6 +1383,15 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1301
1383
|
this.adManager_.onAssetUnload();
|
|
1302
1384
|
}
|
|
1303
1385
|
|
|
1386
|
+
if (this.preloadDueAdManager_ && !keepAdManager) {
|
|
1387
|
+
this.preloadDueAdManager_.destroy();
|
|
1388
|
+
this.preloadDueAdManager_ = null;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
if (!keepAdManager) {
|
|
1392
|
+
this.preloadDueAdManagerTimer_.stop();
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1304
1395
|
if (this.cmsdManager_) {
|
|
1305
1396
|
this.cmsdManager_.reset();
|
|
1306
1397
|
}
|
|
@@ -1332,6 +1423,14 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1332
1423
|
this.drmEngine_ = null;
|
|
1333
1424
|
}
|
|
1334
1425
|
|
|
1426
|
+
if (this.preloadNextUrl_ &&
|
|
1427
|
+
this.assetUri_ != this.preloadNextUrl_.getAssetUri()) {
|
|
1428
|
+
if (!this.preloadNextUrl_.isDestroyed()) {
|
|
1429
|
+
this.preloadNextUrl_.destroy();
|
|
1430
|
+
}
|
|
1431
|
+
this.preloadNextUrl_ = null;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1335
1434
|
this.assetUri_ = null;
|
|
1336
1435
|
this.mimeType_ = null;
|
|
1337
1436
|
this.bufferObserver_ = null;
|
|
@@ -1351,6 +1450,15 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1351
1450
|
}
|
|
1352
1451
|
}
|
|
1353
1452
|
|
|
1453
|
+
// On some devices, cached MediaKeySystemAccess objects may corrupt
|
|
1454
|
+
// after several playbacks, and they are not able anymore to properly
|
|
1455
|
+
// create MediaKeys objects. To prevent it, clear the cache after
|
|
1456
|
+
// each playback.
|
|
1457
|
+
if (this.config_.streaming.clearDecodingCache) {
|
|
1458
|
+
shaka.util.StreamUtils.clearDecodingConfigCache();
|
|
1459
|
+
shaka.media.DrmEngine.clearMediaKeySystemAccessMap();
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1354
1462
|
this.manifest_ = null;
|
|
1355
1463
|
this.stats_ = new shaka.util.Stats(); // Replace with a clean object.
|
|
1356
1464
|
this.lastTextFactory_ = null;
|
|
@@ -1426,6 +1534,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1426
1534
|
}
|
|
1427
1535
|
|
|
1428
1536
|
if (this.assetUri_) {
|
|
1537
|
+
// Note: This is used to avoid the destruction of the nextUrl
|
|
1538
|
+
// preloadManager that can be the current one.
|
|
1539
|
+
this.assetUri_ = assetUri;
|
|
1429
1540
|
await this.unload(/* initializeMediaSource= */ false);
|
|
1430
1541
|
}
|
|
1431
1542
|
|
|
@@ -1627,6 +1738,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1627
1738
|
// properly destroyed or released.
|
|
1628
1739
|
await preloadManager.destroy();
|
|
1629
1740
|
}
|
|
1741
|
+
this.preloadNextUrl_ = null;
|
|
1630
1742
|
}
|
|
1631
1743
|
}
|
|
1632
1744
|
|
|
@@ -1664,6 +1776,34 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1664
1776
|
*/
|
|
1665
1777
|
async unloadAndSavePreload(
|
|
1666
1778
|
initializeMediaSource = true, keepAdManager = false) {
|
|
1779
|
+
const preloadManager = await this.savePreload_();
|
|
1780
|
+
await this.unload(initializeMediaSource, keepAdManager);
|
|
1781
|
+
return preloadManager;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
/**
|
|
1785
|
+
* Detach the player from the current media element, if any, and returns a
|
|
1786
|
+
* PreloadManager that contains the loaded manifest of that asset, if any.
|
|
1787
|
+
* Allows for the asset to be re-loaded by this player faster, in the future.
|
|
1788
|
+
* When in src= mode, this detach but does not make a PreloadManager.
|
|
1789
|
+
* Leaves the player in a state where it cannot play media, until it has been
|
|
1790
|
+
* attached to something else.
|
|
1791
|
+
*
|
|
1792
|
+
* @param {boolean=} keepAdManager
|
|
1793
|
+
* @return {!Promise.<?shaka.media.PreloadManager>}
|
|
1794
|
+
* @export
|
|
1795
|
+
*/
|
|
1796
|
+
async detachAndSavePreload(keepAdManager = false) {
|
|
1797
|
+
const preloadManager = await this.savePreload_();
|
|
1798
|
+
await this.detach(keepAdManager);
|
|
1799
|
+
return preloadManager;
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
/**
|
|
1803
|
+
* @return {!Promise.<?shaka.media.PreloadManager>}
|
|
1804
|
+
* @private
|
|
1805
|
+
*/
|
|
1806
|
+
async savePreload_() {
|
|
1667
1807
|
let preloadManager = null;
|
|
1668
1808
|
if (this.manifest_ && this.parser_ && this.parserFactory_ &&
|
|
1669
1809
|
this.assetUri_) {
|
|
@@ -1698,7 +1838,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1698
1838
|
this.abrManager_ = null;
|
|
1699
1839
|
this.abrManagerFactory_ = null;
|
|
1700
1840
|
}
|
|
1701
|
-
await this.unload(initializeMediaSource, keepAdManager);
|
|
1702
1841
|
return preloadManager;
|
|
1703
1842
|
}
|
|
1704
1843
|
|
|
@@ -2376,6 +2515,28 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2376
2515
|
this.loadEventManager_.listen(
|
|
2377
2516
|
mediaElement, 'timeupdate', onVideoProgress);
|
|
2378
2517
|
this.onVideoProgress_();
|
|
2518
|
+
if (this.manifest_.nextUrl) {
|
|
2519
|
+
if (this.config_.streaming.preloadNextUrlWindow > 0) {
|
|
2520
|
+
const onTimeUpdate = async () => {
|
|
2521
|
+
const timeToEnd = this.video_.duration - this.video_.currentTime;
|
|
2522
|
+
if (!isNaN(timeToEnd)) {
|
|
2523
|
+
if (timeToEnd <= this.config_.streaming.preloadNextUrlWindow) {
|
|
2524
|
+
this.loadEventManager_.unlisten(
|
|
2525
|
+
mediaElement, 'timeupdate', onTimeUpdate);
|
|
2526
|
+
goog.asserts.assert(this.manifest_.nextUrl,
|
|
2527
|
+
'this.manifest_.nextUrl should be valid.');
|
|
2528
|
+
this.preloadNextUrl_ =
|
|
2529
|
+
await this.preload(this.manifest_.nextUrl);
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
};
|
|
2533
|
+
this.loadEventManager_.listen(
|
|
2534
|
+
mediaElement, 'timeupdate', onTimeUpdate);
|
|
2535
|
+
}
|
|
2536
|
+
this.loadEventManager_.listen(mediaElement, 'ended', () => {
|
|
2537
|
+
this.load(this.preloadNextUrl_ || this.manifest_.nextUrl);
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2379
2540
|
}
|
|
2380
2541
|
|
|
2381
2542
|
if (this.adManager_) {
|
|
@@ -3413,10 +3574,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3413
3574
|
}
|
|
3414
3575
|
|
|
3415
3576
|
// If lowLatencyMode is enabled, and inaccurateManifestTolerance and
|
|
3416
|
-
// rebufferingGoal and segmentPrefetchLimit and baseDelay
|
|
3417
|
-
//
|
|
3418
|
-
// to 0
|
|
3419
|
-
//
|
|
3577
|
+
// rebufferingGoal and segmentPrefetchLimit and baseDelay and
|
|
3578
|
+
// autoCorrectDrift and maxDisabledTime are not specified, set
|
|
3579
|
+
// inaccurateManifestTolerance to 0 and rebufferingGoal to 0.01 and
|
|
3580
|
+
// segmentPrefetchLimit to 2 and updateIntervalSeconds to 0.1 and and
|
|
3581
|
+
// baseDelay to 100 and autoCorrectDrift to false and maxDisabledTime
|
|
3582
|
+
// to 1 by default for low latency streaming.
|
|
3420
3583
|
if (config['streaming'] && config['streaming']['lowLatencyMode']) {
|
|
3421
3584
|
if (config['streaming']['inaccurateManifestTolerance'] == undefined) {
|
|
3422
3585
|
config['streaming']['inaccurateManifestTolerance'] = 0;
|
|
@@ -3430,6 +3593,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3430
3593
|
if (config['streaming']['updateIntervalSeconds'] == undefined) {
|
|
3431
3594
|
config['streaming']['updateIntervalSeconds'] = 0.1;
|
|
3432
3595
|
}
|
|
3596
|
+
if (config['streaming']['maxDisabledTime'] == undefined) {
|
|
3597
|
+
config['streaming']['maxDisabledTime'] = 1;
|
|
3598
|
+
}
|
|
3433
3599
|
if (config['streaming']['retryParameters'] == undefined) {
|
|
3434
3600
|
config['streaming']['retryParameters'] = {};
|
|
3435
3601
|
}
|
|
@@ -3439,6 +3605,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3439
3605
|
if (config['manifest'] == undefined) {
|
|
3440
3606
|
config['manifest'] = {};
|
|
3441
3607
|
}
|
|
3608
|
+
if (config['manifest']['dash'] == undefined) {
|
|
3609
|
+
config['manifest']['dash'] = {};
|
|
3610
|
+
}
|
|
3611
|
+
if (config['manifest']['dash']['autoCorrectDrift'] == undefined) {
|
|
3612
|
+
config['manifest']['dash']['autoCorrectDrift'] = false;
|
|
3613
|
+
}
|
|
3442
3614
|
if (config['manifest']['retryParameters'] == undefined) {
|
|
3443
3615
|
config['manifest']['retryParameters'] = {};
|
|
3444
3616
|
}
|
|
@@ -3513,6 +3685,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3513
3685
|
}
|
|
3514
3686
|
}
|
|
3515
3687
|
if (this.networkingEngine_) {
|
|
3688
|
+
this.networkingEngine_.setForceHTTP(this.config_.streaming.forceHTTP);
|
|
3516
3689
|
this.networkingEngine_.setForceHTTPS(this.config_.streaming.forceHTTPS);
|
|
3517
3690
|
}
|
|
3518
3691
|
|
|
@@ -3600,6 +3773,24 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3600
3773
|
return ret;
|
|
3601
3774
|
}
|
|
3602
3775
|
|
|
3776
|
+
/**
|
|
3777
|
+
* Return a copy of the current non default configuration. Modifications of
|
|
3778
|
+
* the returned value will not affect the Player's active configuration.
|
|
3779
|
+
* You must call <code>player.configure()</code> to make changes.
|
|
3780
|
+
*
|
|
3781
|
+
* @return {!Object}
|
|
3782
|
+
* @export
|
|
3783
|
+
*/
|
|
3784
|
+
getNonDefaultConfiguration() {
|
|
3785
|
+
goog.asserts.assert(this.config_, 'Config must not be null!');
|
|
3786
|
+
|
|
3787
|
+
const ret = this.defaultConfig_();
|
|
3788
|
+
shaka.util.PlayerConfiguration.mergeConfigObjects(
|
|
3789
|
+
ret, this.config_, this.defaultConfig_());
|
|
3790
|
+
return shaka.util.ConfigUtils.getDifferenceFromConfigObjects(
|
|
3791
|
+
this.config_, this.defaultConfig_());
|
|
3792
|
+
}
|
|
3793
|
+
|
|
3603
3794
|
/**
|
|
3604
3795
|
* Return a reference to the current configuration. Modifications to the
|
|
3605
3796
|
* returned value will affect the Player's active configuration. This method
|
|
@@ -5734,6 +5925,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5734
5925
|
error.code == shaka.util.Error.Code.HTTP_ERROR) {
|
|
5735
5926
|
// These errors can be near-instant, so delay a bit before retrying.
|
|
5736
5927
|
retryDelaySeconds = 1;
|
|
5928
|
+
if (this.config_.streaming.lowLatencyMode) {
|
|
5929
|
+
retryDelaySeconds = 0.1;
|
|
5930
|
+
}
|
|
5737
5931
|
} else if (error.code == shaka.util.Error.Code.TIMEOUT) {
|
|
5738
5932
|
// We already waited for a timeout, so retry quickly.
|
|
5739
5933
|
retryDelaySeconds = 0.1;
|
|
@@ -6027,8 +6221,14 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6027
6221
|
// serviceDescription must override if it is defined in the MPD and
|
|
6028
6222
|
// liveSync configuration is not set.
|
|
6029
6223
|
if (this.manifest_ && this.manifest_.serviceDescription) {
|
|
6030
|
-
liveSyncMaxLatency = this.
|
|
6031
|
-
|
|
6224
|
+
liveSyncMaxLatency = this.config_.streaming.liveSyncMaxLatency;
|
|
6225
|
+
if (this.manifest_.serviceDescription.targetLatency != null) {
|
|
6226
|
+
liveSyncMaxLatency =
|
|
6227
|
+
this.manifest_.serviceDescription.targetLatency +
|
|
6228
|
+
this.config_.streaming.liveSyncTargetLatencyTolerance;
|
|
6229
|
+
} else if (this.manifest_.serviceDescription.maxLatency != null) {
|
|
6230
|
+
liveSyncMaxLatency = this.manifest_.serviceDescription.maxLatency;
|
|
6231
|
+
}
|
|
6032
6232
|
liveSyncPlaybackRate =
|
|
6033
6233
|
this.manifest_.serviceDescription.maxPlaybackRate ||
|
|
6034
6234
|
this.config_.streaming.liveSyncPlaybackRate;
|
|
@@ -6044,8 +6244,14 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6044
6244
|
// serviceDescription must override if it is defined in the MPD and
|
|
6045
6245
|
// liveSync configuration is not set.
|
|
6046
6246
|
if (this.manifest_ && this.manifest_.serviceDescription) {
|
|
6047
|
-
liveSyncMinLatency = this.
|
|
6048
|
-
|
|
6247
|
+
liveSyncMinLatency = this.config_.streaming.liveSyncMinLatency;
|
|
6248
|
+
if (this.manifest_.serviceDescription.targetLatency != null) {
|
|
6249
|
+
liveSyncMinLatency =
|
|
6250
|
+
this.manifest_.serviceDescription.targetLatency -
|
|
6251
|
+
this.config_.streaming.liveSyncTargetLatencyTolerance;
|
|
6252
|
+
} else if (this.manifest_.serviceDescription.minLatency != null) {
|
|
6253
|
+
liveSyncMinLatency = this.manifest_.serviceDescription.minLatency;
|
|
6254
|
+
}
|
|
6049
6255
|
liveSyncMinPlaybackRate =
|
|
6050
6256
|
this.manifest_.serviceDescription.minPlaybackRate ||
|
|
6051
6257
|
this.config_.streaming.liveSyncMinPlaybackRate;
|
|
@@ -7240,7 +7446,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
7240
7446
|
* @export
|
|
7241
7447
|
*/
|
|
7242
7448
|
// eslint-disable-next-line no-useless-concat
|
|
7243
|
-
shaka.Player.version = 'v4.
|
|
7449
|
+
shaka.Player.version = 'v4.9.1' + '-uncompiled'; // x-release-please-version
|
|
7244
7450
|
|
|
7245
7451
|
// Initialize the deprecation system using the version string we just set
|
|
7246
7452
|
// on the player.
|
|
@@ -8,6 +8,7 @@ goog.provide('shaka.polyfill.MediaCapabilities');
|
|
|
8
8
|
|
|
9
9
|
goog.require('shaka.log');
|
|
10
10
|
goog.require('shaka.media.Capabilities');
|
|
11
|
+
goog.require('shaka.media.DrmEngine');
|
|
11
12
|
goog.require('shaka.polyfill');
|
|
12
13
|
goog.require('shaka.util.Platform');
|
|
13
14
|
|
|
@@ -276,25 +277,22 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
276
277
|
mediaKeySystemConfig.videoCapabilities = videoCapabilities;
|
|
277
278
|
}
|
|
278
279
|
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
audioConfig ? audioConfig.contentType : '',
|
|
283
|
-
mcapKeySystemConfig.keySystem);
|
|
280
|
+
const videoCodec = videoConfig ? videoConfig.contentType : '';
|
|
281
|
+
const audioCodec = audioConfig ? audioConfig.contentType : '';
|
|
282
|
+
const keySystem = mcapKeySystemConfig.keySystem;
|
|
284
283
|
|
|
285
284
|
/** @type {MediaKeySystemAccess} */
|
|
286
285
|
let keySystemAccess = null;
|
|
287
286
|
try {
|
|
288
|
-
if (
|
|
289
|
-
|
|
290
|
-
keySystemAccess = shaka.
|
|
291
|
-
|
|
287
|
+
if (shaka.media.DrmEngine.hasMediaKeySystemAccess(
|
|
288
|
+
videoCodec, audioCodec, keySystem)) {
|
|
289
|
+
keySystemAccess = shaka.media.DrmEngine.getMediaKeySystemAccess(
|
|
290
|
+
videoCodec, audioCodec, keySystem);
|
|
292
291
|
} else {
|
|
293
292
|
keySystemAccess = await navigator.requestMediaKeySystemAccess(
|
|
294
293
|
mcapKeySystemConfig.keySystem, [mediaKeySystemConfig]);
|
|
295
|
-
shaka.
|
|
296
|
-
|
|
297
|
-
keySystemAccess;
|
|
294
|
+
shaka.media.DrmEngine.setMediaKeySystemAccess(
|
|
295
|
+
videoCodec, audioCodec, keySystem, keySystemAccess);
|
|
298
296
|
}
|
|
299
297
|
} catch (e) {
|
|
300
298
|
shaka.log.info('navigator.requestMediaKeySystemAccess failed.');
|
|
@@ -346,19 +344,6 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
346
344
|
}
|
|
347
345
|
return result;
|
|
348
346
|
}
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* A method for generating a key for the MediaKeySystemAccessRequests cache.
|
|
352
|
-
*
|
|
353
|
-
* @param {!string} videoCodec
|
|
354
|
-
* @param {!string} audioCodec
|
|
355
|
-
* @param {!string} keySystem
|
|
356
|
-
* @return {!string}
|
|
357
|
-
* @private
|
|
358
|
-
*/
|
|
359
|
-
static generateKeySystemCacheKey_(videoCodec, audioCodec, keySystem) {
|
|
360
|
-
return `${videoCodec}#${audioCodec}#${keySystem}`;
|
|
361
|
-
}
|
|
362
347
|
};
|
|
363
348
|
|
|
364
349
|
/**
|
|
@@ -371,16 +356,6 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
371
356
|
*/
|
|
372
357
|
shaka.polyfill.MediaCapabilities.originalMcap = null;
|
|
373
358
|
|
|
374
|
-
/**
|
|
375
|
-
* A cache that stores the MediaKeySystemAccess result of calling
|
|
376
|
-
* `navigator.requestMediaKeySystemAccess` by a key combination of
|
|
377
|
-
* video/audio codec and key system string.
|
|
378
|
-
*
|
|
379
|
-
* @type {(Object<(!string), (!MediaKeySystemAccess)>)}
|
|
380
|
-
* @export
|
|
381
|
-
*/
|
|
382
|
-
shaka.polyfill.MediaCapabilities.memoizedMediaKeySystemAccessRequests_ = {};
|
|
383
|
-
|
|
384
359
|
/**
|
|
385
360
|
* A cache that stores the canDisplayType result of calling
|
|
386
361
|
* `cast.__platform__.canDisplayType`.
|
|
@@ -141,7 +141,8 @@ shaka.transmuxer.AacTransmuxer = class {
|
|
|
141
141
|
return Promise.reject(new shaka.util.Error(
|
|
142
142
|
shaka.util.Error.Severity.CRITICAL,
|
|
143
143
|
shaka.util.Error.Category.MEDIA,
|
|
144
|
-
shaka.util.Error.Code.TRANSMUXING_FAILED
|
|
144
|
+
shaka.util.Error.Code.TRANSMUXING_FAILED,
|
|
145
|
+
reference ? reference.getUris()[0] : null));
|
|
145
146
|
}
|
|
146
147
|
stream.audioSamplingRate = info.sampleRate;
|
|
147
148
|
stream.channelsCount = info.channelCount;
|
|
@@ -155,7 +156,8 @@ shaka.transmuxer.AacTransmuxer = class {
|
|
|
155
156
|
return Promise.reject(new shaka.util.Error(
|
|
156
157
|
shaka.util.Error.Severity.CRITICAL,
|
|
157
158
|
shaka.util.Error.Category.MEDIA,
|
|
158
|
-
shaka.util.Error.Code.TRANSMUXING_FAILED
|
|
159
|
+
shaka.util.Error.Code.TRANSMUXING_FAILED,
|
|
160
|
+
reference ? reference.getUris()[0] : null));
|
|
159
161
|
}
|
|
160
162
|
const length = header.headerLength + header.frameLength;
|
|
161
163
|
if (offset + length <= uint8ArrayData.length) {
|
|
@@ -144,7 +144,8 @@ shaka.transmuxer.Ac3Transmuxer = class {
|
|
|
144
144
|
return Promise.reject(new shaka.util.Error(
|
|
145
145
|
shaka.util.Error.Severity.CRITICAL,
|
|
146
146
|
shaka.util.Error.Category.MEDIA,
|
|
147
|
-
shaka.util.Error.Code.TRANSMUXING_FAILED
|
|
147
|
+
shaka.util.Error.Code.TRANSMUXING_FAILED,
|
|
148
|
+
reference ? reference.getUris()[0] : null));
|
|
148
149
|
}
|
|
149
150
|
stream.audioSamplingRate = frame.sampleRate;
|
|
150
151
|
stream.channelsCount = frame.channelCount;
|