shaka-player 2.5.4 → 2.5.5

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 (102) hide show
  1. package/.csslintrc +13 -0
  2. package/CHANGELOG.md +56 -0
  3. package/build/build.py +4 -1
  4. package/build/check.py +17 -0
  5. package/build/compiler.py +40 -0
  6. package/build/types/core +1 -0
  7. package/build/types/ui +4 -1
  8. package/demo/asset_card.js +41 -11
  9. package/demo/cast_receiver/receiver_app.css +19 -13
  10. package/demo/close_button.js +0 -6
  11. package/demo/common/asset.js +6 -1
  12. package/demo/common/assets.js +72 -14
  13. package/demo/demo.less +105 -16
  14. package/demo/index.html +8 -5
  15. package/demo/load.js +5 -7
  16. package/demo/main.js +81 -16
  17. package/dist/.csslintstamp +0 -0
  18. package/dist/controls.css +1 -1
  19. package/dist/controls.css.map +1 -1
  20. package/dist/demo.compiled.debug.js +46 -39
  21. package/dist/demo.compiled.debug.map +3 -3
  22. package/dist/demo.compiled.js +46 -39
  23. package/dist/demo.compiled.map +3 -3
  24. package/dist/demo.css +1 -1
  25. package/dist/demo.css.map +1 -1
  26. package/dist/deps.js +11 -7
  27. package/dist/receiver.compiled.debug.js +10 -6
  28. package/dist/receiver.compiled.debug.map +3 -3
  29. package/dist/receiver.compiled.js +10 -6
  30. package/dist/receiver.compiled.map +3 -3
  31. package/dist/shaka-player.compiled.debug.externs.js +123 -92
  32. package/dist/shaka-player.compiled.debug.js +113 -105
  33. package/dist/shaka-player.compiled.debug.map +4 -4
  34. package/dist/shaka-player.compiled.externs.js +123 -92
  35. package/dist/shaka-player.compiled.js +551 -548
  36. package/dist/shaka-player.compiled.map +4 -4
  37. package/dist/shaka-player.ui.debug.externs.js +170 -101
  38. package/dist/shaka-player.ui.debug.js +187 -188
  39. package/dist/shaka-player.ui.debug.map +4 -4
  40. package/dist/shaka-player.ui.externs.js +170 -101
  41. package/dist/shaka-player.ui.js +651 -651
  42. package/dist/shaka-player.ui.map +3 -3
  43. package/docs/tutorials/drm-config.md +1 -0
  44. package/docs/tutorials/fairplay.md +77 -0
  45. package/docs/tutorials/index.json +1 -0
  46. package/docs/tutorials/ui-customization.md +3 -0
  47. package/docs/tutorials/ui.md +3 -1
  48. package/externs/mediasession.js +16 -1
  49. package/externs/shaka/net.js +5 -1
  50. package/externs/shaka/player.js +136 -90
  51. package/externs/webkitmediakeys.js +4 -0
  52. package/lib/dash/content_protection.js +33 -1
  53. package/lib/dash/dash_parser.js +12 -4
  54. package/lib/hls/hls_parser.js +20 -4
  55. package/lib/media/drm_engine.js +29 -2
  56. package/lib/media/media_source_engine.js +7 -3
  57. package/lib/media/playhead.js +8 -3
  58. package/lib/media/streaming_engine.js +24 -8
  59. package/lib/media/video_wrapper.js +8 -3
  60. package/lib/net/networking_engine.js +1 -0
  61. package/lib/player.js +3 -2
  62. package/lib/polyfill/patchedmediakeys_apple.js +2 -72
  63. package/lib/util/error.js +12 -0
  64. package/lib/util/fairplay_utils.js +122 -0
  65. package/lib/util/player_configuration.js +5 -0
  66. package/lib/util/pssh.js +41 -0
  67. package/package.json +4 -3
  68. package/shaka-player.uncompiled.js +5 -1
  69. package/test/dash/dash_parser_content_protection_unit.js +35 -1
  70. package/test/dash/dash_parser_manifest_unit.js +31 -0
  71. package/test/hls/hls_live_unit.js +7 -1
  72. package/test/hls/hls_parser_unit.js +50 -0
  73. package/test/media/media_source_engine_integration.js +12 -0
  74. package/test/media/playhead_unit.js +2 -0
  75. package/test/player_external.js +3 -2
  76. package/test/player_integration.js +75 -0
  77. package/test/test/externs/jasmine.js +6 -0
  78. package/test/test/util/test_scheme.js +32 -1
  79. package/test/test/util/ui_utils.js +41 -0
  80. package/test/ui/ui_unit.js +129 -3
  81. package/ui/audio_language_selection.js +17 -96
  82. package/ui/big_play_button.js +61 -0
  83. package/ui/controls.js +111 -86
  84. package/ui/controls.less +3 -5
  85. package/ui/externs/ui.js +14 -2
  86. package/ui/fullscreen_button.js +2 -52
  87. package/ui/less/buttons.less +8 -8
  88. package/ui/less/containers.less +21 -21
  89. package/ui/less/general.less +11 -0
  90. package/ui/less/other_elements.less +2 -1
  91. package/ui/less/overflow_menu.less +11 -10
  92. package/ui/less/range_elements.less +6 -0
  93. package/ui/less/spinner.less +2 -0
  94. package/ui/pip_button.js +1 -1
  95. package/ui/{play_pause_button.js → play_button.js} +17 -47
  96. package/ui/resolution_selection.js +41 -104
  97. package/ui/seek_bar.js +15 -17
  98. package/ui/settings_menu.js +113 -0
  99. package/ui/small_play_button.js +73 -0
  100. package/ui/text_displayer.js +2 -2
  101. package/ui/text_selection.js +39 -105
  102. package/ui/ui.js +12 -0
