Source: ui/volume_bar.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.ui.VolumeBar');
  7. goog.require('goog.asserts');
  8. goog.require('shaka.ads.Utils');
  9. goog.require('shaka.ui.Controls');
  10. goog.require('shaka.ui.Locales');
  11. goog.require('shaka.ui.Localization');
  12. goog.require('shaka.ui.RangeElement');
  13. /**
  14. * @extends {shaka.ui.RangeElement}
  15. * @final
  16. * @export
  17. */
  18. shaka.ui.VolumeBar = class extends shaka.ui.RangeElement {
  19. /**
  20. * @param {!HTMLElement} parent
  21. * @param {!shaka.ui.Controls} controls
  22. */
  23. constructor(parent, controls) {
  24. super(parent, controls,
  25. ['shaka-volume-bar-container'], ['shaka-volume-bar']);
  26. /** @private {!shaka.extern.UIConfiguration} */
  27. this.config_ = this.controls.getConfig();
  28. // We use a range of 100 to avoid problems with Firefox.
  29. // See https://github.com/shaka-project/shaka-player/issues/3987
  30. this.setRange(0, 100);
  31. this.eventManager.listen(this.video,
  32. 'volumechange',
  33. () => this.onPresentationVolumeChange_());
  34. this.eventManager.listen(this.adManager,
  35. shaka.ads.Utils.AD_VOLUME_CHANGED,
  36. () => this.onAdVolumeChange_());
  37. this.eventManager.listen(this.adManager,
  38. shaka.ads.Utils.AD_MUTED,
  39. () => this.onAdVolumeChange_());
  40. this.eventManager.listen(this.adManager,
  41. shaka.ads.Utils.AD_STOPPED,
  42. () => this.onPresentationVolumeChange_());
  43. this.eventManager.listen(this.localization,
  44. shaka.ui.Localization.LOCALE_UPDATED,
  45. () => this.updateAriaLabel_());
  46. this.eventManager.listen(this.localization,
  47. shaka.ui.Localization.LOCALE_CHANGED,
  48. () => this.updateAriaLabel_());
  49. // Initialize volume display and label.
  50. this.onPresentationVolumeChange_();
  51. this.updateAriaLabel_();
  52. if (this.ad) {
  53. // There was already an ad.
  54. this.onChange();
  55. }
  56. }
  57. /**
  58. * Update the video element's state to match the input element's state.
  59. * Called by the base class when the input element changes.
  60. *
  61. * @override
  62. */
  63. onChange() {
  64. if (this.ad && this.ad.isLinear()) {
  65. this.ad.setVolume(this.getValue() / 100);
  66. } else {
  67. this.video.volume = this.getValue() / 100;
  68. if (this.video.volume == 0) {
  69. this.video.muted = true;
  70. } else {
  71. this.video.muted = false;
  72. }
  73. }
  74. }
  75. /** @private */
  76. onPresentationVolumeChange_() {
  77. if (this.video.muted) {
  78. this.setValue(0);
  79. } else {
  80. this.setValue(this.video.volume * 100);
  81. }
  82. this.updateColors_();
  83. }
  84. /** @private */
  85. onAdVolumeChange_() {
  86. goog.asserts.assert(this.ad != null,
  87. 'This.ad should exist at this point!');
  88. const volume = this.ad.getVolume();
  89. this.setValue(volume * 100);
  90. this.updateColors_();
  91. }
  92. /** @private */
  93. updateColors_() {
  94. const colors = this.config_.volumeBarColors;
  95. const gradient = ['to right'];
  96. gradient.push(colors.level + this.getValue() + '%');
  97. gradient.push(colors.base + this.getValue() + '%');
  98. gradient.push(colors.base + '100%');
  99. this.container.style.background =
  100. 'linear-gradient(' + gradient.join(',') + ')';
  101. }
  102. /** @private */
  103. updateAriaLabel_() {
  104. this.bar.ariaLabel = this.localization.resolve(shaka.ui.Locales.Ids.VOLUME);
  105. }
  106. };
  107. /**
  108. * @implements {shaka.extern.IUIElement.Factory}
  109. * @final
  110. */
  111. shaka.ui.VolumeBar.Factory = class {
  112. /** @override */
  113. create(rootElement, controls) {
  114. return new shaka.ui.VolumeBar(rootElement, controls);
  115. }
  116. };
  117. shaka.ui.Controls.registerElement('volume', new shaka.ui.VolumeBar.Factory());