shaka-player 4.3.0 → 4.3.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 (78) hide show
  1. package/.github/workflows/build-and-test.yaml +20 -0
  2. package/AUTHORS +2 -0
  3. package/CHANGELOG.md +44 -0
  4. package/CONTRIBUTORS +2 -0
  5. package/README.md +1 -1
  6. package/conditional/dummy_cast_proxy.js +120 -0
  7. package/dist/demo.compiled.debug.js +104 -110
  8. package/dist/demo.compiled.debug.map +3 -3
  9. package/dist/demo.compiled.js +104 -110
  10. package/dist/demo.compiled.map +3 -3
  11. package/dist/deps.js +8 -6
  12. package/dist/locales.js +32 -32
  13. package/dist/receiver.compiled.debug.js +54 -60
  14. package/dist/receiver.compiled.debug.map +3 -3
  15. package/dist/receiver.compiled.js +54 -60
  16. package/dist/receiver.compiled.map +3 -3
  17. package/dist/shaka-player.compiled.d.ts +19 -2
  18. package/dist/shaka-player.compiled.debug.d.ts +19 -2
  19. package/dist/shaka-player.compiled.debug.externs.js +102 -80
  20. package/dist/shaka-player.compiled.debug.js +657 -652
  21. package/dist/shaka-player.compiled.debug.map +4 -4
  22. package/dist/shaka-player.compiled.externs.js +102 -80
  23. package/dist/shaka-player.compiled.js +904 -901
  24. package/dist/shaka-player.compiled.map +4 -4
  25. package/dist/shaka-player.ui.d.ts +19 -2
  26. package/dist/shaka-player.ui.debug.d.ts +19 -2
  27. package/dist/shaka-player.ui.debug.externs.js +102 -80
  28. package/dist/shaka-player.ui.debug.js +703 -698
  29. package/dist/shaka-player.ui.debug.map +4 -4
  30. package/dist/shaka-player.ui.externs.js +102 -80
  31. package/dist/shaka-player.ui.js +1029 -1026
  32. package/dist/shaka-player.ui.map +4 -4
  33. package/docs/tutorials/welcome.md +2 -2
  34. package/externs/shaka/mp4_parser.js +3 -0
  35. package/externs/shaka/player.js +2 -1
  36. package/lib/ads/ad_manager.js +2 -2
  37. package/lib/cea/cea708_window.js +2 -2
  38. package/lib/cea/mp4_cea_parser.js +37 -16
  39. package/lib/dash/segment_template.js +1 -1
  40. package/lib/hls/hls_parser.js +49 -23
  41. package/lib/media/content_workarounds.js +12 -0
  42. package/lib/media/media_source_capabilities.js +36 -0
  43. package/lib/media/media_source_engine.js +28 -7
  44. package/lib/media/segment_reference.js +3 -0
  45. package/lib/media/streaming_engine.js +33 -10
  46. package/lib/media/transmuxer.js +6 -4
  47. package/lib/player.js +10 -6
  48. package/lib/polyfill/abort_controller.js +143 -0
  49. package/lib/polyfill/media_capabilities.js +65 -11
  50. package/lib/polyfill/patchedmediakeys_apple.js +33 -28
  51. package/lib/text/ttml_text_parser.js +32 -7
  52. package/lib/text/ui_text_displayer.js +17 -0
  53. package/lib/util/mp4_box_parsers.js +24 -0
  54. package/lib/util/mp4_parser.js +35 -0
  55. package/lib/util/player_configuration.js +10 -3
  56. package/lib/util/stream_utils.js +35 -13
  57. package/package.json +4 -4
  58. package/shaka-player.uncompiled.js +1 -0
  59. package/test/ads/ad_manager_unit.js +3 -1
  60. package/test/dash/dash_parser_manifest_unit.js +1 -0
  61. package/test/hls/hls_parser_unit.js +132 -0
  62. package/test/media/drm_engine_unit.js +11 -1
  63. package/test/media/media_source_engine_integration.js +78 -2
  64. package/test/player_integration.js +10 -3
  65. package/test/polyfill/media_capabilities_unit.js +259 -0
  66. package/test/polyfill/patchedmediakeys_apple_unit.js +6 -0
  67. package/test/test/boot.js +29 -11
  68. package/test/test/util/manifest_parser_util.js +4 -3
  69. package/test/test/util/stream_generator.js +212 -8
  70. package/test/test/util/test_scheme.js +6 -5
  71. package/test/test/util/util.js +3 -2
  72. package/test/text/mp4_ttml_parser_unit.js +6 -4
  73. package/test/text/ttml_text_parser_unit.js +119 -86
  74. package/test/text/ui_text_displayer_unit.js +76 -0
  75. package/test/util/stream_utils_unit.js +18 -0
  76. package/test/util/xml_utils_unit.js +6 -1
  77. package/third_party/closure-uri/uri.js +1 -1
  78. package/ui/controls.js +49 -36