@@ -29,7 +29,7 @@
29
29
 
30
30
  /* Styles for the menu itself. */
31
31
  background: white;
32
- box-shadow: 0 1px 9px 0 rgba(0,0,0,0.40);
32
+ box-shadow: 0 1px 9px 0 rgba(0, 0, 0, 0.4);
33
33
  border-radius: 2px;
34
34
  max-height: 250px;
35
35
  min-width: 180px;
@@ -64,20 +64,21 @@
64
64
  &:hover {
65
65
  background: rgb(224, 224, 224);
66
66
  }
67
+
67
68
  .shaka-keyboard-navigation &:focus {
68
69
  background: rgb(224, 224, 224);
69
70
  }
70
71
  }
71
72
 
72
- /* These are the elements which contain the material design icons. */
73
- /* TODO: Pull MD icon details out of JS. */
73
+ /* These are the elements which contain the material design icons.
74
+ * TODO: Pull MD icon details out of JS. */
74
75
  i {
75
76
  /* TODO(b/116651454): eliminate hard-coded offsets */
76
77
  padding-left: 10px;
77
78
  }
78
79
 
79
- /* If the seekbar is missing, this is positioned lower. */
80
- /* TODO: Solve with flex layout instead? */
80
+ /* If the seekbar is missing, this is positioned lower.
81
+ * TODO: Solve with flex layout instead? */
81
82
  &.shaka-low-position {
82
83
  /* TODO(b/116651454): eliminate hard-coded offsets */
83
84
  bottom: 15px;
@@ -93,6 +94,7 @@
93
94
  .shaka-overflow-menu span {
94
95
  text-align: left;
95
96
  position: relative;
97
+
96
98
  /* TODO(b/116651454): eliminate hard-coded offsets */
97
99
  left: 13px;
98
100
  }
@@ -101,6 +103,7 @@
101
103
  * right of MD icons. */
102
104
  .shaka-overflow-button-label {
103
105
  position: relative;
106
+
104
107
  /* This is a flex container, whose children flow vertically. */
105
108
  display: flex;
106
109
  flex-direction: column;
@@ -114,12 +117,10 @@
114
117
  color: rgba(0, 0, 0, 0.54);
115
118
  }
116
119
 
117
- /* These three submenus have somewhat different margins inside them. */
118
- /* TODO: This is all submenus, but not the top-level menu. Is there a better
120
+ /* These three submenus have somewhat different margins inside them.
121
+ * TODO: This is all submenus, but not the top-level menu. Is there a better
119
122
  * way to express this? */
120
- .shaka-resolutions,
121
- .shaka-audio-languages,
122
- .shaka-text-languages {
123
+ .shaka-resolutions, .shaka-audio-languages, .shaka-text-languages {
123
124
  span {
124
125
  /* TODO(b/116651454): eliminate hard-coded offsets */
125
126
  margin-left: 54px;
@@ -51,8 +51,10 @@
51
51
 
52
52
  /* Vertical margins to occupy the same space as the thumb. */
53
53
  margin: (@thumb-size - @track-height)/2 6px;
54
+
54
55
  /* Smaller height to contain the background for the virtual track. */
55
56
  height: @track-height;
57
+
56
58
  /* Rounded ends on the virtual track. */
57
59
  border-radius: @track-height;
58
60
 
@@ -123,6 +125,7 @@
123
125
  &::-webkit-slider-runnable-track {
124
126
  .track();
125
127
  }
128
+
126
129
  &::-webkit-slider-thumb {
127
130
  .thumb();
128
131
  }
@@ -131,6 +134,7 @@
131
134
  &::-moz-range-track {
132
135
  .track();
133
136
  }
137
+
134
138
  &::-moz-range-thumb {
135
139
  .thumb();
136
140
  }
@@ -139,6 +143,7 @@
139
143
  &::-ms-track {
140
144
  .track();
141
145
  }
146
+
142
147
  &::-ms-thumb {
143
148
  .thumb();
144
149
  }
@@ -152,6 +157,7 @@
152
157
  &::-ms-fill-lower {
153
158
  .hidden();
154
159
  }
160
+
155
161
  &::-ms-fill-upper {
156
162
  .hidden();
157
163
  }
@@ -71,10 +71,12 @@
71
71
  stroke-dasharray: 1, 200;
72
72
  stroke-dashoffset: 0;
73
73
  }
74
+
74
75
  50% {
75
76
  stroke-dasharray: 89, 200;
76
77
  stroke-dashoffset: -35px;
77
78
  }
79
+
78
80
  100% {
79
81
  stroke-dasharray: 89, 200;
80
82
  stroke-dashoffset: -124px;
package/ui/pip_button.js CHANGED
@@ -100,7 +100,7 @@ shaka.ui.PipButton = class extends shaka.ui.Element {
100
100
  this.onLeavePictureInPicture_();
101
101
  });
102
102
 
103
- this.eventManager.listen(this.controls, 'caststatuschange', (e) => {
103
+ this.eventManager.listen(this.controls, 'caststatuschanged', (e) => {
104
104
  this.onCastStatusChange_(e);
105
105
  });
106
106
 
@@ -16,10 +16,9 @@
16
16
  */
17
17
 
18
18
 
19
- goog.provide('shaka.ui.PlayPauseButton');
19
+ goog.provide('shaka.ui.PlayButton');
20
20
 
21
21
  goog.require('shaka.ui.Element');
22
- goog.require('shaka.ui.Enums');
23
22
  goog.require('shaka.ui.Locales');
24
23
  goog.require('shaka.ui.Localization');
25
24
  goog.require('shaka.util.Dom');
@@ -27,10 +26,9 @@ goog.require('shaka.util.Dom');
27
26
 
28
27
  /**
29
28
  * @extends {shaka.ui.Element}
30
- * @final
31
29
  * @export
32
30
  */
33
- shaka.ui.PlayPauseButton = class extends shaka.ui.Element {
31
+ shaka.ui.PlayButton = class extends shaka.ui.Element {
34
32
  /**
35
33
  * @param {!HTMLElement} parent
36
34
  * @param {!shaka.ui.Controls} controls
@@ -38,37 +36,30 @@ shaka.ui.PlayPauseButton = class extends shaka.ui.Element {
38
36
  constructor(parent, controls) {
39
37
  super(parent, controls);
40
38
 
41
- /** @private {!HTMLElement} */
42
- this.button_ = shaka.util.Dom.createHTMLElement('button');
43
- this.button_.classList.add('shaka-play-pause-button');
44
- this.button_.classList.add('material-icons');
45
- this.parent.appendChild(this.button_);
46
-
47
- this.updateIcon_();
48
- this.updateAriaLabel_();
39
+ /** @protected {!HTMLElement} */
40
+ this.button = shaka.util.Dom.createHTMLElement('button');
41
+ this.parent.appendChild(this.button);
49
42
 
50
43
  const LOCALE_UPDATED = shaka.ui.Localization.LOCALE_UPDATED;
51
44
  this.eventManager.listen(this.localization, LOCALE_UPDATED, () => {
52
- this.updateAriaLabel_();
45
+ this.updateAriaLabel();
53
46
  });
54
47
 
55
48
  const LOCALE_CHANGED = shaka.ui.Localization.LOCALE_CHANGED;
56
49
  this.eventManager.listen(this.localization, LOCALE_CHANGED, () => {
57
- this.updateAriaLabel_();
50
+ this.updateAriaLabel();
58
51
  });
59
52
 
60
53
  this.eventManager.listen(this.video, 'play', () => {
61
- this.updateAriaLabel_();
62
- this.updateIcon_();
54
+ this.updateAriaLabel();
63
55
  });
64
56
 
65
57
  this.eventManager.listen(this.video, 'pause', () => {
66
- this.updateAriaLabel_();
67
- this.updateIcon_();
58
+ this.updateAriaLabel();
68
59
  });
69
60
 
70
- this.eventManager.listen(this.button_, 'click', () => {
71
- if (this.isPaused_()) {
61
+ this.eventManager.listen(this.button, 'click', () => {
62
+ if (this.isPaused()) {
72
63
  this.video.play();
73
64
  } else {
74
65
  this.video.pause();
@@ -78,41 +69,20 @@ shaka.ui.PlayPauseButton = class extends shaka.ui.Element {
78
69
 
79
70
  /**
80
71
  * @return {boolean}
81
- * @private
72
+ * @protected
82
73
  */
83
- isPaused_() {
74
+ isPaused() {
84
75
  // The video element is in a paused state while seeking, but we don't count
85
76
  // that.
86
77
  return this.video.paused && !this.controls.isSeeking();
87
78
  }
88
79
 
89
- /** @private */
90
- updateAriaLabel_() {
80
+ /** @protected */
81
+ updateAriaLabel() {
91
82
  const LocIds = shaka.ui.Locales.Ids;
92
- const label = this.isPaused_() ? LocIds.PLAY : LocIds.PAUSE;
83
+ const label = this.isPaused() ? LocIds.PLAY : LocIds.PAUSE;
93
84
 
94
- this.button_.setAttribute(shaka.ui.Constants.ARIA_LABEL,
85
+ this.button.setAttribute(shaka.ui.Constants.ARIA_LABEL,
95
86
  this.localization.resolve(label));
96
87
  }
97
-
98
- /** @private */
99
- updateIcon_() {
100
- const Icons = shaka.ui.Enums.MaterialDesignIcons;
101
- this.button_.textContent = this.isPaused_() ? Icons.PLAY : Icons.PAUSE;
102
- }
103
- };
104
-
105
-
106
- /**
107
- * @implements {shaka.extern.IUIElement.Factory}
108
- * @final
109
- */
110
- shaka.ui.PlayPauseButton.Factory = class {
111
- /** @override */
112
- create(rootElement, controls) {
113
- return new shaka.ui.PlayPauseButton(rootElement, controls);
114
- }
115
88
  };
116
-
117
- shaka.ui.Controls.registerElement(
118
- 'play_pause', new shaka.ui.PlayPauseButton.Factory());
@@ -18,30 +18,29 @@
18
18
 
19
19
  goog.provide('shaka.ui.ResolutionSelection');
20
20
 
21
- goog.require('shaka.ui.Element');
22
21
  goog.require('shaka.ui.Enums');
23
22
  goog.require('shaka.ui.Locales');
24
23
  goog.require('shaka.ui.Localization');
25
24
  goog.require('shaka.ui.OverflowMenu');
25
+ goog.require('shaka.ui.SettingsMenu');
26
26
  goog.require('shaka.util.Dom');
27
27
 
28
28
 
29
29
  /**
30
- * @extends {shaka.ui.Element}
30
+ * @extends {shaka.ui.SettingsMenu}
31
31
  * @final
32
32
  * @export
33
33
  */
34
- shaka.ui.ResolutionSelection = class extends shaka.ui.Element {
34
+ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
35
35
  /**
36
36
  * @param {!HTMLElement} parent
37
37
  * @param {!shaka.ui.Controls} controls
38
38
  */
39
39
  constructor(parent, controls) {
40
- super(parent, controls);
40
+ super(parent, controls, shaka.ui.Enums.MaterialDesignIcons.RESOLUTION);
41
41
 
42
- this.addResolutionButton_();
43
-
44
- this.addResolutionMenu_();
42
+ this.button.classList.add('shaka-resolution-button');
43
+ this.menu.classList.add('shaka-resolutions');
45
44
 
46
45
  this.eventManager.listen(
47
46
  this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
@@ -53,9 +52,6 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.Element {
53
52
  this.updateLocalizedStrings_();
54
53
  });
55
54
 
56
- this.eventManager.listen(this.resolutionButton_, 'click', () => {
57
- this.onResolutionClick_();
58
- });
59
55
 
60
56
  this.eventManager.listen(this.player, 'variantchanged', () => {
61
57
  this.updateResolutionSelection_();
@@ -76,108 +72,56 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.Element {
76
72
  }
77
73
 
78
74
 
79
- /**
80
- * @private
81
- */
82
- addResolutionButton_() {
83
- /** @private {!HTMLElement}*/
84
- this.resolutionButton_ = shaka.util.Dom.createHTMLElement('button');
85
-
86
- this.resolutionButton_.classList.add('shaka-resolution-button');
87
-
88
- const icon = shaka.util.Dom.createHTMLElement('i');
89
- icon.classList.add('material-icons');
90
- icon.textContent = shaka.ui.Enums.MaterialDesignIcons.RESOLUTION;
91
- this.resolutionButton_.appendChild(icon);
92
-
93
- const label = shaka.util.Dom.createHTMLElement('label');
94
- label.classList.add('shaka-overflow-button-label');
95
-
96
- /** @private {!HTMLElement}*/
97
- this.resolutionNameSpan_ = shaka.util.Dom.createHTMLElement('span');
98
- label.appendChild(this.resolutionNameSpan_);
99
-
100
- /** @private {!HTMLElement}*/
101
- this.currentResolution_ = shaka.util.Dom.createHTMLElement('span');
102
- this.currentResolution_.classList.add('shaka-current-selection-span');
103
- label.appendChild(this.currentResolution_);
104
- this.resolutionButton_.appendChild(label);
105
-
106
- this.parent.appendChild(this.resolutionButton_);
107
- }
108
-
109
-
110
- /**
111
- * @private
112
- */
113
- addResolutionMenu_() {
114
- /** @private {!HTMLElement}*/
115
- this.resolutionMenu_ = shaka.util.Dom.createHTMLElement('div');
116
- this.resolutionMenu_.classList.add('shaka-resolutions');
117
- this.resolutionMenu_.classList.add('shaka-no-propagation');
118
- this.resolutionMenu_.classList.add('shaka-show-controls-on-mouse-over');
119
- this.resolutionMenu_.classList.add('shaka-settings-menu');
120
-
121
- /** @private {!HTMLElement}*/
122
- this.backFromResolutionButton_ =
123
- shaka.util.Dom.createHTMLElement('button');
124
- this.backFromResolutionButton_.classList.add(
125
- 'shaka-back-to-overflow-button');
126
- this.resolutionMenu_.appendChild(this.backFromResolutionButton_);
127
-
128
- const backIcon = shaka.util.Dom.createHTMLElement('i');
129
- backIcon.classList.add('material-icons');
130
- backIcon.textContent = shaka.ui.Enums.MaterialDesignIcons.BACK;
131
- this.backFromResolutionButton_.appendChild(backIcon);
132
-
133
- /** @private {!HTMLElement}*/
134
- this.backFromResolutionSpan_ = shaka.util.Dom.createHTMLElement('span');
135
- this.backFromResolutionButton_.appendChild(this.backFromResolutionSpan_);
136
-
137
- const controlsContainer = this.controls.getControlsContainer();
138
- controlsContainer.appendChild(this.resolutionMenu_);
139
- }
140
-
141
-
142
75
  /** @private */
143
76
  updateResolutionSelection_() {
77
+ /** @type {!Array.<shaka.extern.Track>} */
144
78
  let tracks = this.player.getVariantTracks();
145
79
 
146
80
  // Hide resolution menu and button for audio-only content and src= content
147
81
  // without resolution information.
82
+ // TODO: for audio-only content, this should be a bitrate selection menu
83
+ // instead.
148
84
  if (tracks.length && !tracks[0].height) {
149
- shaka.ui.Utils.setDisplay(this.resolutionMenu_, false);
150
- shaka.ui.Utils.setDisplay(this.resolutionButton_, false);
85
+ shaka.ui.Utils.setDisplay(this.menu, false);
86
+ shaka.ui.Utils.setDisplay(this.button, false);
151
87
  return;
152
88
  }
153
89
  // Otherwise, restore it.
154
- shaka.ui.Utils.setDisplay(this.resolutionButton_, true);
90
+ shaka.ui.Utils.setDisplay(this.button, true);
155
91
 
156
- tracks.sort(function(t1, t2) {
157
- return t1.height - t2.height;
92
+ tracks.sort((t1, t2) => {
93
+ return t2.height - t1.height;
158
94
  });
159
- tracks.reverse();
160
95
 
161
96
  // If there is a selected variant track, then we filter out any tracks in
162
97
  // a different language. Then we use those remaining tracks to display the
163
98
  // available resolutions.
164
99
  const selectedTrack = tracks.find((track) => track.active);
165
100
  if (selectedTrack) {
166
- const language = selectedTrack.language;
167
- // Filter by current audio language.
168
- tracks = tracks.filter((track) => track.language == language);
101
+ // Filter by current audio language and channel count.
102
+ tracks = tracks.filter(
103
+ (track) => track.language == selectedTrack.language &&
104
+ track.channelsCount == selectedTrack.channelsCount);
169
105
  }
170
106
 
107
+ // Remove duplicate entries with the same height. This can happen if
108
+ // we have multiple resolutions of audio. Pick an arbitrary one.
109
+ tracks = tracks.filter((track, idx) => {
110
+ // Keep the first one with the same height.
111
+ const otherIdx = tracks.findIndex((t) => t.height == track.height);
112
+ return otherIdx == idx;
113
+ });
114
+
171
115
  // Remove old shaka-resolutions
172
116
  // 1. Save the back to menu button
173
117
  const backButton = shaka.ui.Utils.getFirstDescendantWithClassName(
174
- this.resolutionMenu_, 'shaka-back-to-overflow-button');
118
+ this.menu, 'shaka-back-to-overflow-button');
175
119
 
176
120
  // 2. Remove everything
177
- shaka.ui.Utils.removeAllChildren(this.resolutionMenu_);
121
+ shaka.ui.Utils.removeAllChildren(this.menu);
178
122
 
179
123
  // 3. Add the backTo Menu button back
180
- this.resolutionMenu_.appendChild(backButton);
124
+ this.menu.appendChild(backButton);
181
125
 
182
126
  const abrEnabled = this.player.getConfiguration().abr.enabled;
183
127
 
@@ -197,9 +141,9 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.Element {
197
141
  button.setAttribute('aria-selected', 'true');
198
142
  button.appendChild(shaka.ui.Utils.checkmarkIcon());
199
143
  span.classList.add('shaka-chosen-item');
200
- this.currentResolution_.textContent = span.textContent;
144
+ this.currentSelection.textContent = span.textContent;
201
145
  }
202
- this.resolutionMenu_.appendChild(button);
146
+ this.menu.appendChild(button);
203
147
  });
204
148
 
205
149
  // Add the Auto button
@@ -225,24 +169,17 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.Element {
225
169
 
226
170
  this.abrOnSpan_.classList.add('shaka-chosen-item');
227
171
 
228
- this.currentResolution_.textContent =
172
+ this.currentSelection.textContent =
229
173
  this.localization.resolve(shaka.ui.Locales.Ids.AUTO_QUALITY);
230
174
  }
231
175
 
232
- this.resolutionMenu_.appendChild(autoButton);
233
- shaka.ui.Utils.focusOnTheChosenItem(this.resolutionMenu_);
176
+ this.menu.appendChild(autoButton);
177
+ shaka.ui.Utils.focusOnTheChosenItem(this.menu);
234
178
  this.controls.dispatchEvent(
235
179
  new shaka.util.FakeEvent('resolutionselectionupdated'));
236
180
  }
237
181
 
238
182
 
239
- /** @private */
240
- onResolutionClick_() {
241
- this.controls.dispatchEvent(new shaka.util.FakeEvent('submenuopen'));
242
- shaka.ui.Utils.setDisplay(this.resolutionMenu_, true);
243
- shaka.ui.Utils.focusOnTheChosenItem(this.resolutionMenu_);
244
- }
245
-
246
183
  /**
247
184
  * @param {!shaka.extern.Track} track
248
185
  * @private
@@ -251,8 +188,8 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.Element {
251
188
  // Disable abr manager before changing tracks.
252
189
  let config = {abr: {enabled: false}};
253
190
  this.player.configure(config);
254
-
255
- this.player.selectVariantTrack(track, /* clearBuffer */ true);
191
+ const clearBuffer = this.controls.getConfig().clearBufferOnQualityChange;
192
+ this.player.selectVariantTrack(track, clearBuffer);
256
193
  }
257
194
 
258
195
 
@@ -262,19 +199,19 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.Element {
262
199
  updateLocalizedStrings_() {
263
200
  const LocIds = shaka.ui.Locales.Ids;
264
201
 
265
- this.resolutionButton_.setAttribute(shaka.ui.Constants.ARIA_LABEL,
202
+ this.button.setAttribute(shaka.ui.Constants.ARIA_LABEL,
266
203
  this.localization.resolve(LocIds.RESOLUTION));
267
- this.backFromResolutionButton_.setAttribute(shaka.ui.Constants.ARIA_LABEL,
204
+ this.backButton.setAttribute(shaka.ui.Constants.ARIA_LABEL,
268
205
  this.localization.resolve(LocIds.RESOLUTION));
269
- this.backFromResolutionSpan_.textContent =
206
+ this.backSpan.textContent =
270
207
  this.localization.resolve(LocIds.RESOLUTION);
271
- this.resolutionNameSpan_.textContent =
208
+ this.nameSpan.textContent =
272
209
  this.localization.resolve(LocIds.RESOLUTION);
273
210
  this.abrOnSpan_.textContent =
274
211
  this.localization.resolve(LocIds.AUTO_QUALITY);
275
212
 
276
213
  if (this.player.getConfiguration().abr.enabled) {
277
- this.currentResolution_.textContent =
214
+ this.currentSelection.textContent =
278
215
  this.localization.resolve(shaka.ui.Locales.Ids.AUTO_QUALITY);
279
216
  }
280
217
  }
package/ui/seek_bar.js CHANGED
@@ -86,6 +86,7 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
86
86
  * @override
87
87
  */
88
88
  onChangeStart() {
89
+ this.controls.setSeeking(true);
89
90
  this.video.pause();
90
91
  }
91
92
 
@@ -126,7 +127,7 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
126
127
  // They just let go of the seek bar, so cancel the timer and manually
127
128
  // call the event so that we can respond immediately.
128
129
  this.seekTimer_.tickNow();
129
-
130
+ this.controls.setSeeking(false);
130
131
  this.video.play();
131
132
  }
132
133
 
@@ -161,9 +162,8 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
161
162
  } else {
162
163
  shaka.ui.Utils.setDisplay(this.container, true);
163
164
 
164
- const gradient = ['to right'];
165
165
  if (bufferedLength == 0) {
166
- gradient.push('#000 0%');
166
+ this.container.style.background = Constants.SEEK_BAR_BASE_COLOR;
167
167
  } else {
168
168
  const clampedBufferStart = Math.max(bufferedStart, seekRange.start);
169
169
  const clampedBufferEnd = Math.min(bufferedEnd, seekRange.end);
@@ -180,21 +180,19 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
180
180
  const bufferEndFraction = (bufferEndDistance / seekRangeSize) || 0;
181
181
  const playheadFraction = (playheadDistance / seekRangeSize) || 0;
182
182
 
183
- gradient.push(Constants.SEEK_BAR_BASE_COLOR + ' ' +
184
- (bufferStartFraction * 100) + '%');
185
- gradient.push(Constants.SEEK_BAR_PLAYED_COLOR + ' ' +
186
- (bufferStartFraction * 100) + '%');
187
- gradient.push(Constants.SEEK_BAR_PLAYED_COLOR + ' ' +
188
- (playheadFraction * 100) + '%');
189
- gradient.push(Constants.SEEK_BAR_BUFFERED_COLOR + ' ' +
190
- (playheadFraction * 100) + '%');
191
- gradient.push(Constants.SEEK_BAR_BUFFERED_COLOR + ' ' +
192
- (bufferEndFraction * 100) + '%');
193
- gradient.push(Constants.SEEK_BAR_BASE_COLOR + ' ' +
194
- (bufferEndFraction * 100) + '%');
183
+ const makeColor = (color, fract) => color + ' ' + (fract * 100) + '%';
184
+ const gradient = [
185
+ 'to right',
186
+ makeColor(Constants.SEEK_BAR_BASE_COLOR, bufferStartFraction),
187
+ makeColor(Constants.SEEK_BAR_PLAYED_COLOR, bufferStartFraction),
188
+ makeColor(Constants.SEEK_BAR_PLAYED_COLOR, playheadFraction),
189
+ makeColor(Constants.SEEK_BAR_BUFFERED_COLOR, playheadFraction),
190
+ makeColor(Constants.SEEK_BAR_BUFFERED_COLOR, bufferEndFraction),
191
+ makeColor(Constants.SEEK_BAR_BASE_COLOR, bufferEndFraction),
192
+ ];
193
+ this.container.style.background =
194
+ 'linear-gradient(' + gradient.join(',') + ')';
195
195
  }
196
- this.container.style.background =
197
- 'linear-gradient(' + gradient.join(',') + ')';
198
196
  }
199
197
  }
200
198
 
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2016 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+
19
+ goog.provide('shaka.ui.SettingsMenu');
20
+
21
+ goog.require('shaka.ui.Element');
22
+ goog.require('shaka.ui.Enums');
23
+ goog.require('shaka.util.Dom');
24
+
25
+
26
+ /**
27
+ * @extends {shaka.ui.Element}
28
+ * @export
29
+ */
30
+ shaka.ui.SettingsMenu = class extends shaka.ui.Element {
31
+ /**
32
+ * @param {!HTMLElement} parent
33
+ * @param {!shaka.ui.Controls} controls
34
+ * @param {string} iconText
35
+ */
36
+ constructor(parent, controls, iconText) {
37
+ super(parent, controls);
38
+
39
+ this.addButton_(iconText);
40
+
41
+ this.addMenu_();
42
+
43
+ this.eventManager.listen(this.button, 'click', () => {
44
+ this.onButtonClick_();
45
+ });
46
+ }
47
+
48
+
49
+ /**
50
+ * @param {string} iconText
51
+ * @private
52
+ */
53
+ addButton_(iconText) {
54
+ /** @protected {!HTMLElement}*/
55
+ this.button = shaka.util.Dom.createHTMLElement('button');
56
+
57
+ /** @protected {!HTMLElement}*/
58
+ this.icon = shaka.util.Dom.createHTMLElement('i');
59
+ this.icon.classList.add('material-icons');
60
+ this.icon.textContent = iconText;
61
+ this.button.appendChild(this.icon);
62
+
63
+ const label = shaka.util.Dom.createHTMLElement('label');
64
+ label.classList.add('shaka-overflow-button-label');
65
+
66
+ /** @protected {!HTMLElement}*/
67
+ this.nameSpan = shaka.util.Dom.createHTMLElement('span');
68
+ label.appendChild(this.nameSpan);
69
+
70
+ /** @protected {!HTMLElement}*/
71
+ this.currentSelection = shaka.util.Dom.createHTMLElement('span');
72
+ this.currentSelection.classList.add('shaka-current-selection-span');
73
+ label.appendChild(this.currentSelection);
74
+ this.button.appendChild(label);
75
+
76
+ this.parent.appendChild(this.button);
77
+ }
78
+
79
+
80
+ /** @private */
81
+ addMenu_() {
82
+ /** @protected {!HTMLElement}*/
83
+ this.menu = shaka.util.Dom.createHTMLElement('div');
84
+ this.menu.classList.add('shaka-no-propagation');
85
+ this.menu.classList.add('shaka-show-controls-on-mouse-over');
86
+ this.menu.classList.add('shaka-settings-menu');
87
+
88
+ /** @protected {!HTMLElement}*/
89
+ this.backButton = shaka.util.Dom.createHTMLElement('button');
90
+ this.backButton.classList.add('shaka-back-to-overflow-button');
91
+ this.menu.appendChild(this.backButton);
92
+
93
+ const backIcon = shaka.util.Dom.createHTMLElement('i');
94
+ backIcon.classList.add('material-icons');
95
+ backIcon.textContent = shaka.ui.Enums.MaterialDesignIcons.BACK;
96
+ this.backButton.appendChild(backIcon);
97
+
98
+ /** @protected {!HTMLElement}*/
99
+ this.backSpan = shaka.util.Dom.createHTMLElement('span');
100
+ this.backButton.appendChild(this.backSpan);
101
+
102
+ const controlsContainer = this.controls.getControlsContainer();
103
+ controlsContainer.appendChild(this.menu);
104
+ }
105
+
106
+
107
+ /** @private */
108
+ onButtonClick_() {
109
+ this.controls.dispatchEvent(new shaka.util.FakeEvent('submenuopen'));
110
+ shaka.ui.Utils.setDisplay(this.menu, true);
111
+ shaka.ui.Utils.focusOnTheChosenItem(this.menu);
112
+ }
113
+ };