Source: ui/ad_info.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.ui.AdInfo');
  7. goog.require('goog.asserts');
  8. goog.require('shaka.ads.Utils');
  9. goog.require('shaka.ui.Element');
  10. goog.require('shaka.ui.Locales');
  11. goog.require('shaka.ui.Localization');
  12. goog.require('shaka.ui.Utils');
  13. goog.require('shaka.util.Dom');
  14. goog.require('shaka.util.Timer');
  15. goog.requireType('shaka.ui.Controls');
  16. /**
  17. * @extends {shaka.ui.Element}
  18. * @final
  19. * @export
  20. */
  21. shaka.ui.AdInfo = 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. /** @private {!HTMLElement} */
  29. this.adInfo_ = shaka.util.Dom.createButton();
  30. this.adInfo_.classList.add('shaka-ad-info');
  31. this.adInfo_.disabled = true;
  32. this.parent.appendChild(this.adInfo_);
  33. /**
  34. * The timer that tracks down the ad progress.
  35. *
  36. * @private {shaka.util.Timer}
  37. */
  38. this.timer_ = new shaka.util.Timer(() => {
  39. this.onTimerTick_();
  40. });
  41. this.updateAriaLabel_();
  42. this.eventManager.listen(
  43. this.localization, shaka.ui.Localization.LOCALE_UPDATED, () => {
  44. this.updateAriaLabel_();
  45. });
  46. this.eventManager.listen(
  47. this.localization, shaka.ui.Localization.LOCALE_CHANGED, () => {
  48. this.updateAriaLabel_();
  49. });
  50. this.eventManager.listen(
  51. this.adManager, shaka.ads.Utils.AD_STARTED, () => {
  52. this.onAdStarted_();
  53. });
  54. this.eventManager.listen(
  55. this.adManager, shaka.ads.Utils.AD_STOPPED, () => {
  56. this.reset_();
  57. });
  58. if (this.ad) {
  59. // There was already an ad.
  60. this.onAdStarted_();
  61. }
  62. }
  63. /**
  64. * @private
  65. */
  66. updateAriaLabel_() {
  67. // TODO
  68. }
  69. /**
  70. * @private
  71. */
  72. onAdStarted_() {
  73. this.timer_.tickNow();
  74. this.timer_.tickEvery(0.5);
  75. }
  76. /**
  77. * @private
  78. */
  79. onTimerTick_() {
  80. const LocIds = shaka.ui.Locales.Ids;
  81. goog.asserts.assert(this.ad != null,
  82. 'this.ad should exist at this point');
  83. if (!this.ad.isLinear()) {
  84. // Do not show information for non-linear ads.
  85. return;
  86. }
  87. let text = '';
  88. const adsInAdPod = this.ad.getSequenceLength();
  89. if (adsInAdPod > 1) {
  90. // If it's a single ad, showing 'Ad 1 of 1' isn't helpful.
  91. // Only show this element if there's more than 1 ad and it's a linear ad.
  92. const adPosition = this.ad.getPositionInSequence();
  93. text = this.localization.resolve(LocIds.AD_PROGRESS)
  94. .replace('[AD_ON]', String(adPosition))
  95. .replace('[NUM_ADS]', String(adsInAdPod));
  96. }
  97. const secondsLeft = Math.round(this.ad.getRemainingTime());
  98. const adDuration = this.ad.getDuration();
  99. if (secondsLeft == -1 || adDuration == -1) {
  100. this.adInfo_.textContent = text;
  101. shaka.ui.Utils.setDisplay(this.adInfo_, text != '');
  102. return;
  103. }
  104. if (secondsLeft > 0) {
  105. const timePassed = adDuration - secondsLeft;
  106. const timePassedStr =
  107. shaka.ui.Utils.buildTimeString(timePassed, /* showHour= */ false);
  108. const adLength = shaka.ui.Utils.buildTimeString(
  109. adDuration, /* showHour= */ false);
  110. const timeString = timePassedStr + ' / ' + adLength;
  111. // If there's more than one ad in the sequence, show the time
  112. // without the word 'Ad' (it will be shown by another element).
  113. // Otherwise, the format is "Ad: 0:05 / 0:10."
  114. if (adsInAdPod > 1) {
  115. text += '\u00A0\u00A0' + timeString;
  116. } else {
  117. text = this.localization.resolve(LocIds.AD_TIME)
  118. .replace('[AD_TIME]', timeString);
  119. }
  120. this.adInfo_.textContent = text;
  121. shaka.ui.Utils.setDisplay(this.adInfo_, text != '');
  122. } else {
  123. this.reset_();
  124. }
  125. }
  126. /**
  127. * @private
  128. */
  129. reset_() {
  130. this.timer_.stop();
  131. // Controls are going to hide the whole ad panel once the ad is over,
  132. // this is just a safeguard.
  133. this.adInfo_.textContent = '';
  134. }
  135. /**
  136. * @override
  137. */
  138. release() {
  139. this.timer_.stop();
  140. this.timer_ = null;
  141. super.release();
  142. }
  143. };