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
@@ -0,0 +1,126 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+
8
+ goog.provide('shaka.ui.RecenterVRButton');
9
+
10
+ goog.require('shaka.ui.Controls');
11
+ goog.require('shaka.ui.Element');
12
+ goog.require('shaka.ui.Enums');
13
+ goog.require('shaka.ui.Locales');
14
+ goog.require('shaka.ui.Localization');
15
+ goog.require('shaka.ui.OverflowMenu');
16
+ goog.require('shaka.ui.Utils');
17
+ goog.require('shaka.util.Dom');
18
+ goog.requireType('shaka.ui.Controls');
19
+
20
+
21
+ /**
22
+ * @extends {shaka.ui.Element}
23
+ * @final
24
+ * @export
25
+ */
26
+ shaka.ui.RecenterVRButton = class extends shaka.ui.Element {
27
+ /**
28
+ * @param {!HTMLElement} parent
29
+ * @param {!shaka.ui.Controls} controls
30
+ */
31
+ constructor(parent, controls) {
32
+ super(parent, controls);
33
+
34
+ /** @private {!HTMLButtonElement} */
35
+ this.recenterVRButton_ = shaka.util.Dom.createButton();
36
+ this.recenterVRButton_.classList.add('shaka-recenter-vr-button');
37
+ this.recenterVRButton_.classList.add('shaka-tooltip');
38
+ this.recenterVRButton_.ariaPressed = 'false';
39
+
40
+ /** @private {!HTMLElement} */
41
+ this.recenterVRIcon_ = shaka.util.Dom.createHTMLElement('i');
42
+ this.recenterVRIcon_.classList.add('material-icons-round');
43
+ this.recenterVRIcon_.textContent =
44
+ shaka.ui.Enums.MaterialDesignIcons.RECENTER_VR;
45
+ this.recenterVRButton_.appendChild(this.recenterVRIcon_);
46
+
47
+ const label = shaka.util.Dom.createHTMLElement('label');
48
+ label.classList.add('shaka-overflow-button-label');
49
+ label.classList.add('shaka-overflow-menu-only');
50
+ this.recenterVRNameSpan_ = shaka.util.Dom.createHTMLElement('span');
51
+ label.appendChild(this.recenterVRNameSpan_);
52
+
53
+ this.recenterVRCurrentSelectionSpan_ =
54
+ shaka.util.Dom.createHTMLElement('span');
55
+ this.recenterVRCurrentSelectionSpan_.classList.add(
56
+ 'shaka-current-selection-span');
57
+ label.appendChild(this.recenterVRCurrentSelectionSpan_);
58
+ this.recenterVRButton_.appendChild(label);
59
+ this.parent.appendChild(this.recenterVRButton_);
60
+
61
+ // Setup strings in the correct language
62
+ this.updateLocalizedStrings_();
63
+
64
+ this.eventManager.listen(
65
+ this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
66
+ this.updateLocalizedStrings_();
67
+ });
68
+
69
+ this.eventManager.listen(
70
+ this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
71
+ this.updateLocalizedStrings_();
72
+ });
73
+
74
+ const vr = this.controls.getVR();
75
+
76
+ this.eventManager.listen(this.recenterVRButton_, 'click', () => {
77
+ vr.reset();
78
+ });
79
+
80
+ this.eventManager.listen(vr, 'vrstatuschanged', () => {
81
+ this.checkAvailability_();
82
+ });
83
+
84
+ this.checkAvailability_();
85
+ }
86
+
87
+
88
+ /**
89
+ * @private
90
+ */
91
+ checkAvailability_() {
92
+ shaka.ui.Utils.setDisplay(this.recenterVRButton_,
93
+ this.controls.isPlayingVR());
94
+ }
95
+
96
+
97
+ /**
98
+ * @private
99
+ */
100
+ updateLocalizedStrings_() {
101
+ const LocIds = shaka.ui.Locales.Ids;
102
+
103
+ this.recenterVRButton_.ariaLabel =
104
+ this.localization.resolve(LocIds.RECENTER_VR);
105
+ this.recenterVRNameSpan_.textContent =
106
+ this.localization.resolve(LocIds.RECENTER_VR);
107
+ }
108
+ };
109
+
110
+
111
+ /**
112
+ * @implements {shaka.extern.IUIElement.Factory}
113
+ * @final
114
+ */
115
+ shaka.ui.RecenterVRButton.Factory = class {
116
+ /** @override */
117
+ create(rootElement, controls) {
118
+ return new shaka.ui.RecenterVRButton(rootElement, controls);
119
+ }
120
+ };
121
+
122
+ shaka.ui.OverflowMenu.registerElement(
123
+ 'recenter_vr', new shaka.ui.RecenterVRButton.Factory());
124
+
125
+ shaka.ui.Controls.registerElement(
126
+ 'recenter_vr', new shaka.ui.RecenterVRButton.Factory());
@@ -14,6 +14,7 @@ goog.require('shaka.ui.Enums');
14
14
  goog.require('shaka.ui.Locales');