@@ -461,4 +461,80 @@ describe('UITextDisplayer', () => {
461
461
  expect(Object.keys(cueCssObj)).not.toContain('left');
462
462
  }
463
463
  });
464
+
465
+ it('does not lose second item in a region', () => {
466
+ const cueRegion = new shaka.text.CueRegion();
467
+ cueRegion.id = 'regionId';
468
+ cueRegion.height = 80;
469
+ cueRegion.heightUnits = shaka.text.CueRegion.units.PERCENTAGE;
470
+ cueRegion.width = 80;
471
+ cueRegion.widthUnits = shaka.text.CueRegion.units.PERCENTAGE;
472
+ cueRegion.viewportAnchorX = 10;
473
+ cueRegion.viewportAnchorY = 10;
474
+ cueRegion.viewportAnchorUnits = shaka.text.CueRegion.units.PERCENTAGE;
475
+
476
+ // These have identical nested.
477
+ const cue1 = new shaka.text.Cue(168, 181.84, '');
478
+ cue1.nestedCues = [
479
+ new shaka.text.Cue(168, 181.84, ''),
480
+ ];
481
+ cue1.region = cueRegion;
482
+
483
+ const nested1 = new shaka.text.Cue(168, 170.92, '');
484
+ nested1.nestedCues = [new shaka.text.Cue(0, 170.92,
485
+ 'Emo look. I mean listen.')];
486
+
487
+ const nested2 = new shaka.text.Cue(172, 174.84, '');
488
+ nested2.nestedCues = [new shaka.text.Cue(172, 174.84,
489
+ 'You have to learn to listen.')];
490
+
491
+ const nested3 = new shaka.text.Cue(175.84, 177.64, '');
492
+ nested3.nestedCues = [new shaka.text.Cue(175.84, 177.64,
493
+ 'This is not some game.')];
494
+
495
+ const nested4 = new shaka.text.Cue(177.68, 181.84, '');
496
+ nested4.nestedCues = [new shaka.text.Cue(177.68, 181.84,
497
+ 'You - I mean we - we could easily die out here.')];
498
+
499
+ cue1.nestedCues[0].nestedCues = [nested1, nested2, nested3, nested4];
500
+
501
+ video.currentTime = 170;
502
+ textDisplayer.setTextVisibility(true);
503
+ textDisplayer.append([cue1]);
504
+ updateCaptions();
505
+
506
+ /** @type {Element} */
507
+ const textContainer = videoContainer.querySelector('.shaka-text-container');
508
+ let captions = textContainer.querySelectorAll('div');
509
+ expect(captions.length).toBe(1);
510
+ let allRegionElements = textContainer.querySelectorAll(
511
+ '.shaka-text-region');
512
+ // Verify that the nested cues are all attached to a single region element.
513
+ expect(allRegionElements.length).toBe(1);
514
+
515
+ // Advance time to where there is none to show
516
+ video.currentTime = 171;
517
+ updateCaptions();
518
+
519
+ allRegionElements = textContainer.querySelectorAll(
520
+ '.shaka-text-region');
521
+ expect(allRegionElements.length).toBe(1);
522
+
523
+ // Advance time to where there is something to show
524
+ video.currentTime = 173;
525
+ updateCaptions();
526
+
527
+ allRegionElements = textContainer.querySelectorAll(
528
+ '.shaka-text-region');
529
+ expect(allRegionElements.length).toBe(1);
530
+
531
+ captions = textContainer.querySelectorAll('div');
532
+
533
+ expect(captions.length).toBe(1);
534
+ expect(captions[0].textContent).toBe('You have to learn to listen.');
535
+
536
+ allRegionElements = textContainer.querySelectorAll(
537
+ '.shaka-text-region');
538
+ expect(allRegionElements.length).toBe(1);
539
+ });
464
540
  });
