Source: lib/media/period_observer.js

  1. /**
  2. * @license
  3. * Copyright 2016 Google Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. goog.provide('shaka.media.PeriodObserver');
  18. goog.require('shaka.media.IPlayheadObserver');
  19. goog.require('shaka.util.Periods');
  20. /**
  21. * The period observer keeps track of which period we are in and calls the
  22. * |onPeriodChange| callback whenever we change periods.
  23. *
  24. * @implements {shaka.media.IPlayheadObserver}
  25. * @final
  26. */
  27. shaka.media.PeriodObserver = class {
  28. /**
  29. * The period observer needs an always-up-to-date collection of periods,
  30. * and right now the only way to have that is to reference the manifest.
  31. *
  32. * @param {shaka.extern.Manifest} manifest
  33. */
  34. constructor(manifest) {
  35. /** @private {?shaka.extern.Manifest} */
  36. this.manifest_ = manifest;
  37. /**
  38. * This will be which period we think the playhead is currently in. If it is
  39. * |null|, it means we don't know. We say "we think" because this may become
  40. * out-of-date between updates.
  41. *
  42. * @private {?shaka.extern.Period}
  43. */
  44. this.currentPeriod_ = null;
  45. /**
  46. * The callback for when we change periods. To avoid null-checks, assign it
  47. * a no-op when there is no external callback assigned to it. When we move
  48. * into a new period, this callback will be called with the new period.
  49. *
  50. * @private {function(shaka.extern.Period)}
  51. */
  52. this.onChangedPeriods_ = (period) => {};
  53. }
  54. /** @override */
  55. release() {
  56. // Break all internal references.
  57. this.manifest_ = null;
  58. this.currentPeriod_ = null;
  59. this.onChangedPeriods_ = (period) => {};
  60. }
  61. /** @override */
  62. poll(positionInSeconds, wasSeeking) {
  63. // We detect changes in period by comparing where we think we are against
  64. // where we actually are.
  65. const expectedPeriod = this.currentPeriod_;
  66. const actualPeriod = this.findCurrentPeriod_(positionInSeconds);
  67. if (expectedPeriod != actualPeriod) {
  68. this.onChangedPeriods_(actualPeriod);
  69. }
  70. // Make sure we are up-to-date.
  71. this.currentPeriod_ = actualPeriod;
  72. }
  73. /**
  74. * Set all callbacks. This will override any previous calls to |setListeners|.
  75. *
  76. * @param {function(shaka.extern.Period)} onChangedPeriods
  77. * The callback for when we move to a new period.
  78. */
  79. setListeners(onChangedPeriods) {
  80. this.onChangedPeriods_ = onChangedPeriods;
  81. }
  82. /**
  83. * Find which period we are most likely in based on the current manifest and
  84. * current time. The value here may be different than |this.currentPeriod_|,
  85. * if that is true, it means we changed periods since the last time we updated
  86. * |this.currentPeriod_|.
  87. *
  88. * @param {number} currentTimeSeconds
  89. * @return {shaka.extern.Period}
  90. * @private
  91. */
  92. findCurrentPeriod_(currentTimeSeconds) {
  93. const periods = this.manifest_.periods;
  94. const found = shaka.util.Periods.findPeriodForTime(
  95. periods,
  96. currentTimeSeconds);
  97. // Fallback to periods[0] so that it can never be null. If we join a live
  98. // stream, periods[0].startTime may be non-zero. We can't guarantee that
  99. // video.currentTime will always be inside the seek range so it may be
  100. // possible to call findCurrentPeriod_(beforeFirstPeriod).
  101. return found || periods[0];
  102. }
  103. };