Source: ui/mute_button.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.ui.MuteButton');
  7. goog.require('shaka.ads.Utils');
  8. goog.require('shaka.ui.ContextMenu');
  9. goog.require('shaka.ui.Controls');
  10. goog.require('shaka.ui.Element');
  11. goog.require('shaka.ui.Enums');
  12. goog.require('shaka.ui.Locales');
  13. goog.require('shaka.ui.Localization');
  14. goog.require('shaka.ui.OverflowMenu');
  15. goog.require('shaka.ui.Utils');
  16. goog.require('shaka.util.Dom');
  17. /**
  18. * @extends {shaka.ui.Element}
  19. * @final
  20. * @export
  21. */
  22. shaka.ui.MuteButton = class extends shaka.ui.Element {
  23. /**
  24. * @param {!HTMLElement} parent
  25. * @param {!shaka.ui.Controls} controls
  26. */
  27. constructor(parent, controls) {
  28. super(parent, controls);
  29. const LocIds = shaka.ui.Locales.Ids;
  30. /** @private {!HTMLButtonElement} */
  31. this.button_ = shaka.util.Dom.createButton();
  32. this.button_.classList.add('shaka-mute-button');
  33. this.button_.classList.add('shaka-tooltip');
  34. /** @private {!HTMLElement} */
  35. this.icon_ = shaka.util.Dom.createHTMLElement('i');
  36. this.icon_.classList.add('material-icons-round');
  37. this.icon_.textContent = shaka.ui.Enums.MaterialDesignIcons.MUTE;
  38. this.button_.appendChild(this.icon_);
  39. const label = shaka.util.Dom.createHTMLElement('label');
  40. label.classList.add('shaka-overflow-button-label');
  41. label.classList.add('shaka-overflow-menu-only');
  42. this.nameSpan_ = shaka.util.Dom.createHTMLElement('span');
  43. this.nameSpan_.textContent = this.localization.resolve(LocIds.MUTE);
  44. label.appendChild(this.nameSpan_);
  45. /** @private {!HTMLElement} */
  46. this.currentState_ = shaka.util.Dom.createHTMLElement('span');
  47. this.currentState_.classList.add('shaka-current-selection-span');
  48. label.appendChild(this.currentState_);
  49. this.button_.appendChild(label);
  50. this.parent.appendChild(this.button_);
  51. this.updateLocalizedStrings_();
  52. this.updateIcon_();
  53. this.eventManager.listen(
  54. this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
  55. this.updateLocalizedStrings_();
  56. });
  57. this.eventManager.listen(
  58. this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
  59. this.updateLocalizedStrings_();
  60. });
  61. this.eventManager.listen(this.button_, 'click', () => {
  62. if (!this.controls.isOpaque()) {
  63. return;
  64. }
  65. if (this.ad && this.ad.isLinear()) {
  66. this.ad.setMuted(!this.ad.isMuted());
  67. } else {
  68. if (!this.video.muted && this.video.volume == 0) {
  69. this.video.volume = 1;
  70. } else {
  71. this.video.muted = !this.video.muted;
  72. }
  73. }
  74. });
  75. this.eventManager.listen(this.video, 'volumechange', () => {
  76. this.updateLocalizedStrings_();
  77. this.updateIcon_();
  78. });
  79. this.eventManager.listen(this.player, 'loading', () => {
  80. this.updateLocalizedStrings_();
  81. this.updateIcon_();
  82. });
  83. this.eventManager.listen(this.player, 'loaded', () => {
  84. this.checkAvailability_();
  85. });
  86. this.eventManager.listen(this.player, 'unloading', () => {
  87. this.checkAvailability_();
  88. });
  89. this.eventManager.listen(this.player, 'trackschanged', () => {
  90. this.checkAvailability_();
  91. });
  92. this.eventManager.listen(this.controls, 'caststatuschanged', () => {
  93. this.updateLocalizedStrings_();
  94. this.updateIcon_();
  95. });
  96. this.eventManager.listen(this.adManager,
  97. shaka.ads.Utils.AD_VOLUME_CHANGED, () => {
  98. this.updateLocalizedStrings_();
  99. this.updateIcon_();
  100. });
  101. this.eventManager.listen(this.adManager,
  102. shaka.ads.Utils.AD_MUTED, () => {
  103. this.updateLocalizedStrings_();
  104. this.updateIcon_();
  105. });
  106. this.eventManager.listen(this.adManager,
  107. shaka.ads.Utils.AD_STARTED, () => {
  108. this.checkAvailability_();
  109. });
  110. this.eventManager.listen(this.adManager,
  111. shaka.ads.Utils.AD_STOPPED, () => {
  112. // The base class also listens for this event and sets this.ad
  113. // to null. This is a safeguard in case of a race condition as
  114. // the label and icon code depends on this.ad being correctly
  115. // updated at the time it runs.
  116. this.ad = null;
  117. this.updateLocalizedStrings_();
  118. this.updateIcon_();
  119. this.checkAvailability_();
  120. });
  121. this.checkAvailability_();
  122. }
  123. /**
  124. * @private
  125. */
  126. updateLocalizedStrings_() {
  127. const LocIds = shaka.ui.Locales.Ids;
  128. let label;
  129. if (this.ad) {
  130. label = this.ad.isMuted() ? LocIds.UNMUTE : LocIds.MUTE;
  131. } else {
  132. label = (this.video.muted || this.video.volume == 0) ?
  133. LocIds.UNMUTE : LocIds.MUTE;
  134. }
  135. this.button_.ariaLabel = this.localization.resolve(label);
  136. this.nameSpan_.textContent = this.localization.resolve(label);
  137. }
  138. /**
  139. * @private
  140. */
  141. updateIcon_() {
  142. const Icons = shaka.ui.Enums.MaterialDesignIcons;
  143. let icon;
  144. if (this.ad) {
  145. icon = this.ad.isMuted() ? Icons.UNMUTE : Icons.MUTE;
  146. } else {
  147. icon = (this.video.muted || this.video.volume == 0) ?
  148. Icons.UNMUTE : Icons.MUTE;
  149. }
  150. this.icon_.textContent = icon;
  151. }
  152. /** @private */
  153. checkAvailability_() {
  154. let available = true;
  155. if (this.ad && this.ad.isLinear()) {
  156. // We can't tell if the Ad has audio or not.
  157. available = true;
  158. } else if (this.player.isVideoOnly()) {
  159. available = false;
  160. }
  161. shaka.ui.Utils.setDisplay(this.button_, available);
  162. }
  163. };
  164. /**
  165. * @implements {shaka.extern.IUIElement.Factory}
  166. * @final
  167. */
  168. shaka.ui.MuteButton.Factory = class {
  169. /** @override */
  170. create(rootElement, controls) {
  171. return new shaka.ui.MuteButton(rootElement, controls);
  172. }
  173. };
  174. shaka.ui.OverflowMenu.registerElement(
  175. 'mute', new shaka.ui.MuteButton.Factory());
  176. shaka.ui.Controls.registerElement(
  177. 'mute', new shaka.ui.MuteButton.Factory());
  178. shaka.ui.ContextMenu.registerElement(
  179. 'mute', new shaka.ui.MuteButton.Factory());