@@ -717,6 +717,24 @@ describe('StreamUtils', () => {
717
717
 
718
718
  expect(manifest.variants.length).toBe(1);
719
719
  });
720
+
721
+ it('supports legacy AVC1 codec', async () => {
722
+ if (!MediaSource.isTypeSupported('video/mp4; codecs="avc1.42001e"')) {
723
+ pending('Codec avc1.42001e is not supported by the platform.');
724
+ }
725
+ manifest = shaka.test.ManifestGenerator.generate((manifest) => {
726
+ manifest.addVariant(0, (variant) => {
727
+ variant.addVideo(1, (stream) => {
728
+ stream.mime('video/mp4', 'avc1.66.30');
729
+ });
730
+ });
731
+ });
732
+
733
+ await shaka.util.StreamUtils.filterManifest(
734
+ fakeDrmEngine, /* currentVariant= */ null, manifest);
735
+
736
+ expect(manifest.variants.length).toBe(1);
737
+ });
720
738
  });
721
739
 
722
740
  describe('chooseCodecsAndFilterManifest', () => {
@@ -425,10 +425,15 @@ describe('XmlUtils', () => {
425
425
  });
426
426
 
427
427
  it('returns null on XML that embeds SVG', () => {
428
+ // Some platforms, such as Xbox One, don't recognize elements as SVG
429
+ // based on namespace alone. So the SVG element below needs to be a real
430
+ // SVG element.
428
431
  const xmlString = [
429
432
  '<?xml version="1.0"?>',
430
433
  '<Root>',
431
- ' <Child xmlns="http://www.w3.org/2000/svg"></Child>',
434
+ ' <svg viewBox="0 0 100 100">',
435
+ ' <rect x="0" y="0" width="100" height"100" />',
436
+ ' </svg>',
432
437
  '</Root>',
433
438
  ].join('\n');
434
439
  const doc = XmlUtils.parseXmlString(xmlString, 'Root');
@@ -798,7 +798,7 @@ goog.Uri.QueryData.prototype.add = function(key, value) {
798
798
  // Invalidate the cache.
799
799
  this.encodedQuery_ = null;
800
800
 
801
- var values = this.keyMap_.hasOwnProperty(key) && this.keyMap_[key];
801
+ var values = this.keyMap_.hasOwnProperty(key) ? this.keyMap_[key] : null;
802
802
  if (!values) {
803
803
  this.keyMap_[key] = (values = []);
804
804
  }
package/ui/controls.js CHANGED
@@ -587,48 +587,61 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
587
587
  return false;
588
588
  }
589
589
 
590
- /** @export */
591
- async toggleFullScreen() {
592
- if (document.fullscreenEnabled) {
593
- if (document.fullscreenElement) {
594
- if (screen.orientation) {
595
- screen.orientation.unlock();
590
+ /** @private */
591
+ async enterFullScreen_() {
592
+ try {
593
+ if (document.fullscreenEnabled) {
594
+ if (document.pictureInPictureElement) {
595
+ await document.exitPictureInPicture();
596
+ }
597
+ await this.videoContainer_.requestFullscreen({navigationUI: 'hide'});
598
+
599
+ if (this.config_.forceLandscapeOnFullscreen && screen.orientation) {
600
+ // Locking to 'landscape' should let it be either
601
+ // 'landscape-primary' or 'landscape-secondary' as appropriate.
602
+ // We ignore errors from this specific call, since it creates noise
603
+ // on desktop otherwise.
604
+ try {
605
+ await screen.orientation.lock('landscape');
606
+ } catch (error) {}
596
607
  }
597
- await document.exitFullscreen();
598
608
  } else {
599
- // If we are in PiP mode, leave PiP mode first.
600
- try {
601
- if (document.pictureInPictureElement) {
602
- await document.exitPictureInPicture();
603
- }
604
- await this.videoContainer_.requestFullscreen({navigationUI: 'hide'});
605
- if (this.config_.forceLandscapeOnFullscreen && screen.orientation) {
606
- try {
607
- // Locking to 'landscape' should let it be either
608
- // 'landscape-primary' or 'landscape-secondary' as appropriate.
609
- await screen.orientation.lock('landscape');
610
- } catch (error) {
611
- // If screen.orientation.lock does not work on a device, it will
612
- // be rejected with an error. Suppress that error.
613
- }
614
- }
615
- } catch (error) {
616
- this.dispatchEvent(new shaka.util.FakeEvent(
617
- 'error', (new Map()).set('detail', error)));
609
+ const video = /** @type {HTMLVideoElement} */(this.localVideo_);
610
+ if (video.webkitSupportsFullscreen) {
611
+ video.webkitEnterFullscreen();
618
612
  }
619
613
  }
614
+ } catch (error) {
615
+ // Entering fullscreen can fail without user interaction.
616
+ this.dispatchEvent(new shaka.util.FakeEvent(
617
+ 'error', (new Map()).set('detail', error)));
618
+ }
619
+ }
620
+
621
+ /** @private */
622
+ async exitFullScreen_() {
623
+ if (document.fullscreenEnabled) {
624
+ if (screen.orientation) {
625
+ screen.orientation.unlock();
626
+ }
627
+ await document.exitFullscreen();
620
628
  } else {
621
629
  const video = /** @type {HTMLVideoElement} */(this.localVideo_);
622
630
  if (video.webkitSupportsFullscreen) {
623
- if (video.webkitDisplayingFullscreen) {
624
- video.webkitExitFullscreen();
625
- } else {
626
- video.webkitEnterFullscreen();
627
- }
631
+ video.webkitExitFullscreen();
628
632
  }
629
633
  }
630
634
  }
631
635
 
636
+ /** @export */
637
+ async toggleFullScreen() {
638
+ if (this.isFullScreenEnabled()) {
639
+ await this.exitFullScreen_();
640
+ } else {
641
+ await this.enterFullScreen_();
642
+ }
643
+ }
644
+
632
645
  /** @export */
633
646
  showAdUI() {
634
647
  shaka.ui.Utils.setDisplay(this.adPanel_, true);
@@ -1030,11 +1043,11 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
1030
1043
  }
1031
1044
 
1032
1045
  if (screen.orientation.type.includes('landscape') &&
1033
- !document.fullscreenElement) {
1034
- await this.videoContainer_.requestFullscreen({navigationUI: 'hide'});
1046
+ !this.isFullScreenEnabled()) {
1047
+ await this.enterFullScreen_();
1035
1048
  } else if (screen.orientation.type.includes('portrait') &&
1036
- document.fullscreenElement) {
1037
- await document.exitFullscreen();
1049
+ this.isFullScreenEnabled()) {
1050
+ await this.exitFullScreen_();
1038
1051
  }
1039
1052
  }
1040
1053
 
@@ -1192,7 +1205,7 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
1192
1205
  // The controls are hidden, so show them.
1193
1206
  this.onMouseMove_(event);
1194
1207
  // Stop this event from becoming a click event.
1195
- event.preventDefault();
1208
+ event.cancelable && event.preventDefault();
1196
1209
  }
1197
1210
  }
1198
1211