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.
Files changed (120) hide show
  1. package/AUTHORS +1 -0
  2. package/CONTRIBUTORS +1 -0
  3. package/LICENSE +54 -0
  4. package/README.md +22 -1
  5. package/dist/controls.css +1 -1
  6. package/dist/controls.css.map +1 -1
  7. package/dist/deps.js +36 -25
  8. package/dist/locales.js +40 -30
  9. package/dist/shaka-player.compiled.d.ts +196 -46
  10. package/dist/shaka-player.compiled.debug.d.ts +196 -46
  11. package/dist/shaka-player.compiled.debug.externs.js +474 -337
  12. package/dist/shaka-player.compiled.debug.js +992 -871
  13. package/dist/shaka-player.compiled.debug.map +4 -4
  14. package/dist/shaka-player.compiled.externs.js +474 -337
  15. package/dist/shaka-player.compiled.js +1248 -1174
  16. package/dist/shaka-player.compiled.map +4 -4
  17. package/dist/shaka-player.ui.d.ts +259 -49
  18. package/dist/shaka-player.ui.debug.d.ts +259 -49
  19. package/dist/shaka-player.ui.debug.externs.js +591 -376
  20. package/dist/shaka-player.ui.debug.js +1208 -1003
  21. package/dist/shaka-player.ui.debug.map +4 -4
  22. package/dist/shaka-player.ui.externs.js +591 -376
  23. package/dist/shaka-player.ui.js +1533 -1408
  24. package/dist/shaka-player.ui.map +4 -4
  25. package/externs/device_sensor_event.js +18 -0
  26. package/externs/hisense.js +16 -0
  27. package/externs/playstation.js +31 -0
  28. package/externs/shaka/abr_manager.js +3 -1
  29. package/externs/shaka/ads.js +5 -0
  30. package/externs/shaka/codecs.js +13 -0
  31. package/externs/shaka/manifest.js +69 -7
  32. package/externs/shaka/net.js +13 -1
  33. package/externs/shaka/offline.js +7 -1
  34. package/externs/shaka/player.js +184 -13
  35. package/externs/shaka/text.js +19 -0
  36. package/externs/tizen.js +41 -0
  37. package/externs/webos.js +19 -0
  38. package/externs/xbox.js +43 -0
  39. package/lib/abr/simple_abr_manager.js +9 -1
  40. package/lib/ads/ad_manager.js +19 -2
  41. package/lib/ads/client_side_ad_manager.js +5 -3
  42. package/lib/ads/media_tailor_ad_manager.js +9 -0
  43. package/lib/cast/cast_receiver.js +0 -14
  44. package/lib/cast/cast_utils.js +1 -0
  45. package/lib/cea/mp4_cea_parser.js +6 -1
  46. package/lib/dash/content_protection.js +97 -53
  47. package/lib/dash/dash_parser.js +240 -179
  48. package/lib/dash/mpd_utils.js +72 -65
  49. package/lib/dash/segment_base.js +35 -22
  50. package/lib/dash/segment_list.js +39 -31
  51. package/lib/dash/segment_template.js +47 -23
  52. package/lib/hls/hls_parser.js +376 -165
  53. package/lib/media/buffering_observer.js +25 -1
  54. package/lib/media/drm_engine.js +91 -71
  55. package/lib/media/manifest_filterer.js +220 -0
  56. package/lib/media/media_source_engine.js +108 -29
  57. package/lib/media/playhead.js +3 -3
  58. package/lib/media/preload_manager.js +827 -0
  59. package/lib/media/presentation_timeline.js +11 -0
  60. package/lib/media/segment_index.js +60 -49
  61. package/lib/media/segment_prefetch.js +140 -43
  62. package/lib/media/segment_reference.js +31 -8
  63. package/lib/media/segment_utils.js +208 -25
  64. package/lib/media/streaming_engine.js +321 -77
  65. package/lib/mss/content_protection.js +31 -25
  66. package/lib/mss/mss_parser.js +78 -55
  67. package/lib/net/networking_engine.js +49 -4
  68. package/lib/offline/indexeddb/v1_storage_cell.js +2 -0
  69. package/lib/offline/indexeddb/v2_storage_cell.js +2 -0
  70. package/lib/offline/manifest_converter.js +10 -3
  71. package/lib/offline/storage.js +5 -3
  72. package/lib/player.js +896 -674
  73. package/lib/polyfill/media_capabilities.js +16 -1
  74. package/lib/text/simple_text_displayer.js +9 -0
  75. package/lib/text/stub_text_displayer.js +7 -0
  76. package/lib/text/text_engine.js +16 -3
  77. package/lib/text/ttml_text_parser.js +116 -114
  78. package/lib/text/ui_text_displayer.js +28 -11
  79. package/lib/text/vtt_text_parser.js +54 -115
  80. package/lib/transmuxer/opus.js +91 -0
  81. package/lib/transmuxer/ts_transmuxer.js +115 -0
  82. package/lib/util/cmcd_manager.js +152 -3
  83. package/lib/util/dom_utils.js +11 -0
  84. package/lib/util/error.js +5 -0
  85. package/lib/util/fake_event.js +2 -0
  86. package/lib/util/manifest_parser_utils.js +97 -3
  87. package/lib/util/mime_utils.js +10 -5
  88. package/lib/util/mp4_box_parsers.js +346 -17
  89. package/lib/util/mp4_generator.js +23 -0
  90. package/lib/util/periods.js +24 -37
  91. package/lib/util/platform.js +161 -9
  92. package/lib/util/player_configuration.js +61 -3
  93. package/lib/util/stats.js +16 -0
  94. package/lib/util/stream_utils.js +350 -277
  95. package/lib/util/string_utils.js +36 -0
  96. package/lib/util/tXml.js +814 -0
  97. package/lib/util/ts_parser.js +50 -0
  98. package/lib/util/xml_utils.js +10 -338
  99. package/package.json +2 -2
  100. package/shaka-player.uncompiled.js +8 -0
  101. package/ui/controls.js +187 -5
  102. package/ui/enums.js +2 -0
  103. package/ui/externs/ui.js +30 -3
  104. package/ui/gl_matrix/matrix_4x4.js +568 -0
  105. package/ui/gl_matrix/matrix_quaternion.js +45 -0
  106. package/ui/less/containers.less +11 -0
  107. package/ui/locales/en-GB.json +2 -0
  108. package/ui/locales/en.json +2 -0
  109. package/ui/locales/es-419.json +2 -0
  110. package/ui/locales/es.json +2 -0
  111. package/ui/locales/source.json +8 -0
  112. package/ui/recenter_vr.js +126 -0
  113. package/ui/resolution_selection.js +25 -5
  114. package/ui/statistics_button.js +12 -0
  115. package/ui/text_selection.js +1 -1
  116. package/ui/toggle_stereoscopic.js +127 -0
  117. package/ui/ui.js +74 -38
  118. package/ui/vr_manager.js +557 -0
  119. package/ui/vr_utils.js +232 -0
  120. package/ui/vr_webgl.js +697 -0
@@ -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 codec of this stream to the output stream's codecs.
725
- const codecs = new Set(outputStream.codecs.split(','));
726
- for (const codec of match.codecs.split(',')) {
727
- if (codec) {
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
 
@@ -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: http://webostv.developer.lge.com/discover/specifications/web-engine/
153
- return shaka.util.Platform.userAgentContains_('Web0S') &&
154
- shaka.util.Platform.userAgentContains_(
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: http://webostv.developer.lge.com/discover/specifications/web-engine/
165
- return !!navigator.userAgent.match(/webOS\/4/i);
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 4.
170
+ * Check if the current platform is a WebOS 5.
170
171
  *
171
172
  * @return {boolean}
172
173
  */
173
174
  static isWebOS5() {
174
- // See: http://webostv.developer.lge.com/discover/specifications/web-engine/
175
- return !!navigator.userAgent.match(/webOS\/5/i);
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
- sourceBufferExtraFeatures: '',
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
  };