shaka-player 4.10.0 → 4.10.2

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 (40) hide show
  1. package/dist/deps.js +9 -9
  2. package/dist/locales.js +36 -36
  3. package/dist/shaka-player.compiled.d.ts +2 -2
  4. package/dist/shaka-player.compiled.debug.d.ts +2 -2
  5. package/dist/shaka-player.compiled.debug.externs.js +1 -1
  6. package/dist/shaka-player.compiled.debug.js +140 -139
  7. package/dist/shaka-player.compiled.debug.map +4 -4
  8. package/dist/shaka-player.compiled.externs.js +1 -1
  9. package/dist/shaka-player.compiled.js +1169 -1163
  10. package/dist/shaka-player.compiled.map +4 -4
  11. package/dist/shaka-player.ui.d.ts +2 -2
  12. package/dist/shaka-player.ui.debug.d.ts +2 -2
  13. package/dist/shaka-player.ui.debug.externs.js +1 -1
  14. package/dist/shaka-player.ui.debug.js +167 -165
  15. package/dist/shaka-player.ui.debug.map +4 -4
  16. package/dist/shaka-player.ui.externs.js +1 -1
  17. package/dist/shaka-player.ui.js +1396 -1391
  18. package/dist/shaka-player.ui.map +4 -4
  19. package/externs/shaka/player.js +7 -1
  20. package/lib/abr/simple_abr_manager.js +11 -8
  21. package/lib/hls/hls_parser.js +7 -6
  22. package/lib/media/drm_engine.js +9 -197
  23. package/lib/media/presentation_timeline.js +13 -5
  24. package/lib/player.js +20 -12
  25. package/lib/polyfill/media_capabilities.js +4 -4
  26. package/lib/polyfill/patchedmediakeys_apple.js +3 -3
  27. package/lib/polyfill/patchedmediakeys_webkit.js +3 -3
  28. package/lib/text/simple_text_displayer.js +3 -0
  29. package/lib/text/ssa_text_parser.js +22 -7
  30. package/lib/text/text_utils.js +17 -1
  31. package/lib/text/ttml_text_parser.js +5 -3
  32. package/lib/text/ui_text_displayer.js +6 -1
  33. package/lib/util/config_utils.js +5 -0
  34. package/lib/util/drm_utils.js +191 -0
  35. package/lib/util/periods.js +4 -4
  36. package/lib/util/player_configuration.js +1 -0
  37. package/lib/util/ts_parser.js +4 -4
  38. package/package.json +1 -1
  39. package/ui/locales/fr.json +1 -1
  40. package/ui/statistics_button.js +10 -3
@@ -630,7 +630,9 @@ shaka.text.TtmlTextParser = class {
630
630
  cue.fontFamily = 'serif';
631
631
  break;
632
632
  default:
633
- cue.fontFamily = fontFamily;
633
+ cue.fontFamily = fontFamily.split(',').filter((font) => {
634
+ return font != 'default';
635
+ }).join(',');
634
636
  break;
635
637
  }
636
638
  }
@@ -1300,9 +1302,9 @@ shaka.text.TtmlTextParser.percentValues_ =
1300
1302
  /**
1301
1303
  * @const
1302
1304
  * @private {!RegExp}
1303
- * @example 0.6% 90%
1305
+ * @example 0.6% 90% 300% 1000%
1304
1306
  */
1305
- shaka.text.TtmlTextParser.percentValue_ = /^(\d{1,2}(?:\.\d+)?|100)%$/;
1307
+ shaka.text.TtmlTextParser.percentValue_ = /^(\d{1,4}(?:\.\d+)?|100)%$/;
1306
1308
 
