shaka-player 4.7.12 → 4.8.0
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/AUTHORS +1 -0
- package/CONTRIBUTORS +1 -0
- package/LICENSE +54 -0
- package/README.md +22 -1
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +36 -25
- package/dist/locales.js +40 -30
- package/dist/shaka-player.compiled.d.ts +196 -46
- package/dist/shaka-player.compiled.debug.d.ts +196 -46
- package/dist/shaka-player.compiled.debug.externs.js +474 -337
- package/dist/shaka-player.compiled.debug.js +992 -871
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +474 -337
- package/dist/shaka-player.compiled.js +1248 -1174
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +259 -49
- package/dist/shaka-player.ui.debug.d.ts +259 -49
- package/dist/shaka-player.ui.debug.externs.js +591 -376
- package/dist/shaka-player.ui.debug.js +1208 -1003
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +591 -376
- package/dist/shaka-player.ui.js +1533 -1408
- package/dist/shaka-player.ui.map +4 -4
- package/externs/device_sensor_event.js +18 -0
- package/externs/hisense.js +16 -0
- package/externs/playstation.js +31 -0
- package/externs/shaka/abr_manager.js +3 -1
- package/externs/shaka/ads.js +5 -0
- package/externs/shaka/codecs.js +13 -0
- package/externs/shaka/manifest.js +69 -7
- package/externs/shaka/net.js +13 -1
- package/externs/shaka/offline.js +7 -1
- package/externs/shaka/player.js +184 -13
- package/externs/shaka/text.js +19 -0
- package/externs/tizen.js +41 -0
- package/externs/webos.js +19 -0
- package/externs/xbox.js +43 -0
- package/lib/abr/simple_abr_manager.js +9 -1
- package/lib/ads/ad_manager.js +19 -2
- package/lib/ads/client_side_ad_manager.js +5 -3
- package/lib/ads/media_tailor_ad_manager.js +9 -0
- package/lib/cast/cast_receiver.js +0 -14
- package/lib/cast/cast_utils.js +1 -0
- package/lib/cea/mp4_cea_parser.js +6 -1
- package/lib/dash/content_protection.js +97 -53
- package/lib/dash/dash_parser.js +240 -179
- package/lib/dash/mpd_utils.js +72 -65
- package/lib/dash/segment_base.js +35 -22
- package/lib/dash/segment_list.js +39 -31
- package/lib/dash/segment_template.js +47 -23
- package/lib/hls/hls_parser.js +376 -165
- package/lib/media/buffering_observer.js +25 -1
- package/lib/media/drm_engine.js +91 -71
- package/lib/media/manifest_filterer.js +220 -0
- package/lib/media/media_source_engine.js +108 -29
- package/lib/media/playhead.js +3 -3
- package/lib/media/preload_manager.js +827 -0
- package/lib/media/presentation_timeline.js +11 -0
- package/lib/media/segment_index.js +60 -49
- package/lib/media/segment_prefetch.js +140 -43
- package/lib/media/segment_reference.js +31 -8
- package/lib/media/segment_utils.js +208 -25
- package/lib/media/streaming_engine.js +321 -77
- package/lib/mss/content_protection.js +31 -25
- package/lib/mss/mss_parser.js +78 -55
- package/lib/net/networking_engine.js +49 -4
- package/lib/offline/indexeddb/v1_storage_cell.js +2 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +2 -0
- package/lib/offline/manifest_converter.js +10 -3
- package/lib/offline/storage.js +5 -3
- package/lib/player.js +896 -674
- package/lib/polyfill/media_capabilities.js +16 -1
- package/lib/text/simple_text_displayer.js +9 -0
- package/lib/text/stub_text_displayer.js +7 -0
- package/lib/text/text_engine.js +16 -3
- package/lib/text/ttml_text_parser.js +116 -114
- package/lib/text/ui_text_displayer.js +28 -11
- package/lib/text/vtt_text_parser.js +54 -115
- package/lib/transmuxer/opus.js +91 -0
- package/lib/transmuxer/ts_transmuxer.js +115 -0
- package/lib/util/cmcd_manager.js +152 -3
- package/lib/util/dom_utils.js +11 -0
- package/lib/util/error.js +5 -0
- package/lib/util/fake_event.js +2 -0
- package/lib/util/manifest_parser_utils.js +97 -3
- package/lib/util/mime_utils.js +10 -5
- package/lib/util/mp4_box_parsers.js +346 -17
- package/lib/util/mp4_generator.js +23 -0
- package/lib/util/periods.js +24 -37
- package/lib/util/platform.js +161 -9
- package/lib/util/player_configuration.js +61 -3
- package/lib/util/stats.js +16 -0
- package/lib/util/stream_utils.js +350 -277
- package/lib/util/string_utils.js +36 -0
- package/lib/util/tXml.js +814 -0
- package/lib/util/ts_parser.js +50 -0
- package/lib/util/xml_utils.js +10 -338
- package/package.json +2 -2
- package/shaka-player.uncompiled.js +8 -0
- package/ui/controls.js +187 -5
- package/ui/enums.js +2 -0
- package/ui/externs/ui.js +30 -3
- package/ui/gl_matrix/matrix_4x4.js +568 -0
- package/ui/gl_matrix/matrix_quaternion.js +45 -0
- package/ui/less/containers.less +11 -0
- package/ui/locales/en-GB.json +2 -0
- package/ui/locales/en.json +2 -0
- package/ui/locales/es-419.json +2 -0
- package/ui/locales/es.json +2 -0
- package/ui/locales/source.json +8 -0
- package/ui/recenter_vr.js +126 -0
- package/ui/resolution_selection.js +25 -5
- package/ui/statistics_button.js +12 -0
- package/ui/text_selection.js +1 -1
- package/ui/toggle_stereoscopic.js +127 -0
- package/ui/ui.js +74 -38
- package/ui/vr_manager.js +557 -0
- package/ui/vr_utils.js +232 -0
- package/ui/vr_webgl.js +697 -0
package/lib/util/periods.js
CHANGED
|
@@ -45,6 +45,9 @@ shaka.util.PeriodCombiner = class {
|
|
|
45
45
|
/** @private {boolean} */
|
|
46
46
|
this.multiTypeVariantsAllowed_ = false;
|
|
47
47
|
|
|
48
|
+
/** @private {boolean} */
|
|
49
|
+
this.useStreamOnce_ = false;
|
|
50
|
+
|
|
48
51
|
/**
|
|
49
52
|
* The IDs of the periods we have already used to generate streams.
|
|
50
53
|
* This helps us identify the periods which have been added when a live
|
|
@@ -599,14 +602,6 @@ shaka.util.PeriodCombiner = class {
|
|
|
599
602
|
goog.asserts.assert(match.segmentIndex,
|
|
600
603
|
'stream should have a segmentIndex.');
|
|
601
604
|
if (match.segmentIndex) {
|
|
602
|
-
match.segmentIndex.forEachTopLevelReference((ref) => {
|
|
603
|
-
ref.codecs = match.codecs;
|
|
604
|
-
ref.mimeType = match.mimeType;
|
|
605
|
-
if (ref.initSegmentReference) {
|
|
606
|
-
ref.initSegmentReference.codecs = match.codecs;
|
|
607
|
-
ref.initSegmentReference.mimeType = match.mimeType;
|
|
608
|
-
}
|
|
609
|
-
});
|
|
610
605
|
outputStream.segmentIndex.appendSegmentIndex(match.segmentIndex);
|
|
611
606
|
}
|
|
612
607
|
}
|
|
@@ -721,41 +716,16 @@ shaka.util.PeriodCombiner = class {
|
|
|
721
716
|
|
|
722
717
|
if (used) {
|
|
723
718
|
unusedStreamsPerPeriod[i].delete(match);
|
|
724
|
-
// Add the
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
codecs.add(codec);
|
|
719
|
+
// Add the full mimetypes to the stream.
|
|
720
|
+
if (match.fullMimeTypes) {
|
|
721
|
+
for (const fullMimeType of match.fullMimeTypes.values()) {
|
|
722
|
+
outputStream.fullMimeTypes.add(fullMimeType);
|
|
729
723
|
}
|
|
730
724
|
}
|
|
731
|
-
const PeriodCombiner = shaka.util.PeriodCombiner;
|
|
732
|
-
outputStream.codecs = PeriodCombiner.filterDuplicateCodecs_(
|
|
733
|
-
Array.from(codecs)).join(',');
|
|
734
725
|
}
|
|
735
726
|
}
|
|
736
727
|
}
|
|
737
728
|
|
|
738
|
-
/**
|
|
739
|
-
* @param {!Array.<string>} codecs
|
|
740
|
-
* @return {!Array.<string>} codecs
|
|
741
|
-
* @private
|
|
742
|
-
*/
|
|
743
|
-
static filterDuplicateCodecs_(codecs) {
|
|
744
|
-
// Filter out duplicate codecs.
|
|
745
|
-
const seen = new Set();
|
|
746
|
-
const ret = [];
|
|
747
|
-
for (const codec of codecs) {
|
|
748
|
-
const shortCodec = shaka.util.MimeUtils.getCodecBase(codec);
|
|
749
|
-
if (!seen.has(shortCodec)) {
|
|
750
|
-
ret.push(codec);
|
|
751
|
-
seen.add(shortCodec);
|
|
752
|
-
} else {
|
|
753
|
-
shaka.log.debug('Ignoring duplicate codec');
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
return ret;
|
|
757
|
-
}
|
|
758
|
-
|
|
759
729
|
/**
|
|
760
730
|
* Clone a Stream to make an output Stream for combining others across
|
|
761
731
|
* periods.
|
|
@@ -1041,6 +1011,12 @@ shaka.util.PeriodCombiner = class {
|
|
|
1041
1011
|
}
|
|
1042
1012
|
}
|
|
1043
1013
|
|
|
1014
|
+
// Remove just found stream if configured to, so possible future linear
|
|
1015
|
+
// searches can be faster.
|
|
1016
|
+
if (this.useStreamOnce_ && !shaka.util.PeriodCombiner.isDummy_(best)) {
|
|
1017
|
+
streams.delete(getKey(best));
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1044
1020
|
return best;
|
|
1045
1021
|
}
|
|
1046
1022
|
|
|
@@ -1075,11 +1051,21 @@ shaka.util.PeriodCombiner = class {
|
|
|
1075
1051
|
/**
|
|
1076
1052
|
* @param {boolean} allowed If set to true, multi-mimeType or multi-codec
|
|
1077
1053
|
* variants will be allowed.
|
|
1054
|
+
* @export
|
|
1078
1055
|
*/
|
|
1079
1056
|
setAllowMultiTypeVariants(allowed) {
|
|
1080
1057
|
this.multiTypeVariantsAllowed_ = allowed;
|
|
1081
1058
|
}
|
|
1082
1059
|
|
|
1060
|
+
/**
|
|
1061
|
+
* @param {boolean} useOnce if true, stream will be used only once in period
|
|
1062
|
+
* flattening algoritnm.
|
|
1063
|
+
* @export
|
|
1064
|
+
*/
|
|
1065
|
+
setUseStreamOnce(useOnce) {
|
|
1066
|
+
this.useStreamOnce_ = useOnce;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1083
1069
|
/**
|
|
1084
1070
|
* @param {T} outputStream An audio or video output stream
|
|
1085
1071
|
* @param {T} candidate A candidate stream to be combined with the output
|
|
@@ -1578,6 +1564,7 @@ shaka.util.PeriodCombiner = class {
|
|
|
1578
1564
|
accessibilityPurpose: null,
|
|
1579
1565
|
external: false,
|
|
1580
1566
|
fastSwitching: false,
|
|
1567
|
+
fullMimeTypes: new Set(),
|
|
1581
1568
|
};
|
|
1582
1569
|
}
|
|
1583
1570
|
|
package/lib/util/platform.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.util.Platform');
|
|
8
8
|
|
|
9
|
+
goog.require('shaka.log');
|
|
9
10
|
goog.require('shaka.util.Timer');
|
|
10
11
|
|
|
11
12
|
|
|
@@ -149,10 +150,9 @@ shaka.util.Platform = class {
|
|
|
149
150
|
* @return {boolean}
|
|
150
151
|
*/
|
|
151
152
|
static isWebOS3() {
|
|
152
|
-
// See:
|
|
153
|
-
return shaka.util.Platform.
|
|
154
|
-
shaka.util.Platform.
|
|
155
|
-
'Chrome/38.0.2125.122 Safari/537.36');
|
|
153
|
+
// See: https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine#useragent-string
|
|
154
|
+
return shaka.util.Platform.isWebOS() &&
|
|
155
|
+
shaka.util.Platform.chromeVersion() === 38;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
/**
|
|
@@ -161,18 +161,20 @@ shaka.util.Platform = class {
|
|
|
161
161
|
* @return {boolean}
|
|
162
162
|
*/
|
|
163
163
|
static isWebOS4() {
|
|
164
|
-
// See:
|
|
165
|
-
return
|
|
164
|
+
// See: https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine#useragent-string
|
|
165
|
+
return shaka.util.Platform.isWebOS() &&
|
|
166
|
+
shaka.util.Platform.chromeVersion() === 53;
|
|
166
167
|
}
|
|
167
168
|
|
|
168
169
|
/**
|
|
169
|
-
* Check if the current platform is a WebOS
|
|
170
|
+
* Check if the current platform is a WebOS 5.
|
|
170
171
|
*
|
|
171
172
|
* @return {boolean}
|
|
172
173
|
*/
|
|
173
174
|
static isWebOS5() {
|
|
174
|
-
// See:
|
|
175
|
-
return
|
|
175
|
+
// See: https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine#useragent-string
|
|
176
|
+
return shaka.util.Platform.isWebOS() &&
|
|
177
|
+
shaka.util.Platform.chromeVersion() === 68;
|
|
176
178
|
}
|
|
177
179
|
|
|
178
180
|
/**
|
|
@@ -440,6 +442,25 @@ shaka.util.Platform = class {
|
|
|
440
442
|
return shaka.util.Platform.userAgentContains_('Android');
|
|
441
443
|
}
|
|
442
444
|
|
|
445
|
+
/**
|
|
446
|
+
* Return true if the platform is controlled by a remote control.
|
|
447
|
+
*
|
|
448
|
+
* @return {boolean}
|
|
449
|
+
*/
|
|
450
|
+
static isSmartTV() {
|
|
451
|
+
const Platform = shaka.util.Platform;
|
|
452
|
+
if (Platform.isTizen() || Platform.isWebOS() ||
|
|
453
|
+
Platform.isXboxOne() || Platform.isPS4() ||
|
|
454
|
+
Platform.isPS5() || Platform.isAmazonFireTV() ||
|
|
455
|
+
Platform.isEOS() || Platform.isAPL() ||
|
|
456
|
+
Platform.isVirginMedia() || Platform.isOrange() ||
|
|
457
|
+
Platform.isWPE() || Platform.isChromecast() ||
|
|
458
|
+
Platform.isHisense()) {
|
|
459
|
+
return true;
|
|
460
|
+
}
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
|
|
443
464
|
/**
|
|
444
465
|
* Check if the user agent contains a key. This is the best way we know of
|
|
445
466
|
* right now to detect platforms. If there is a better way, please send a
|
|
@@ -554,6 +575,137 @@ shaka.util.Platform = class {
|
|
|
554
575
|
|
|
555
576
|
return false;
|
|
556
577
|
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Detect the maximum resolution that the platform's hardware can handle.
|
|
581
|
+
*
|
|
582
|
+
* @return {!Promise.<{width: number, height: number}>}
|
|
583
|
+
*/
|
|
584
|
+
static async detectMaxHardwareResolution() {
|
|
585
|
+
const Platform = shaka.util.Platform;
|
|
586
|
+
const maxResolution = {
|
|
587
|
+
width: Infinity,
|
|
588
|
+
height: Infinity,
|
|
589
|
+
};
|
|
590
|
+
|
|
591
|
+
if (Platform.isChromecast()) {
|
|
592
|
+
// In our tests, the original Chromecast seems to have trouble decoding
|
|
593
|
+
// above 1080p. It would be a waste to select a higher res anyway, given
|
|
594
|
+
// that the device only outputs 1080p to begin with.
|
|
595
|
+
// Chromecast has an extension to query the device/display's resolution.
|
|
596
|
+
if (window.cast && cast.__platform__ &&
|
|
597
|
+
cast.__platform__.canDisplayType && cast.__platform__.canDisplayType(
|
|
598
|
+
'video/mp4; codecs="avc1.640028"; width=3840; height=2160')) {
|
|
599
|
+
// The device and display can both do 4k. Assume a 4k limit.
|
|
600
|
+
maxResolution.width = 3840;
|
|
601
|
+
maxResolution.height = 2160;
|
|
602
|
+
} else {
|
|
603
|
+
// Chromecast has always been able to do 1080p. Assume a 1080p limit.
|
|
604
|
+
maxResolution.width = 1920;
|
|
605
|
+
maxResolution.height = 1080;
|
|
606
|
+
}
|
|
607
|
+
} else if (Platform.isTizen()) {
|
|
608
|
+
maxResolution.width = 1920;
|
|
609
|
+
maxResolution.height = 1080;
|
|
610
|
+
try {
|
|
611
|
+
if (webapis.systeminfo && webapis.systeminfo.getMaxVideoResolution) {
|
|
612
|
+
const maxVideoResolution =
|
|
613
|
+
webapis.systeminfo.getMaxVideoResolution();
|
|
614
|
+
maxResolution.width = maxVideoResolution.width;
|
|
615
|
+
maxResolution.height = maxVideoResolution.height;
|
|
616
|
+
} else {
|
|
617
|
+
if (webapis.productinfo.is8KPanelSupported &&
|
|
618
|
+
webapis.productinfo.is8KPanelSupported()) {
|
|
619
|
+
maxResolution.width = 7680;
|
|
620
|
+
maxResolution.height = 4320;
|
|
621
|
+
} else if (webapis.productinfo.isUdPanelSupported &&
|
|
622
|
+
webapis.productinfo.isUdPanelSupported()) {
|
|
623
|
+
maxResolution.width = 3840;
|
|
624
|
+
maxResolution.height = 2160;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
} catch (e) {
|
|
628
|
+
shaka.log.alwaysWarn('Tizen: Error detecting screen size, default ' +
|
|
629
|
+
'screen size 1920x1080.');
|
|
630
|
+
}
|
|
631
|
+
} else if (Platform.isXboxOne()) {
|
|
632
|
+
const protectionCapabilities =
|
|
633
|
+
new Windows.Media.Protection.ProtectionCapabilities();
|
|
634
|
+
const protectionResult =
|
|
635
|
+
Windows.Media.Protection.ProtectionCapabilityResult;
|
|
636
|
+
// isTypeSupported may return "maybe", which means the operation is not
|
|
637
|
+
// completed. This means we need to retry
|
|
638
|
+
// https://learn.microsoft.com/en-us/uwp/api/windows.media.protection.protectioncapabilityresult?view=winrt-22621
|
|
639
|
+
let result = null;
|
|
640
|
+
try {
|
|
641
|
+
const type =
|
|
642
|
+
'video/mp4;codecs="hvc1,mp4a";features="decode-res-x=3840,' +
|
|
643
|
+
'decode-res-y=2160,decode-bitrate=20000,decode-fps=30,' +
|
|
644
|
+
'decode-bpc=10,display-res-x=3840,display-res-y=2160,' +
|
|
645
|
+
'display-bpc=8"';
|
|
646
|
+
const keySystem = 'com.microsoft.playready.recommendation';
|
|
647
|
+
do {
|
|
648
|
+
result = protectionCapabilities.isTypeSupported(type, keySystem);
|
|
649
|
+
} while (result === protectionResult.maybe);
|
|
650
|
+
} catch (e) {
|
|
651
|
+
result = protectionResult.notSupported;
|
|
652
|
+
}
|
|
653
|
+
if (result === protectionResult.probably) {
|
|
654
|
+
maxResolution.width = 3840;
|
|
655
|
+
maxResolution.height = 2160;
|
|
656
|
+
} else {
|
|
657
|
+
maxResolution.width = 1920;
|
|
658
|
+
maxResolution.height = 1080;
|
|
659
|
+
}
|
|
660
|
+
} else if (Platform.isWebOS()) {
|
|
661
|
+
try {
|
|
662
|
+
const deviceInfo =
|
|
663
|
+
/** @type {{screenWidth: number, screenHeight: number}} */(
|
|
664
|
+
JSON.parse(window.PalmSystem.deviceInfo));
|
|
665
|
+
// WebOS has always been able to do 1080p. Assume a 1080p limit.
|
|
666
|
+
maxResolution.width = Math.max(1920, deviceInfo.screenWidth);
|
|
667
|
+
maxResolution.height = Math.max(1080, deviceInfo.screenHeight);
|
|
668
|
+
} catch (e) {
|
|
669
|
+
shaka.log.alwaysWarn('WebOS: Error detecting screen size, default ' +
|
|
670
|
+
'screen size 1920x1080.');
|
|
671
|
+
maxResolution.width = 1920;
|
|
672
|
+
maxResolution.height = 1080;
|
|
673
|
+
}
|
|
674
|
+
} else if (Platform.isHisense()) {
|
|
675
|
+
// eslint-disable-next-line new-cap
|
|
676
|
+
if (window.Hisense_Get4KSupportState &&
|
|
677
|
+
// eslint-disable-next-line new-cap
|
|
678
|
+
window.Hisense_Get4KSupportState()) {
|
|
679
|
+
maxResolution.width = 3840;
|
|
680
|
+
maxResolution.height = 2160;
|
|
681
|
+
} else {
|
|
682
|
+
maxResolution.width = 1920;
|
|
683
|
+
maxResolution.height = 1080;
|
|
684
|
+
}
|
|
685
|
+
} else if (Platform.isPS4() || Platform.isPS5()) {
|
|
686
|
+
let supports4K = false;
|
|
687
|
+
try {
|
|
688
|
+
const result = await window.msdk.device.getDisplayInfo();
|
|
689
|
+
supports4K = result.resolution === '4K';
|
|
690
|
+
} catch (e) {
|
|
691
|
+
try {
|
|
692
|
+
const result = await window.msdk.device.getDisplayInfoImmediate();
|
|
693
|
+
supports4K = result.resolution === '4K';
|
|
694
|
+
} catch (e) {
|
|
695
|
+
shaka.log.alwaysWarn(
|
|
696
|
+
'PlayStation: Failed to get the display info:', e);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
if (supports4K) {
|
|
700
|
+
maxResolution.width = 3840;
|
|
701
|
+
maxResolution.height = 2160;
|
|
702
|
+
} else {
|
|
703
|
+
maxResolution.width = 1920;
|
|
704
|
+
maxResolution.height = 1080;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
return maxResolution;
|
|
708
|
+
}
|
|
557
709
|
};
|
|
558
710
|
|
|
559
711
|
/** @private {shaka.util.Timer} */
|
|
@@ -94,6 +94,13 @@ shaka.util.PlayerConfiguration = class {
|
|
|
94
94
|
ignoreDuplicateInitData: !shaka.util.Platform.isTizen2(),
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
+
// The Xbox One and PS4 only support the Playready DRM, so they should
|
|
98
|
+
// prefer that key system by default to improve startup performance.
|
|
99
|
+
if (shaka.util.Platform.isXboxOne() ||
|
|
100
|
+
shaka.util.Platform.isPS4()) {
|
|
101
|
+
drm.preferredKeySystems.push('com.microsoft.playready');
|
|
102
|
+
}
|
|
103
|
+
|
|
97
104
|
let codecSwitchingStrategy = shaka.config.CodecSwitchingStrategy.RELOAD;
|
|
98
105
|
let multiTypeVariantsAllowed = false;
|
|
99
106
|
if (shaka.util.Platform.supportsSmoothCodecSwitching()) {
|
|
@@ -133,17 +140,22 @@ shaka.util.PlayerConfiguration = class {
|
|
|
133
140
|
'com.microsoft.playready',
|
|
134
141
|
'urn:uuid:79f0049a-4098-8642-ab92-e65be0885f95':
|
|
135
142
|
'com.microsoft.playready',
|
|
136
|
-
'urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb':
|
|
137
|
-
'com.adobe.primetime',
|
|
138
143
|
},
|
|
139
144
|
manifestPreprocessor: (element) => {
|
|
140
145
|
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
141
146
|
[element],
|
|
142
147
|
element);
|
|
143
148
|
},
|
|
149
|
+
manifestPreprocessorTXml: (element) => {
|
|
150
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
151
|
+
[element],
|
|
152
|
+
element);
|
|
153
|
+
},
|
|
144
154
|
sequenceMode: false,
|
|
145
155
|
enableAudioGroups: false,
|
|
146
156
|
multiTypeVariantsAllowed,
|
|
157
|
+
useStreamOnceInPeriodFlattening: false,
|
|
158
|
+
updatePeriod: -1,
|
|
147
159
|
},
|
|
148
160
|
hls: {
|
|
149
161
|
ignoreTextStreamFailures: false,
|
|
@@ -151,6 +163,7 @@ shaka.util.PlayerConfiguration = class {
|
|
|
151
163
|
defaultAudioCodec: 'mp4a.40.2',
|
|
152
164
|
defaultVideoCodec: 'avc1.42E01E',
|
|
153
165
|
ignoreManifestProgramDateTime: false,
|
|
166
|
+
ignoreManifestProgramDateTimeForTypes: [],
|
|
154
167
|
mediaPlaylistFullMimeType:
|
|
155
168
|
'video/mp2t; codecs="avc1.42E01E, mp4a.40.2"',
|
|
156
169
|
useSafariBehaviorForLive: true,
|
|
@@ -166,6 +179,11 @@ shaka.util.PlayerConfiguration = class {
|
|
|
166
179
|
[element],
|
|
167
180
|
element);
|
|
168
181
|
},
|
|
182
|
+
manifestPreprocessorTXml: (element) => {
|
|
183
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
184
|
+
[element],
|
|
185
|
+
element);
|
|
186
|
+
},
|
|
169
187
|
sequenceMode: false,
|
|
170
188
|
keySystemsBySystemId: {
|
|
171
189
|
'9a04f079-9840-4286-ab92-e65be0885f95':
|
|
@@ -192,6 +210,7 @@ shaka.util.PlayerConfiguration = class {
|
|
|
192
210
|
rebufferingGoal: 2,
|
|
193
211
|
bufferingGoal: 10,
|
|
194
212
|
bufferBehind: 30,
|
|
213
|
+
evictionGoal: 1,
|
|
195
214
|
ignoreTextStreamFailures: false,
|
|
196
215
|
alwaysStreamText: false,
|
|
197
216
|
startAtSegmentBoundary: false,
|
|
@@ -205,6 +224,7 @@ shaka.util.PlayerConfiguration = class {
|
|
|
205
224
|
stallThreshold: 1 /* seconds */,
|
|
206
225
|
stallSkip: 0.1 /* seconds */,
|
|
207
226
|
useNativeHlsOnSafari: true,
|
|
227
|
+
useNativeHlsForFairPlay: true,
|
|
208
228
|
// If we are within 2 seconds of the start of a live segment, fetch the
|
|
209
229
|
// previous one. This allows for segment drift, but won't download an
|
|
210
230
|
// extra segment if we aren't close to the start.
|
|
@@ -223,13 +243,23 @@ shaka.util.PlayerConfiguration = class {
|
|
|
223
243
|
// When low latency streaming is enabled, segmentPrefetchLimit will
|
|
224
244
|
// default to 2 if not specified.
|
|
225
245
|
segmentPrefetchLimit: 0,
|
|
246
|
+
prefetchAudioLanguages: [],
|
|
247
|
+
disableAudioPrefetch: false,
|
|
248
|
+
disableTextPrefetch: false,
|
|
249
|
+
disableVideoPrefetch: false,
|
|
226
250
|
liveSync: false,
|
|
227
251
|
liveSyncMaxLatency: 1,
|
|
228
252
|
liveSyncPlaybackRate: 1.1,
|
|
229
253
|
liveSyncMinLatency: 0,
|
|
230
254
|
liveSyncMinPlaybackRate: 1,
|
|
255
|
+
liveSyncPanicMode: false,
|
|
256
|
+
liveSyncPanicThreshold: 60,
|
|
231
257
|
allowMediaSourceRecoveries: true,
|
|
232
258
|
minTimeBetweenRecoveries: 5,
|
|
259
|
+
vodDynamicPlaybackRate: false,
|
|
260
|
+
vodDynamicPlaybackRateLowBufferRate: 0.95,
|
|
261
|
+
vodDynamicPlaybackRateBufferRatio: 0.5,
|
|
262
|
+
infiniteLiveStreamDuration: false,
|
|
233
263
|
};
|
|
234
264
|
|
|
235
265
|
// WebOS, Tizen, Chromecast and Hisense have long hardware pipelines
|
|
@@ -316,7 +346,9 @@ shaka.util.PlayerConfiguration = class {
|
|
|
316
346
|
enabled: false,
|
|
317
347
|
sessionId: '',
|
|
318
348
|
contentId: '',
|
|
349
|
+
rtpSafetyFactor: 5,
|
|
319
350
|
useHeaders: false,
|
|
351
|
+
includeKeys: [],
|
|
320
352
|
};
|
|
321
353
|
|
|
322
354
|
const cmsd = {
|
|
@@ -334,13 +366,38 @@ shaka.util.PlayerConfiguration = class {
|
|
|
334
366
|
|
|
335
367
|
const mediaSource = {
|
|
336
368
|
codecSwitchingStrategy: codecSwitchingStrategy,
|
|
337
|
-
|
|
369
|
+
addExtraFeaturesToSourceBuffer: (mimeType) => {
|
|
370
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
371
|
+
[mimeType],
|
|
372
|
+
'');
|
|
373
|
+
},
|
|
338
374
|
forceTransmux: false,
|
|
339
375
|
insertFakeEncryptionInInit: true,
|
|
376
|
+
modifyCueCallback: (cue, uri) => {
|
|
377
|
+
return shaka.util.ConfigUtils.referenceParametersAndReturn(
|
|
378
|
+
[cue, uri],
|
|
379
|
+
undefined);
|
|
380
|
+
},
|
|
340
381
|
};
|
|
341
382
|
|
|
383
|
+
let skipPlayDetection = false;
|
|
384
|
+
if (shaka.util.Platform.isWebOS() ||
|
|
385
|
+
shaka.util.Platform.isTizen() ||
|
|
386
|
+
shaka.util.Platform.isChromecast() ||
|
|
387
|
+
shaka.util.Platform.isHisense() ||
|
|
388
|
+
shaka.util.Platform.isPS5() ||
|
|
389
|
+
shaka.util.Platform.isPS4() ||
|
|
390
|
+
shaka.util.Platform.isXboxOne()) {
|
|
391
|
+
skipPlayDetection = true;
|
|
392
|
+
}
|
|
393
|
+
|
|
342
394
|
const ads = {
|
|
343
395
|
customPlayheadTracker: false,
|
|
396
|
+
skipPlayDetection,
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const textDisplayer = {
|
|
400
|
+
captionsUpdatePeriod: 0.25,
|
|
344
401
|
};
|
|
345
402
|
|
|
346
403
|
const AutoShowText = shaka.config.AutoShowText;
|
|
@@ -383,6 +440,7 @@ shaka.util.PlayerConfiguration = class {
|
|
|
383
440
|
},
|
|
384
441
|
playRangeStart: 0,
|
|
385
442
|
playRangeEnd: Infinity,
|
|
443
|
+
textDisplayer: textDisplayer,
|
|
386
444
|
textDisplayFactory: () => null,
|
|
387
445
|
cmcd: cmcd,
|
|
388
446
|
cmsd: cmsd,
|
package/lib/util/stats.js
CHANGED
|
@@ -62,6 +62,9 @@ shaka.util.Stats = class {
|
|
|
62
62
|
/** @private {number} */
|
|
63
63
|
this.bandwidthEstimate_ = NaN;
|
|
64
64
|
|
|
65
|
+
/** @private {number} */
|
|
66
|
+
this.bytesDownloaded_ = NaN;
|
|
67
|
+
|
|
65
68
|
/** @private {!shaka.util.StateHistory} */
|
|
66
69
|
this.stateHistory_ = new shaka.util.StateHistory();
|
|
67
70
|
|
|
@@ -203,6 +206,17 @@ shaka.util.Stats = class {
|
|
|
203
206
|
this.bandwidthEstimate_ = bandwidth;
|
|
204
207
|
}
|
|
205
208
|
|
|
209
|
+
/**
|
|
210
|
+
* @param {number} bytesDownloaded
|
|
211
|
+
*/
|
|
212
|
+
addBytesDownloaded(bytesDownloaded) {
|
|
213
|
+
if (isNaN(this.bytesDownloaded_)) {
|
|
214
|
+
this.bytesDownloaded_ = bytesDownloaded;
|
|
215
|
+
} else {
|
|
216
|
+
this.bytesDownloaded_ += bytesDownloaded;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
206
220
|
/**
|
|
207
221
|
* @return {!shaka.util.StateHistory}
|
|
208
222
|
*/
|
|
@@ -244,6 +258,7 @@ shaka.util.Stats = class {
|
|
|
244
258
|
licenseTime: this.licenseTimeSeconds_,
|
|
245
259
|
liveLatency: this.liveLatencySeconds_,
|
|
246
260
|
maxSegmentDuration: this.maxSegmentDurationSeconds_,
|
|
261
|
+
bytesDownloaded: this.bytesDownloaded_,
|
|
247
262
|
stateHistory: this.stateHistory_.getCopy(),
|
|
248
263
|
switchHistory: this.switchHistory_.getCopy(),
|
|
249
264
|
};
|
|
@@ -276,6 +291,7 @@ shaka.util.Stats = class {
|
|
|
276
291
|
licenseTime: NaN,
|
|
277
292
|
liveLatency: NaN,
|
|
278
293
|
maxSegmentDuration: NaN,
|
|
294
|
+
bytesDownloaded: NaN,
|
|
279
295
|
switchHistory: [],
|
|
280
296
|
stateHistory: [],
|
|
281
297
|
};
|