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
@@ -8,8 +8,10 @@ goog.provide('shaka.media.SegmentUtils');
8
8
 
9
9
  goog.require('goog.asserts');
10
10
  goog.require('shaka.log');
11
+ goog.require('shaka.media.Capabilities');
11
12
  goog.require('shaka.media.ClosedCaptionParser');
12
13
  goog.require('shaka.util.BufferUtils');
14
+ goog.require('shaka.util.ManifestParserUtils');
13
15
  goog.require('shaka.util.MimeUtils');
14
16
  goog.require('shaka.util.Mp4BoxParsers');
15
17
  goog.require('shaka.util.Mp4Parser');
@@ -38,6 +40,7 @@ shaka.media.SegmentUtils = class {
38
40
  channelCount: null,
39
41
  sampleRate: null,
40
42
  closedCaptions: new Map(),
43
+ videoRange: null,
41
44
  };
42
45
  }
43
46
 
@@ -121,6 +124,7 @@ shaka.media.SegmentUtils = class {
121
124
  channelCount: null,
122
125
  sampleRate: null,
123
126
  closedCaptions: closedCaptions,
127
+ videoRange: null,
124
128
  };
125
129
  }
126
130
 
@@ -133,7 +137,8 @@ shaka.media.SegmentUtils = class {
133
137
  const Mp4Parser = shaka.util.Mp4Parser;
134
138
  const SegmentUtils = shaka.media.SegmentUtils;
135
139
 
136
- const codecs = [];
140
+ const audioCodecs = [];
141
+ const videoCodecs = [];
137
142
 
138
143
  let hasAudio = false;
139
144
  let hasVideo = false;
@@ -143,38 +148,38 @@ shaka.media.SegmentUtils = class {
143
148
  switch (codecLC) {
144
149
  case 'avc1':
145
150
  case 'avc3':
146
- codecs.push(codecLC + '.42E01E');
151
+ videoCodecs.push(codecLC + '.42E01E');
147
152
  hasVideo = true;
148
153
  break;
149
154
  case 'hev1':
150
155
  case 'hvc1':
151
- codecs.push(codecLC + '.1.6.L93.90');
156
+ videoCodecs.push(codecLC + '.1.6.L93.90');
152
157
  hasVideo = true;
153
158
  break;
154
159
  case 'dvh1':
155
160
  case 'dvhe':
156
- codecs.push(codecLC + '.05.04');
161
+ videoCodecs.push(codecLC + '.05.04');
157
162
  hasVideo = true;
158
163
  break;
159
164
  case 'vp09':
160
- codecs.push(codecLC + '.00.10.08');
165
+ videoCodecs.push(codecLC + '.00.10.08');
161
166
  hasVideo = true;
162
167
  break;
163
168
  case 'av01':
164
- codecs.push(codecLC + '.0.01M.08');
169
+ videoCodecs.push(codecLC + '.0.01M.08');
165
170
  hasVideo = true;
166
171
  break;
167
172
  case 'mp4a':
168
173
  // We assume AAC, but this can be wrong since mp4a supports
169
174
  // others codecs
170
- codecs.push('mp4a.40.2');
175
+ audioCodecs.push('mp4a.40.2');
171
176
  hasAudio = true;
172
177
  break;
173
178
  case 'ac-3':
174
179
  case 'ec-3':
175
180
  case 'opus':
176
181
  case 'flac':
177
- codecs.push(codecLC);
182
+ audioCodecs.push(codecLC);
178
183
  hasAudio = true;
179
184
  break;
180
185
  }
@@ -192,6 +197,11 @@ shaka.media.SegmentUtils = class {
192
197
  let channelCount = null;
193
198
  /** @type {?number} */
194
199
  let sampleRate = null;
200
+ /** @type {?string} */
201
+ let realVideoRange = null;
202
+
203
+ /** @type {?string} */
204
+ let baseBox;
195
205
 
196
206
  new Mp4Parser()
197
207
  .box('moov', Mp4Parser.children)
@@ -232,7 +242,7 @@ shaka.media.SegmentUtils = class {
232
242
  })
233
243
  .box('esds', (box) => {
234
244
  const parsedESDSBox = shaka.util.Mp4BoxParsers.parseESDS(box.reader);
235
- codecs.push(parsedESDSBox.codec);
245
+ audioCodecs.push(parsedESDSBox.codec);
236
246
  hasAudio = true;
237
247
  })
238
248
  .box('ac-3', codecBoxParser)
@@ -244,23 +254,110 @@ shaka.media.SegmentUtils = class {
244
254
  // VIDEO
245
255
  // These are the various boxes that signal a codec.
246
256
  .box('avc1', (box) => {
247
- const parsedAVCBox =
248
- shaka.util.Mp4BoxParsers.parseAVC(box.reader, box.name);
249
- codecs.push(parsedAVCBox.codec);
250
- hasVideo = true;
257
+ baseBox = box.name;
258
+ Mp4Parser.visualSampleEntry(box);
251
259
  })
252
260
  .box('avc3', (box) => {
253
- const parsedAVCBox =
254
- shaka.util.Mp4BoxParsers.parseAVC(box.reader, box.name);
255
- codecs.push(parsedAVCBox.codec);
261
+ baseBox = box.name;
262
+ Mp4Parser.visualSampleEntry(box);
263
+ })
264
+ .box('hev1', (box) => {
265
+ baseBox = box.name;
266
+ Mp4Parser.visualSampleEntry(box);
267
+ })
268
+ .box('hvc1', (box) => {
269
+ baseBox = box.name;
270
+ Mp4Parser.visualSampleEntry(box);
271
+ })
272
+ .box('dva1', (box) => {
273
+ baseBox = box.name;
274
+ Mp4Parser.visualSampleEntry(box);
275
+ })
276
+ .box('dvav', (box) => {
277
+ baseBox = box.name;
278
+ Mp4Parser.visualSampleEntry(box);
279
+ })
280
+ .box('dvh1', (box) => {
281
+ baseBox = box.name;
282
+ Mp4Parser.visualSampleEntry(box);
283
+ })
284
+ .box('dvhe', (box) => {
285
+ baseBox = box.name;
286
+ Mp4Parser.visualSampleEntry(box);
287
+ })
288
+ .box('vp09', (box) => {
289
+ baseBox = box.name;
290
+ Mp4Parser.visualSampleEntry(box);
291
+ })
292
+ .box('av01', (box) => {
293
+ baseBox = box.name;
294
+ Mp4Parser.visualSampleEntry(box);
295
+ })
296
+ .box('avcC', (box) => {
297
+ let codecBase = baseBox || '';
298
+ switch (baseBox) {
299
+ case 'dvav':
300
+ codecBase = 'avc3';
301
+ break;
302
+ case 'dva1':
303
+ codecBase = 'avc1';
304
+ break;
305
+ }
306
+ const parsedAVCCBox = shaka.util.Mp4BoxParsers.parseAVCC(
307
+ codecBase, box.reader, box.name);
308
+ videoCodecs.push(parsedAVCCBox.codec);
309
+ hasVideo = true;
310
+ })
311
+ .box('hvcC', (box) => {
312
+ let codecBase = baseBox || '';
313
+ switch (baseBox) {
314
+ case 'dvh1':
315
+ codecBase = 'hvc1';
316
+ break;
317
+ case 'dvhe':
318
+ codecBase = 'hev1';
319
+ break;
320
+ }
321
+ const parsedHVCCBox = shaka.util.Mp4BoxParsers.parseHVCC(
322
+ codecBase, box.reader, box.name);
323
+ videoCodecs.push(parsedHVCCBox.codec);
324
+ hasVideo = true;
325
+ })
326
+ .box('dvcC', (box) => {
327
+ let codecBase = baseBox || '';
328
+ switch (baseBox) {
329
+ case 'hvc1':
330
+ codecBase = 'dvh1';
331
+ break;
332
+ case 'hev1':
333
+ codecBase = 'dvhe';
334
+ break;
335
+ case 'avc1':
336
+ codecBase = 'dva1';
337
+ break;
338
+ case 'avc3':
339
+ codecBase = 'dvav';
340
+ break;
341
+ }
342
+ const parsedDVCCBox = shaka.util.Mp4BoxParsers.parseDVCC(
343
+ codecBase, box.reader, box.name);
344
+ videoCodecs.push(parsedDVCCBox.codec);
345
+ hasVideo = true;
346
+ })
347
+ .fullBox('vpcC', (box) => {
348
+ const codecBase = baseBox || '';
349
+ const parsedVPCCBox = shaka.util.Mp4BoxParsers.parseVPCC(
350
+ codecBase, box.reader, box.name);
351
+ videoCodecs.push(parsedVPCCBox.codec);
352
+ hasVideo = true;
353
+ })
354
+ .box('av1C', (box) => {
355
+ const codecBase = baseBox || '';
356
+ const parsedAV1CBox = shaka.util.Mp4BoxParsers.parseAV1C(
357
+ codecBase, box.reader, box.name);
358
+ videoCodecs.push(parsedAV1CBox.codec);
256
359
  hasVideo = true;
257
360
  })
258
- .box('hev1', codecBoxParser)
259
- .box('hvc1', codecBoxParser)
260
- .box('dvh1', codecBoxParser)
261
- .box('dvhe', codecBoxParser)
262
- .box('vp09', codecBoxParser)
263
- .box('av01', codecBoxParser)
264
361
 
265
362
  // This signals an encrypted sample, which we can go inside of to
266
363
  // find the codec used.
@@ -273,8 +370,13 @@ shaka.media.SegmentUtils = class {
273
370
  addCodec(codec);
274
371
  })
275
372
 
373
+ .box('colr', (box) => {
374
+ const {videoRange} = shaka.util.Mp4BoxParsers.parseCOLR(box.reader);
375
+ realVideoRange = videoRange;
376
+ })
377
+
276
378
  .parse(initData || data, /* partialOkay= */ true);
277
- if (!codecs.length) {
379
+ if (!audioCodecs.length && !videoCodecs.length) {
278
380
  return null;
279
381
  }
280
382
  const onlyAudio = hasAudio && !hasVideo;
@@ -290,19 +392,45 @@ shaka.media.SegmentUtils = class {
290
392
  }
291
393
  captionParser.reset();
292
394
  }
395
+ const codecs = audioCodecs.concat(videoCodecs);
293
396
  return {
294
397
  type: onlyAudio ? 'audio' : 'video',
295
398
  mimeType: onlyAudio ? 'audio/mp4' : 'video/mp4',
296
- codecs: SegmentUtils.filterDuplicateCodecs_(codecs).join(', '),
399
+ codecs: SegmentUtils.codecsFiltering(codecs).join(', '),
297
400
  language: language,
298
401
  height: height,
299
402
  width: width,
300
403
  channelCount: channelCount,
301
404
  sampleRate: sampleRate,
302
405
  closedCaptions: closedCaptions,
406
+ videoRange: realVideoRange,
303
407
  };
304
408
  }
305
409
 
410
+ /**
411
+ * @param {!Array.<string>} codecs
412
+ * @return {!Array.<string>} codecs
413
+ */
414
+ static codecsFiltering(codecs) {
415
+ const ContentType = shaka.util.ManifestParserUtils.ContentType;
416
+ const ManifestParserUtils = shaka.util.ManifestParserUtils;
417
+ const SegmentUtils = shaka.media.SegmentUtils;
418
+ const allCodecs = SegmentUtils.filterDuplicateCodecs_(codecs);
419
+ const audioCodecs =
420
+ ManifestParserUtils.guessAllCodecsSafe(ContentType.AUDIO, allCodecs);
421
+ const videoCodecs =
422
+ ManifestParserUtils.guessAllCodecsSafe(ContentType.VIDEO, allCodecs);
423
+ const textCodecs =
424
+ ManifestParserUtils.guessAllCodecsSafe(ContentType.TEXT, allCodecs);
425
+ const validVideoCodecs = SegmentUtils.chooseBetterCodecs_(videoCodecs);
426
+ const finalCodecs =
427
+ audioCodecs.concat(validVideoCodecs).concat(textCodecs);
428
+ if (allCodecs.length && !finalCodecs.length) {
429
+ return allCodecs;
430
+ }
431
+ return finalCodecs;
432
+ }
433
+
306
434
  /**
307
435
  * @param {!Array.<string>} codecs
308
436
  * @return {!Array.<string>} codecs
@@ -323,6 +451,59 @@ shaka.media.SegmentUtils = class {
323
451
  }
324
452
  return ret;
325
453
  }
454
+
455
+ /**
456
+ * Prioritizes Dolby Vision if supported. This is necessary because with
457
+ * Dolby Vision we could have hvcC and dvcC boxes at the same time.
458
+ *
459
+ * @param {!Array.<string>} codecs
460
+ * @return {!Array.<string>} codecs
461
+ * @private
462
+ */
463
+ static chooseBetterCodecs_(codecs) {
464
+ if (codecs.length <= 1) {
465
+ return codecs;
466
+ }
467
+ const dolbyVision = codecs.find((codec) => {
468
+ return codec.startsWith('dvh1.') || codec.startsWith('dvhe.');
469
+ });
470
+ if (!dolbyVision) {
471
+ return codecs;
472
+ }
473
+ const type = `video/mp4; codecs="${dolbyVision}"'`;
474
+ if (shaka.media.Capabilities.isTypeSupported(type)) {
475
+ return [dolbyVision];
476
+ }
477
+ return codecs.filter((codec) => codec != dolbyVision);
478
+ }
479
+
480
+ /**
481
+ * @param {!BufferSource} data
482
+ * @return {?string}
483
+ */
484
+ static getDefaultKID(data) {
485
+ const Mp4Parser = shaka.util.Mp4Parser;
486
+
487
+ let defaultKID = null;
488
+ new Mp4Parser()
489
+ .box('moov', Mp4Parser.children)
490
+ .box('trak', Mp4Parser.children)
491
+ .box('mdia', Mp4Parser.children)
492
+ .box('minf', Mp4Parser.children)
493
+ .box('stbl', Mp4Parser.children)
494
+ .fullBox('stsd', Mp4Parser.sampleDescription)
495
+ .box('encv', Mp4Parser.visualSampleEntry)
496
+ .box('enca', Mp4Parser.audioSampleEntry)
497
+ .box('sinf', Mp4Parser.children)
498
+ .box('schi', Mp4Parser.children)
499
+ .fullBox('tenc', (box) => {
500
+ const parsedTENCBox = shaka.util.Mp4BoxParsers.parseTENC(box.reader);
501
+ defaultKID = parsedTENCBox.defaultKID;
502
+ })
503
+
504
+ .parse(data, /* partialOkay= */ true);
505
+ return defaultKID;
506
+ }
326
507
  };
327
508
 
328
509
 
@@ -336,7 +517,8 @@ shaka.media.SegmentUtils = class {
336
517
  * width: ?string,
337
518
  * channelCount: ?number,
338
519
  * sampleRate: ?number,
339
- * closedCaptions: Map.<string, string>
520
+ * closedCaptions: Map.<string, string>,
521
+ * videoRange: ?string
340
522
  * }}
341
523
  *
342
524
  * @property {string} type
@@ -348,5 +530,6 @@ shaka.media.SegmentUtils = class {
348
530
  * @property {?number} channelCount
349
531
  * @property {?number} sampleRate
350
532
  * @property {Map.<string, string>} closedCaptions
533
+ * @property {?string} videoRange
351
534
  */
352
535
  shaka.media.SegmentUtils.BasicInfo;