15
15
  goog.require('shaka.ui.Localization');
16
16
  goog.require('shaka.ui.OverflowMenu');
17
+ goog.require('shaka.ui.Overlay.TrackLabelFormat');
17
18
  goog.require('shaka.ui.SettingsMenu');
18
19
  goog.require('shaka.ui.Utils');
19
20
  goog.require('shaka.util.Dom');
@@ -67,6 +68,7 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
67
68
 
68
69
  /** @private */
69
70
  updateResolutionSelection_() {
71
+ const TrackLabelFormat = shaka.ui.Overlay.TrackLabelFormat;
70
72
  /** @type {!Array.<shaka.extern.Track>} */
71
73
  let tracks = [];
72
74
  // When played with src=, the variant tracks available from
@@ -80,10 +82,28 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
80
82
  // available resolutions.
81
83
  const selectedTrack = tracks.find((track) => track.active);
82
84
  if (selectedTrack) {
83
- // Filter by current audio language and channel count.
84
- tracks = tracks.filter(
85
- (track) => track.language == selectedTrack.language &&
86
- track.channelsCount == selectedTrack.channelsCount);
85
+ tracks = tracks.filter((track) => {
86
+ if (track.language != selectedTrack.language) {
87
+ return false;
88
+ }
89
+ if (this.controls.getConfig().showAudioChannelCountVariants &&
90
+ track.channelsCount != selectedTrack.channelsCount) {
91
+ return false;
92
+ }
93
+ const trackLabelFormat = this.controls.getConfig().trackLabelFormat;
94
+ if ((trackLabelFormat == TrackLabelFormat.ROLE ||
95
+ trackLabelFormat == TrackLabelFormat.LANGUAGE_ROLE)) {
96
+ if (JSON.stringify(track.audioRoles) !=
97
+ JSON.stringify(selectedTrack.audioRoles)) {
98
+ return false;
99
+ }
100
+ }
101
+ if (trackLabelFormat == TrackLabelFormat.LABEL &&
102
+ track.label != selectedTrack.label) {
103
+ return false;
104
+ }
105
+ return true;
106
+ });
87
107
  }
88
108
 
89
109
  // Remove duplicate entries with the same resolution or quality depending
@@ -195,7 +215,7 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
195
215
 
196
216
  this.updateLocalizedStrings_();
197
217
 
198
- shaka.ui.Utils.setDisplay(this.button, tracks.length > 0);
218
+ shaka.ui.Utils.setDisplay(this.button, tracks.length > 1);
199
219
  }
200
220
 
201
221
 
@@ -117,6 +117,17 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
117
117
  return this.currentStats_[name] + ' (stalls)';
118
118
  };
119
119
 
