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.util.Dom');
  16. /**
  17. * @extends {shaka.ui.Element}
  18. * @final
  19. * @export
  20. */
  21. shaka.ui.MuteButton = class extends shaka.ui.Element {
  22. /**
  23. * @param {!HTMLElement} parent
  24. * @param {!shaka.ui.Controls} controls
  25. */
  26. constructor(parent, controls) {
  27. super(parent, controls);
  28. const LocIds = shaka.ui.Locales.Ids;
  29. /** @private {!HTMLButtonElement} */
  30. this.button_ = shaka.util.Dom.createButton();
  31. this.button_.classList.add('shaka-mute-button');
  32. this.button_.classList.add('shaka-tooltip');
  33. /** @private {!HTMLElement} */
  34. this.icon_ = shaka.util.Dom.createHTMLElement('i');
  35. this.icon_.classList.add('material-icons-round');
  36. this.icon_.textContent = shaka.ui.Enums.MaterialDesignIcons.MUTE;
  37. this.button_.appendChild(this.icon_);
  38. const label = shaka.util.Dom.createHTMLElement('label');
  39. label.classList.add('shaka-overflow-button-label');
  40. label.classList.add('shaka-overflow-menu-only');
  41. this.nameSpan_ = shaka.util.Dom.createHTMLElement('span');
  42. this.nameSpan_.textContent = this.localization.resolve(LocIds.MUTE);
  43. label.appendChild(this.nameSpan_);
  44. /** @private {!HTMLElement} */
  45. this.currentState_ = shaka.util.Dom.createHTMLElement('span');
  46. this.currentState_.classList.add('shaka-current-selection-span');
  47. label.appendChild(this.currentState_);
  48. this.button_.appendChild(label);
  49. this.parent.appendChild(this.button_);
  50. this.updateLocalizedStrings_();
  51. this.updateIcon_();
  52. this.eventManager.listen(
  53. this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
  54. this.updateLocalizedStrings_();
  55. });
  56. this.eventManager.listen(
  57. this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
  58. this.updateLocalizedStrings_();
  59. });
  60. this.eventManager.listen(this.button_, 'click', () => {
  61. if (!this.controls.isOpaque()) {
  62. return;
  63. }
  64. if (this.ad && this.ad.isLinear()) {
  65. this.ad.setMuted(!this.ad.isMuted());
  66. } else {
  67. if (!this.video.muted && this.video.volume == 0) {
  68. this.video.volume = 1;
  69. } else {
  70. this.video.muted = !this.video.muted;
  71. }
  72. }
  73. });
  74. this.eventManager.listen(this.video, 'volumechange', () => {
  75. this.updateLocalizedStrings_();
  76. this.updateIcon_();
  77. });
  78. this.eventManager.listen(this.player, 'loading', () => {
  79. this.updateLocalizedStrings_();
  80. this.updateIcon_();
  81. });
  82. this.eventManager.listen(this.controls, 'caststatuschanged', () => {
  83. this.updateLocalizedStrings_();
  84. this.updateIcon_();
  85. });
  86. this.eventManager.listen(this.adManager,
  87. shaka.ads.Utils.AD_VOLUME_CHANGED, () => {
  88. this.updateLocalizedStrings_();
  89. this.updateIcon_();
  90. });
  91. this.eventManager.listen(this.adManager,
  92. shaka.ads.Utils.AD_MUTED, () => {
  93. this.updateLocalizedStrings_();
  94. this.updateIcon_();
  95. });
  96. this.eventManager.listen(this.adManager,
  97. shaka.ads.Utils.AD_STOPPED, () => {
  98. // The base class also listens for this event and sets this.ad
  99. // to null. This is a safeguard in case of a race condition as
  100. // the label and icon code depends on this.ad being correctly
  101. // updated at the time it runs.
  102. this.ad = null;
  103. this.updateLocalizedStrings_();
  104. this.updateIcon_();
  105. });
  106. }
  107. /**
  108. * @private
  109. */
  110. updateLocalizedStrings_() {
  111. const LocIds = shaka.ui.Locales.Ids;
  112. let label;
  113. if (this.ad) {
  114. label = this.ad.isMuted() ? LocIds.UNMUTE : LocIds.MUTE;
  115. } else {
  116. label = (this.video.muted || this.video.volume == 0) ?
  117. LocIds.UNMUTE : LocIds.MUTE;
  118. }
  119. this.button_.ariaLabel = this.localization.resolve(label);
  120. this.nameSpan_.textContent = this.localization.resolve(label);
  121. }
  122. /**
  123. * @private
  124. */
  125. updateIcon_() {
  126. const Icons = shaka.ui.Enums.MaterialDesignIcons;
  127. let icon;
  128. if (this.ad) {
  129. icon = this.ad.isMuted() ? Icons.UNMUTE : Icons.MUTE;
  130. } else {
  131. icon = (this.video.muted || this.video.volume == 0) ?
  132. Icons.UNMUTE : Icons.MUTE;
  133. }
  134. this.icon_.textContent = icon;
  135. }
  136. };
  137. /**
  138. * @implements {shaka.extern.IUIElement.Factory}
  139. * @final
  140. */
  141. shaka.ui.MuteButton.Factory = class {
  142. /** @override */
  143. create(rootElement, controls) {
  144. return new shaka.ui.MuteButton(rootElement, controls);
  145. }
  146. };
  147. shaka.ui.OverflowMenu.registerElement(
  148. 'mute', new shaka.ui.MuteButton.Factory());
  149. shaka.ui.Controls.registerElement(
  150. 'mute', new shaka.ui.MuteButton.Factory());
  151. shaka.ui.ContextMenu.registerElement(
  152. 'mute', new shaka.ui.MuteButton.Factory());