1307
1309
  /**
1308
1310
  * @const
@@ -11,6 +11,7 @@ goog.require('goog.asserts');
11
11
  goog.require('shaka.Deprecate');
12
12
  goog.require('shaka.text.Cue');
13
13
  goog.require('shaka.text.CueRegion');
14
+ goog.require('shaka.text.Utils');
14
15
  goog.require('shaka.util.Dom');
15
16
  goog.require('shaka.util.EventManager');
16
17
  goog.require('shaka.util.Timer');
@@ -156,7 +157,7 @@ shaka.text.UITextDisplayer = class {
156
157
  // list growing during the comparisons for duplicate cues.
157
158
  // See: https://github.com/shaka-project/shaka-player/issues/3018
158
159
  const cuesList = [...this.cues_];
159
- for (const cue of cues) {
160
+ for (const cue of shaka.text.Utils.removeDuplicates(cues)) {
160
161
  // When a VTT cue spans a segment boundary, the cue will be duplicated
161
162
  // into two segments.
162
163
  // To avoid displaying duplicate cues, if the current cue list already
@@ -654,6 +655,10 @@ shaka.text.UITextDisplayer = class {
654
655
  style.backgroundSize = 'contain';
655
656
  style.backgroundPosition = 'center';
656
657
 
658
+ if (cue.backgroundColor) {
659
+ style.backgroundColor = cue.backgroundColor;
660
+ }
661
+
657
662
  // Quoting https://www.w3.org/TR/ttml-imsc1.2/:
658
663
  // "The width and height (in pixels) of the image resource referenced by
659
664
  // smpte:backgroundImage SHALL be equal to the width and height expressed
@@ -196,6 +196,8 @@ shaka.util.ConfigUtils = class {
196
196
  }
197
197
  } else if (isArrayEmpty(value) && isArrayEmpty(base[key])) {
198
198
  // Do nothing if both are empty arrays
199
+ } else if (Number.isNaN(value) && Number.isNaN(base[key])) {
200
+ // Do nothing if both are NaN
199
201
  } else if (value !== base[key]) {
200
202
  acc[key] = value;
201
203
  }
@@ -215,6 +217,9 @@ shaka.util.ConfigUtils = class {
215
217
  delete obj[key];
216
218
  } else if (isObject(obj[key])) {
217
219
  removeEmpty(obj[key]);
220
+ if (Object.keys(obj[key]).length === 0) {
221
+ delete obj[key];
222
+ }
218
223
  }
219
224
  }
220
225
  };
@@ -6,8 +6,113 @@
6
6
 
7
7
  goog.provide('shaka.util.DrmUtils');
8
8
 
9
+ goog.require('shaka.util.BufferUtils');
10
+ goog.require('shaka.util.Lazy');
11
+
9
12
 
10
13
  shaka.util.DrmUtils = class {
14
+ /**
15
+ * Returns true if the browser has recent EME APIs.
16
+ *
17
+ * @return {boolean}
18
+ */
19
+ static isBrowserSupported() {
20
+ const basic =
21
+ !!window.MediaKeys &&
22
+ !!window.navigator &&
23
+ !!window.navigator.requestMediaKeySystemAccess &&
24
+ !!window.MediaKeySystemAccess &&
25
+ // eslint-disable-next-line no-restricted-syntax
26
+ !!window.MediaKeySystemAccess.prototype.getConfiguration;
27
+
28
+ return basic;
29
+ }
30
+
31
+ /**
32
+ * Checks if two DrmInfos can be decrypted using the same key system.
33
+ * Clear content is considered compatible with every key system.
34
+ *
35
+ * @param {!Array<!shaka.extern.DrmInfo>} drms1
36
+ * @param {!Array<!shaka.extern.DrmInfo>} drms2
37
+ * @return {boolean}
38
+ */
39
+ static areDrmCompatible(drms1, drms2) {
40
+ if (!drms1.length || !drms2.length) {
41
+ return true;
42
+ }
43
+
44
+ if (drms1 === drms2) {
45
+ return true;
46
+ }
47
+
48
+ return shaka.util.DrmUtils.getCommonDrmInfos(
49
+ drms1, drms2).length > 0;
50
+ }
51
+
52
+ /**
53
+ * Returns an array of drm infos that are present in both input arrays.
54
+ * If one of the arrays is empty, returns the other one since clear
55
+ * content is considered compatible with every drm info.
56
+ *
57
+ * @param {!Array<!shaka.extern.DrmInfo>} drms1
58
+ * @param {!Array<!shaka.extern.DrmInfo>} drms2
59
+ * @return {!Array<!shaka.extern.DrmInfo>}
60
+ */
61
+ static getCommonDrmInfos(drms1, drms2) {
62
+ if (!drms1.length) {
63
+ return drms2;
64
+ }
65
+ if (!drms2.length) {
66
+ return drms1;
67
+ }
68
+
69
+ const commonDrms = [];
70
+
71
+ for (const drm1 of drms1) {
72
+ for (const drm2 of drms2) {
73
+ if (drm1.keySystem == drm2.keySystem) {
74
+ const initDataMap = new Map();
75
+ const bothInitDatas = (drm1.initData || [])
76
+ .concat(drm2.initData || []);
77
+ for (const d of bothInitDatas) {
78
+ initDataMap.set(d.keyId, d);
79
+ }
80
+ const initData = Array.from(initDataMap.values());
81
+
82
+ const keyIds = drm1.keyIds && drm2.keyIds ?
83
+ new Set([...drm1.keyIds, ...drm2.keyIds]) :
84
+ drm1.keyIds || drm2.keyIds;
85
+ const mergedDrm = {
86
+ keySystem: drm1.keySystem,
87
+ licenseServerUri: drm1.licenseServerUri || drm2.licenseServerUri,
88
+ distinctiveIdentifierRequired: drm1.distinctiveIdentifierRequired ||
89
+ drm2.distinctiveIdentifierRequired,
90
+ persistentStateRequired: drm1.persistentStateRequired ||
91
+ drm2.persistentStateRequired,
92
+ videoRobustness: drm1.videoRobustness || drm2.videoRobustness,
93
+ audioRobustness: drm1.audioRobustness || drm2.audioRobustness,
94
+ serverCertificate: drm1.serverCertificate || drm2.serverCertificate,
95
+ serverCertificateUri: drm1.serverCertificateUri ||
96
+ drm2.serverCertificateUri,
97
+ initData,
98
+ keyIds,
99
+ };
100
+ commonDrms.push(mergedDrm);
101
+ break;
102
+ }
103
+ }
104
+ }
105
+
106
+ return commonDrms;
107
+ }
108
+
109
+ /**
110
+ * @param {?shaka.extern.DrmInfo} drmInfo
111
+ * @return {string} */
112
+ static keySystem(drmInfo) {
113
+ return drmInfo ? drmInfo.keySystem : '';
114
+ }
115
+
11
116
  /**
12
117
  * @param {?string} keySystem
13
118
  * @return {boolean}
@@ -31,4 +136,90 @@ shaka.util.DrmUtils = class {
31
136
 
32
137
  return false;
33
138
  }
139
+
140
+ /**
141
+ * A method for generating a key for the MediaKeySystemAccessRequests cache.
142
+ *
143
+ * @param {string} videoCodec
144
+ * @param {string} audioCodec
145
+ * @param {string} keySystem
146
+ * @return {string}
147
+ * @private
148
+ */
149
+ static generateKeySystemCacheKey_(videoCodec, audioCodec, keySystem) {
150
+ return `${videoCodec}#${audioCodec}#${keySystem}`;
151
+ }
152
+
153
+ /**
154
+ * Check does MediaKeySystemAccess cache contains something for following
155
+ * attributes.
156
+ *
157
+ * @param {string} videoCodec
158
+ * @param {string} audioCodec
159
+ * @param {string} keySystem
160
+ * @return {boolean}
161
+ */
162
+ static hasMediaKeySystemAccess(videoCodec, audioCodec, keySystem) {
163
+ const DrmUtils = shaka.util.DrmUtils;
164
+ const key = DrmUtils.generateKeySystemCacheKey_(
165
+ videoCodec, audioCodec, keySystem);
166
+ return DrmUtils.memoizedMediaKeySystemAccessRequests_.has(key);
167
+ }
168
+
169
+ /**
170
+ * Get MediaKeySystemAccess object for following attributes.
171
+ *
172
+ * @param {string} videoCodec
173
+ * @param {string} audioCodec
174
+ * @param {string} keySystem
175
+ * @return {?MediaKeySystemAccess}
176
+ */
177
+ static getMediaKeySystemAccess(videoCodec, audioCodec, keySystem) {
178
+ const DrmUtils = shaka.util.DrmUtils;
179
+ const key = DrmUtils.generateKeySystemCacheKey_(
180
+ videoCodec, audioCodec, keySystem);
181
+ return DrmUtils.memoizedMediaKeySystemAccessRequests_.get(key) || null;
182
+ }
183
+
184
+ /**
185
+ * Store MediaKeySystemAccess object associated with specified attributes.
186
+ *
187
+ * @param {string} videoCodec
188
+ * @param {string} audioCodec
189
+ * @param {string} keySystem
190
+ * @param {!MediaKeySystemAccess} mksa
191
+ */
192
+ static setMediaKeySystemAccess(videoCodec, audioCodec, keySystem, mksa) {
193
+ const DrmUtils = shaka.util.DrmUtils;
194
+ const key = DrmUtils.generateKeySystemCacheKey_(
195
+ videoCodec, audioCodec, keySystem);
196
+ return DrmUtils.memoizedMediaKeySystemAccessRequests_.set(key, mksa);
197
+ }
198
+
199
+ /**
200
+ * Clears underlying cache.
201
+ */
202
+ static clearMediaKeySystemAccessMap() {
203
+ const DrmUtils = shaka.util.DrmUtils;
204
+ DrmUtils.memoizedMediaKeySystemAccessRequests_.clear();
205
+ }
34
206
  };