120
+ const parseBytesDownloaded = (name) => {
121
+ const bytes = parseInt(this.currentStats_[name], 10);
122
+ if (bytes > 1e6) {
123
+ return (bytes / 1e6).toFixed(2) + 'MB';
124
+ } else if (bytes > 1e3) {
125
+ return (bytes / 1e3).toFixed(2) + 'KB';
126
+ } else {
127
+ return bytes + 'B';
128
+ }
129
+ };
130
+
120
131
  /** @private {!Object.<string, function(string):string>} */
121
132
  this.parseFrom_ = {
122
133
  'width': parsePx,
@@ -138,6 +149,7 @@ shaka.ui.StatisticsButton = class extends shaka.ui.Element {
138
149
  'droppedFrames': parseFrames,
139
150
  'stallsDetected': parseStalls,
140
151
  'gapsJumped': parseGaps,
152
+ 'bytesDownloaded': parseBytesDownloaded,
141
153
  };
142
154
 
143
155
  /** @private {shaka.util.Timer} */
@@ -135,7 +135,7 @@ shaka.ui.TextSelection = class extends shaka.ui.SettingsMenu {
135
135
  this.player.isTextTrackVisible(),
136
136
  this.currentSelection,
137
137
  this.localization,
138
- this.controls.getConfig().trackLabelFormat,
138
+ this.controls.getConfig().textTrackLabelFormat,
139
139
  this.controls.getConfig().showAudioChannelCountVariants);
140
140
 
141
141
  // Add the Off button
@@ -0,0 +1,127 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+
8
+ goog.provide('shaka.ui.ToggleStereoscopicButton');
9
+
10
+ goog.require('shaka.ui.Controls');
11
+ goog.require('shaka.ui.Element');
12
+ goog.require('shaka.ui.Enums');
13
+ goog.require('shaka.ui.Locales');
14
+ goog.require('shaka.ui.Localization');
15
+ goog.require('shaka.ui.OverflowMenu');
16
+ goog.require('shaka.ui.Utils');
17
+ goog.require('shaka.util.Dom');
18
+ goog.requireType('shaka.ui.Controls');
19
+
20
+
21
+ /**
22
+ * @extends {shaka.ui.Element}
23
+ * @final
24
+ * @export
25
+ */
26
+ shaka.ui.ToggleStereoscopicButton = class extends shaka.ui.Element {
27
+ /**
28
+ * @param {!HTMLElement} parent
29
+ * @param {!shaka.ui.Controls} controls
30
+ */
31
+ constructor(parent, controls) {
32
+ super(parent, controls);
33
+
34
+ /** @private {!HTMLButtonElement} */
35
+ this.toggleStereoscopicButton_ = shaka.util.Dom.createButton();
36
+ this.toggleStereoscopicButton_.classList.add(
37
+ 'shaka-toggle-stereoscopic-button');
38
+ this.toggleStereoscopicButton_.classList.add('shaka-tooltip');
39
+ this.toggleStereoscopicButton_.ariaPressed = 'false';
40
+
41
+ /** @private {!HTMLElement} */
42
+ this.toggleStereoscopicIcon_ = shaka.util.Dom.createHTMLElement('i');
43
+ this.toggleStereoscopicIcon_.classList.add('material-icons-round');
44
+ this.toggleStereoscopicIcon_.textContent =
45
+ shaka.ui.Enums.MaterialDesignIcons.TOGGLE_STEREOSCOPIC;
46
+ this.toggleStereoscopicButton_.appendChild(this.toggleStereoscopicIcon_);
47
+
48
+ const label = shaka.util.Dom.createHTMLElement('label');
49
+ label.classList.add('shaka-overflow-button-label');
50
+ label.classList.add('shaka-overflow-menu-only');
51
+ this.toggleStereoscopicNameSpan_ = shaka.util.Dom.createHTMLElement('span');
52
+ label.appendChild(this.toggleStereoscopicNameSpan_);
53
+
54
+ this.toggleStereoscopicCurrentSelectionSpan_ =
55
+ shaka.util.Dom.createHTMLElement('span');
56
+ this.toggleStereoscopicCurrentSelectionSpan_.classList.add(
57
+ 'shaka-current-selection-span');
58
+ label.appendChild(this.toggleStereoscopicCurrentSelectionSpan_);
59
+ this.toggleStereoscopicButton_.appendChild(label);
60
+ this.parent.appendChild(this.toggleStereoscopicButton_);
61
+
62
+ // Setup strings in the correct language
63
+ this.updateLocalizedStrings_();
64
+
65
+ this.eventManager.listen(
66
+ this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
67
+ this.updateLocalizedStrings_();
68
+ });
69
+
70
+ this.eventManager.listen(
71
+ this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
72
+ this.updateLocalizedStrings_();
73
+ });
74
+
75
+ const vr = this.controls.getVR();
76
+
77
+ this.eventManager.listen(this.toggleStereoscopicButton_, 'click', () => {
78
+ vr.toggleStereoscopicMode();
79
+ });
80
+
81
+ this.eventManager.listen(vr, 'vrstatuschanged', () => {
82
+ this.checkAvailability_();
83
+ });
84
+
85
+ this.checkAvailability_();
86
+ }
87
+
88
+
89
+ /**
90
+ * @private
91
+ */
92
+ checkAvailability_() {
93
+ shaka.ui.Utils.setDisplay(this.toggleStereoscopicButton_,
94
+ this.controls.isPlayingVR());
95
+ }
96
+
97
+
98
+ /**
99
+ * @private
100
+ */
101
+ updateLocalizedStrings_() {
102
+ const LocIds = shaka.ui.Locales.Ids;
103
+
104
+ this.toggleStereoscopicButton_.ariaLabel =
105
+ this.localization.resolve(LocIds.TOGGLE_STEREOSCOPIC);
106
+ this.toggleStereoscopicNameSpan_.textContent =
107
+ this.localization.resolve(LocIds.TOGGLE_STEREOSCOPIC);
108
+ }
109
+ };
110
+
111
+
112
+ /**
113
+ * @implements {shaka.extern.IUIElement.Factory}
114
+ * @final
115
+ */
116
+ shaka.ui.ToggleStereoscopicButton.Factory = class {
117
+ /** @override */
118
+ create(rootElement, controls) {
119
+ return new shaka.ui.ToggleStereoscopicButton(rootElement, controls);
120
+ }
121
+ };
122
+
123
+ shaka.ui.OverflowMenu.registerElement(
124
+ 'toggle_stereoscopic', new shaka.ui.ToggleStereoscopicButton.Factory());
125
+
126
+ shaka.ui.Controls.registerElement(
127
+ 'toggle_stereoscopic', new shaka.ui.ToggleStereoscopicButton.Factory());
package/ui/ui.js CHANGED
@@ -29,8 +29,9 @@ shaka.ui.Overlay = class {
29
29
  * @param {!shaka.Player} player
30
30
  * @param {!HTMLElement} videoContainer
31
31
  * @param {!HTMLMediaElement} video
32
+ * @param {?HTMLCanvasElement=} vrCanvas
32
33
  */
33
- constructor(player, videoContainer, video) {
34
+ constructor(player, videoContainer, video, vrCanvas = null) {
34
35
  /** @private {shaka.Player} */
35
36
  this.player_ = player;
36
37
 
@@ -52,7 +53,7 @@ shaka.ui.Overlay = class {
52
53
 
53
54
  /** @private {shaka.ui.Controls} */
54
55
  this.controls_ = new shaka.ui.Controls(
55
- player, videoContainer, video, this.config_);
56
+ player, videoContainer, video, vrCanvas, this.config_);
56
57
 
57
58
  // Run the initial setup so that no configure() call is required for default
58
59
  // settings.
@@ -189,6 +190,8 @@ shaka.ui.Overlay = class {
189
190
  'picture_in_picture',
190
191
  'cast',
191
192
  'playback_rate',
193
+ 'recenter_vr',
194
+ 'toggle_stereoscopic',
192
195
  ],
193
196
  statisticsList: [
194
197
  'width',
@@ -208,6 +211,7 @@ shaka.ui.Overlay = class {
208
211
  'pauseTime',
209
212
  'playTime',
210
213
  'completionPercent',
214
+ 'bytesDownloaded',
211
215
  ],
212
216
  contextMenuElements: [
213
217
  'loop',
@@ -235,6 +239,7 @@ shaka.ui.Overlay = class {
235
239
  level: 'rgb(255, 255, 255)',
236
240
  },
237
241
  trackLabelFormat: shaka.ui.Overlay.TrackLabelFormat.LANGUAGE,
242
+ textTrackLabelFormat: shaka.ui.Overlay.TrackLabelFormat.LANGUAGE,
238
243
  fadeDelay: 0,
239
244
  doubleClickForFullscreen: true,
240
245
  singleClickForPlayAndPause: true,
@@ -249,6 +254,9 @@ shaka.ui.Overlay = class {
249
254
  showAudioChannelCountVariants: true,
250
255
  seekOnTaps: true,
251
256
  tapSeekDistance: 10,
257
+ refreshTickInSeconds: 0.125,
258
+ displayInVrMode: false,
259
+ defaultVrProjectionMode: 'equirectangular',
252
260
  };
253
261
 
254
262
  // eslint-disable-next-line no-restricted-syntax
@@ -307,6 +315,12 @@ shaka.ui.Overlay = class {
307
315
  const canvases = document.querySelectorAll(
308
316
  '[data-shaka-player-canvas]');
309
317
 
318
+ // Look for elements marked 'data-shaka-player-vr-canvas'
319
+ // on the page. These will be used to create our default
320
+ // UI.
321
+ const vrCanvases = document.querySelectorAll(
322
+ '[data-shaka-player-vr-canvas]');
323
+
310
324
  if (!videos.length && !containers.length) {
311
325
  // No elements have been tagged with shaka attributes.
312
326
  } else if (videos.length && !containers.length) {
@@ -324,21 +338,11 @@ shaka.ui.Overlay = class {
324
338
  const videoParent = video.parentElement;
325
339
  videoParent.replaceChild(container, video);
326
340
  container.appendChild(video);
327
- let currentCanvas = null;
328
- for (const canvas of canvases) {
329
- goog.asserts.assert(canvas.tagName.toLowerCase() == 'canvas',
330
- 'Should be a canvas element!');
331
- if (canvas.parentElement == container) {
332
- currentCanvas = canvas;
333
- break;
334
- }
335
- }
336
- if (!currentCanvas) {
337
- currentCanvas = document.createElement('canvas');
338
- currentCanvas.classList.add('shaka-canvas-container');
339
- container.appendChild(currentCanvas);
340
- }
341
- shaka.ui.Overlay.setupUIandAutoLoad_(container, video, currentCanvas);
341
+ const {lcevcCanvas, vrCanvas} =
342
+ shaka.ui.Overlay.findOrMakeSpecialCanvases_(
343
+ container, canvases, vrCanvases);
344
+ shaka.ui.Overlay.setupUIandAutoLoad_(
345
+ container, video, lcevcCanvas, vrCanvas);
342
346
  }
343
347
  } else {
344
348
  for (const container of containers) {
@@ -365,26 +369,13 @@ shaka.ui.Overlay = class {
365
369
  currentVideo.setAttribute('playsinline', '');
366
370
  container.appendChild(currentVideo);
367
371
  }
368
-
369
- let currentCanvas = null;
370
- for (const canvas of canvases) {
371
- goog.asserts.assert(canvas.tagName.toLowerCase() == 'canvas',
372
- 'Should be a canvas element!');
373
- if (canvas.parentElement == container) {
374
- currentCanvas = canvas;
375
- break;
376
- }
377
- }
378
- if (!currentCanvas) {
379
- currentCanvas = document.createElement('canvas');
380
- currentCanvas.classList.add('shaka-canvas-container');
381
- container.appendChild(currentCanvas);
382
- }
383
-
372
+ const {lcevcCanvas, vrCanvas} =
373
+ shaka.ui.Overlay.findOrMakeSpecialCanvases_(
374
+ container, canvases, vrCanvases);
384
375
  try {
385
376
  // eslint-disable-next-line no-await-in-loop
386
377
  await shaka.ui.Overlay.setupUIandAutoLoad_(
387
- container, currentVideo, currentCanvas);
378
+ container, currentVideo, lcevcCanvas, vrCanvas);
388
379
  } catch (e) {
389
380
  // This can fail if, for example, not every player file has loaded.
390
381
  // Ad-block is a likely cause for this sort of failure.
@@ -423,18 +414,20 @@ shaka.ui.Overlay = class {
423
414
  /**
424
415
  * @param {!Element} container
425
416
  * @param {!Element} video
426
- * @param {!Element} canvas
417
+ * @param {!Element} lcevcCanvas
418
+ * @param {!Element} vrCanvas
427
419
  * @private
428
420
  */
429
- static async setupUIandAutoLoad_(container, video, canvas) {
421
+ static async setupUIandAutoLoad_(container, video, lcevcCanvas, vrCanvas) {
430
422
  // Create the UI
431
423
  const player = new shaka.Player();
432
424
  const ui = new shaka.ui.Overlay(player,
433
425
  shaka.util.Dom.asHTMLElement(container),
434
- shaka.util.Dom.asHTMLMediaElement(video));
426
+ shaka.util.Dom.asHTMLMediaElement(video),
427
+ shaka.util.Dom.asHTMLCanvasElement(vrCanvas));
435
428
 
436
429
  // Attach Canvas used for LCEVC Decoding
437
- player.attachCanvas(/** @type {HTMLCanvasElement} */(canvas));
430
+ player.attachCanvas(/** @type {HTMLCanvasElement} */(lcevcCanvas));
438
431
 
439
432
  // Get and configure cast app id.
440
433
  let castAppId = '';
@@ -494,6 +487,49 @@ shaka.ui.Overlay = class {
494
487
 
495
488
  await player.attach(shaka.util.Dom.asHTMLMediaElement(video));
496
489
  }
490
+
491
+
492
+ /**
493
+ * @param {!Element} container
494
+ * @param {!NodeList.<!Element>} canvases
495
+ * @param {!NodeList.<!Element>} vrCanvases
496
+ * @return {{lcevcCanvas: !Element, vrCanvas: !Element}}
497
+ * @private
498
+ */
499
+ static findOrMakeSpecialCanvases_(container, canvases, vrCanvases) {
500
+ let lcevcCanvas = null;
501
+ for (const canvas of canvases) {
502
+ goog.asserts.assert(canvas.tagName.toLowerCase() == 'canvas',
503
+ 'Should be a canvas element!');
504
+ if (canvas.parentElement == container) {
505
+ lcevcCanvas = canvas;
506
+ break;
507
+ }
508
+ }
509
+ if (!lcevcCanvas) {
510
+ lcevcCanvas = document.createElement('canvas');
511
+ lcevcCanvas.classList.add('shaka-canvas-container');
512
+ container.appendChild(lcevcCanvas);
513
+ }
514
+ let vrCanvas = null;
515
+ for (const canvas of vrCanvases) {
516
+ goog.asserts.assert(canvas.tagName.toLowerCase() == 'canvas',
517
+ 'Should be a canvas element!');
518
+ if (canvas.parentElement == container) {
519
+ vrCanvas = canvas;
520
+ break;
521
+ }
522
+ }
523
+ if (!vrCanvas) {
524
+ vrCanvas = document.createElement('canvas');
525
+ vrCanvas.classList.add('shaka-vr-canvas-container');
526
+ container.appendChild(vrCanvas);
527
+ }
528
+ return {
529
+ lcevcCanvas,
530
+ vrCanvas,
531
+ };
532
+ }
497
533
  };
498
534
 
499
535
  /**