Source: ui/presentation_time.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.ui.PresentationTimeTracker');
  7. goog.require('shaka.ui.Controls');
  8. goog.require('shaka.ui.Element');
  9. goog.require('shaka.ui.Locales');
  10. goog.require('shaka.ui.Utils');
  11. goog.require('shaka.util.Dom');
  12. /**
  13. * @extends {shaka.ui.Element}
  14. * @final
  15. * @export
  16. */
  17. shaka.ui.PresentationTimeTracker = class extends shaka.ui.Element {
  18. /**
  19. * @param {!HTMLElement} parent
  20. * @param {!shaka.ui.Controls} controls
  21. */
  22. constructor(parent, controls) {
  23. super(parent, controls);
  24. /** @type {!HTMLButtonElement} */
  25. this.currentTime_ = shaka.util.Dom.createButton();
  26. this.currentTime_.classList.add('shaka-current-time');
  27. this.setValue_('0:00');
  28. this.parent.appendChild(this.currentTime_);
  29. this.eventManager.listen(this.currentTime_, 'click', () => {
  30. // Jump to LIVE if the user clicks on the current time.
  31. if (this.player.isLive()) {
  32. this.video.currentTime = this.player.seekRange().end;
  33. }
  34. });
  35. this.eventManager.listen(this.controls, 'timeandseekrangeupdated', () => {
  36. this.updateTime_();
  37. });
  38. this.eventManager.listen(this.player, 'trackschanged', () => {
  39. this.onTracksChanged_();
  40. });
  41. }
  42. /** @private */
  43. setValue_(value) {
  44. // To avoid constant updates to the DOM, which makes debugging more
  45. // difficult, only set the value if it has changed. If we don't do this
  46. // check, the DOM updates constantly, this element flashes in the debugger
  47. // in Chrome, and you can't make changes in the CSS panel.
  48. if (value != this.currentTime_.textContent) {
  49. this.currentTime_.textContent = value;
  50. }
  51. }
  52. /** @private */
  53. updateTime_() {
  54. const isSeeking = this.controls.isSeeking();
  55. let displayTime = this.controls.getDisplayTime();
  56. const duration = this.video.duration;
  57. const seekRange = this.player.seekRange();
  58. const seekRangeSize = seekRange.end - seekRange.start;
  59. const Utils = shaka.ui.Utils;
  60. if (this.player.isLive()) {
  61. // The amount of time we are behind the live edge.
  62. const behindLive = Math.floor(seekRange.end - displayTime);
  63. displayTime = Math.max(0, behindLive);
  64. const showHour = seekRangeSize >= 3600;
  65. // Consider "LIVE" when less than 1 second behind the live-edge. Always
  66. // show the full time string when seeking, including the leading '-';
  67. // otherwise, the time string "flickers" near the live-edge.
  68. // The button should only be clickable when it's live stream content, and
  69. // the current play time is behind live edge.
  70. if ((displayTime >= 1) || isSeeking) {
  71. this.setValue_('- ' + Utils.buildTimeString(displayTime, showHour));
  72. this.currentTime_.disabled = false;
  73. } else {
  74. this.setValue_(this.localization.resolve(shaka.ui.Locales.Ids.LIVE));
  75. this.currentTime_.disabled = true;
  76. }
  77. } else {
  78. const showHour = duration >= 3600;
  79. let value = Utils.buildTimeString(displayTime, showHour);
  80. if (duration) {
  81. value += ' / ' + Utils.buildTimeString(duration, showHour);
  82. }
  83. this.setValue_(value);
  84. this.currentTime_.disabled = true;
  85. }
  86. }
  87. /**
  88. * Set the aria label to be 'Live' when the content is live stream.
  89. * @private
  90. */
  91. onTracksChanged_() {
  92. if (this.player.isLive()) {
  93. const ariaLabel = shaka.ui.Locales.Ids.SKIP_TO_LIVE;
  94. this.currentTime_.ariaLabel = this.localization.resolve(ariaLabel);
  95. }
  96. }
  97. };
  98. /**
  99. * @implements {shaka.extern.IUIElement.Factory}
  100. * @final
  101. */
  102. shaka.ui.PresentationTimeTracker.Factory = class {
  103. /** @override */
  104. create(rootElement, controls) {
  105. return new shaka.ui.PresentationTimeTracker(rootElement, controls);
  106. }
  107. };
  108. shaka.ui.Controls.registerElement(
  109. 'time_and_duration', new shaka.ui.PresentationTimeTracker.Factory());