207
+
208
+
209
+ /**
210
+ * Contains the suggested "default" key ID used by EME polyfills that do not
211
+ * have a per-key key status. See w3c/encrypted-media#32.
212
+ * @type {!shaka.util.Lazy<!ArrayBuffer>}
213
+ */
214
+ shaka.util.DrmUtils.DUMMY_KEY_ID = new shaka.util.Lazy(
215
+ () => shaka.util.BufferUtils.toArrayBuffer(new Uint8Array([0])));
216
+
217
+
218
+ /**
219
+ * A cache that stores the MediaKeySystemAccess result of calling
220
+ * `navigator.requestMediaKeySystemAccess` by a key combination of
221
+ * video/audio codec and key system string.
222
+ *
223
+ * @private {!Map<string, !MediaKeySystemAccess>}
224
+ */
225
+ shaka.util.DrmUtils.memoizedMediaKeySystemAccessRequests_ = new Map();
@@ -8,9 +8,9 @@ goog.provide('shaka.util.PeriodCombiner');
8
8
 
9
9
  goog.require('goog.asserts');
10
10
  goog.require('shaka.log');
11
- goog.require('shaka.media.DrmEngine');
12
11
  goog.require('shaka.media.MetaSegmentIndex');
13
12
  goog.require('shaka.media.SegmentIndex');
