shaka-player 4.9.12 → 4.9.13

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 (35) hide show
  1. package/dist/deps.js +9 -9
  2. package/dist/locales.js +32 -32
  3. package/dist/shaka-player.compiled.d.ts +1 -1
  4. package/dist/shaka-player.compiled.debug.d.ts +1 -1
  5. package/dist/shaka-player.compiled.debug.externs.js +1 -1
  6. package/dist/shaka-player.compiled.debug.js +119 -119
  7. package/dist/shaka-player.compiled.debug.map +3 -3
  8. package/dist/shaka-player.compiled.externs.js +1 -1
  9. package/dist/shaka-player.compiled.js +1125 -1120
  10. package/dist/shaka-player.compiled.map +4 -4
  11. package/dist/shaka-player.ui.d.ts +1 -1
  12. package/dist/shaka-player.ui.debug.d.ts +1 -1
  13. package/dist/shaka-player.ui.debug.externs.js +1 -1
  14. package/dist/shaka-player.ui.debug.js +144 -143
  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 +1328 -1324
  18. package/dist/shaka-player.ui.map +4 -4
  19. package/lib/hls/hls_parser.js +3 -3
  20. package/lib/media/drm_engine.js +9 -197
  21. package/lib/player.js +15 -10
  22. package/lib/polyfill/media_capabilities.js +4 -4
  23. package/lib/polyfill/patchedmediakeys_apple.js +3 -3
  24. package/lib/polyfill/patchedmediakeys_webkit.js +3 -3
  25. package/lib/text/simple_text_displayer.js +3 -0
  26. package/lib/text/ssa_text_parser.js +22 -7
  27. package/lib/text/text_utils.js +17 -1
  28. package/lib/text/ttml_text_parser.js +5 -3
  29. package/lib/text/ui_text_displayer.js +6 -1
  30. package/lib/util/config_utils.js +5 -0
  31. package/lib/util/drm_utils.js +191 -0
  32. package/lib/util/periods.js +4 -4
  33. package/lib/util/ts_parser.js +4 -4
  34. package/package.json +1 -1
  35. package/ui/statistics_button.js +10 -3
@@ -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
  }
@@ -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.9.12",
4
+ "version": "4.9.13",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -229,8 +229,11 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
229
229
  loadContainer_() {
230
230
  for (const name of this.controls.getConfig().statisticsList) {
231
231
  if (name in this.currentStats_ && !this.skippedStats_.includes(name)) {
232
- this.container_.appendChild(this.generateComponent_(name));
232
+ const element = this.generateComponent_(name);
233
+ this.container_.appendChild(element);
233
234
  this.statisticsList_.push(name);
235
+ shaka.ui.Utils.setDisplay(element.parentElement,
236
+ !isNaN(this.currentStats_[name]));
234
237
  } else {
235
238
  shaka.log.alwaysWarn('Unrecognized statistic element:', name);
236
239
  }
@@ -242,8 +245,12 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
242
245
  this.currentStats_ = this.player.getStats();
243
246
 
244
247
  for (const name of this.statisticsList_) {
245
- this.displayedElements_[name].textContent =
246
- this.parseFrom_[name](name);
248
+ const element = this.displayedElements_[name];
249
+ element.textContent = this.parseFrom_[name](name);
250
+ if (element && element.parentElement) {
251
+ shaka.ui.Utils.setDisplay(element.parentElement,
252
+ !isNaN(this.currentStats_[name]));
253
+ }
247
254
  }
248
255
  }
249
256