13
+ goog.require('shaka.util.DrmUtils');
14
14
  goog.require('shaka.util.Error');
15
15
  goog.require('shaka.util.IReleasable');
16
16
  goog.require('shaka.util.LanguageUtils');
@@ -282,7 +282,7 @@ shaka.util.PeriodCombiner = class {
282
282
  } else {
283
283
  for (const audio of this.audioStreams_) {
284
284
  for (const video of this.videoStreams_) {
285
- const commonDrmInfos = shaka.media.DrmEngine.getCommonDrmInfos(
285
+ const commonDrmInfos = shaka.util.DrmUtils.getCommonDrmInfos(
286
286
  audio.drmInfos, video.drmInfos);
287
287
 
288
288
  if (audio.drmInfos.length && video.drmInfos.length &&
@@ -855,7 +855,7 @@ shaka.util.PeriodCombiner = class {
855
855
  output.originalId += ',' + (input.originalId || '');
856
856
  }
857
857
 
858
- const commonDrmInfos = shaka.media.DrmEngine.getCommonDrmInfos(
858
+ const commonDrmInfos = shaka.util.DrmUtils.getCommonDrmInfos(
859
859
  output.drmInfos, input.drmInfos);
860
860
  if (input.drmInfos.length && output.drmInfos.length &&
861
861
  !commonDrmInfos.length) {
@@ -1115,7 +1115,7 @@ shaka.util.PeriodCombiner = class {
1115
1115
  if (outputStream.drmInfos) {
1116
1116
  // Check for compatible DRM systems. Note that clear streams are
1117
1117
  // implicitly compatible with any DRM and with each other.
1118
- if (!shaka.media.DrmEngine.areDrmCompatible(outputStream.drmInfos,
1118
+ if (!shaka.util.DrmUtils.areDrmCompatible(outputStream.drmInfos,
1119
1119
  candidate.drmInfos)) {
1120
1120
  return false;
1121
1121
  }
@@ -351,6 +351,7 @@ shaka.util.PlayerConfiguration = class {
351
351
  clearBufferSwitch: false,
352
352
  safeMarginSwitch: 0,
353
353
  cacheLoadThreshold: 20,
354
+ minTimeToSwitch: shaka.util.Platform.isApple() ? 0.5 : 0,
354
355
  };
355
356
 
356
357
  const cmcd = {
@@ -726,7 +726,7 @@ shaka.util.TsParser = class {
726
726
  }
727
727
 
728
728
  /**
729
- * Return the audio data
729
+ * Return the video data
730
730
  *
731
731
  * @param {boolean=} naluProcessing
732
732
  * @return {!Array.<shaka.extern.MPEG_PES>}
@@ -760,15 +760,15 @@ shaka.util.TsParser = class {
760
760
  if (naluProcessing) {
761
761
  let lastNalu;
762
762
  let lastState;
763
+ const pesWithLength = [];
763
764
  for (const pes of this.videoPes_) {
764
765
  pes.nalus = this.parseNalus(pes, lastNalu, lastState);
765
766
  if (pes.nalus.length) {
767
+ pesWithLength.push(pes);
766
768
  lastNalu = pes.nalus[pes.nalus.length - 1];
767
769
  }
768
770
  }
769
- this.videoPes_ = this.videoPes_.filter((pes) => {
770
- return pes.nalus.length;
771
- });
771
+ this.videoPes_ = pesWithLength;
772
772
  }
773
773
  if (sort) {
774
774
  this.videoPes_ = this.videoPes_.sort((a, b) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shaka-player",
3
3
  "description": "DASH/EME video player library",
4
- "version": "4.10.0",
4
+ "version": "4.10.2",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "AD_DURATION": "Durée de l'annonce",
3
3
  "AD_PROGRESS": "Annonce [AD_ON] sur [NUM_ADS]",
4
- "AD_STATISTICS": "Statistiques de la annonce",
4
+ "AD_STATISTICS": "Statistiques de l'annonce",
5
5
  "AD_TIME": "Annonce : [AD_TIME]",
6
6
  "AIRPLAY": "AirPlay",
7
7
  "AUTO_QUALITY": "Automatique",
@@ -241,8 +241,11 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
241
241
  loadContainer_() {
242
242
  for (const name of this.controls.getConfig().statisticsList) {
243
243
  if (name in this.currentStats_ && !this.skippedStats_.includes(name)) {
244
- this.container_.appendChild(this.generateComponent_(name));
244
+ const element = this.generateComponent_(name);
245
+ this.container_.appendChild(element);
245
246
  this.statisticsList_.push(name);
247
+ shaka.ui.Utils.setDisplay(element.parentElement,
248
+ !isNaN(this.currentStats_[name]));
246
249
  } else {
247
250
  shaka.log.alwaysWarn('Unrecognized statistic element:', name);
248
251
  }
@@ -254,8 +257,12 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
254
257
  this.currentStats_ = this.player.getStats();
255
258
 
256
259
  for (const name of this.statisticsList_) {
257
- this.displayedElements_[name].textContent =
258
- this.parseFrom_[name](name);
260
+ const element = this.displayedElements_[name];
261
+ element.textContent = this.parseFrom_[name](name);
262
+ if (element && element.parentElement) {
263
+ shaka.ui.Utils.setDisplay(element.parentElement,
264
+ !isNaN(this.currentStats_[name]));
265
+ }
259
266
  }
260
267
  }
261
268