Source: lib/media/region_timeline.js

  1. /** @license
  2. * Copyright 2016 Google LLC
  3. * SPDX-License-Identifier: Apache-2.0
  4. */
  5. goog.provide('shaka.media.RegionTimeline');
  6. goog.require('shaka.util.IReleasable');
  7. /**
  8. * The region timeline is a set of unique timeline region info entries. When
  9. * a new entry is added, the |onAddRegion| callback will be called.
  10. *
  11. * @implements {shaka.util.IReleasable}
  12. * @final
  13. */
  14. shaka.media.RegionTimeline = class {
  15. constructor() {
  16. /** @private {function(shaka.extern.TimelineRegionInfo)} */
  17. this.onAddRegion_ = (region) => {};
  18. /** @private {!Set.<shaka.extern.TimelineRegionInfo>} */
  19. this.regions_ = new Set();
  20. }
  21. /** @override */
  22. release() {
  23. // Prevent us from holding onto any external references via the callback.
  24. this.onAddRegion_ = (region) => {};
  25. this.regions_.clear();
  26. }
  27. /**
  28. * Set the callbacks for events. This will override any previous calls to
  29. * |setListeners|.
  30. *
  31. * @param {function(shaka.extern.TimelineRegionInfo)} onAddRegion
  32. * Set the callback for when we add a new region. This callback will only
  33. * be called when a region is unique (we reject duplicate regions).
  34. */
  35. setListeners(onAddRegion) {
  36. this.onAddRegion_ = onAddRegion;
  37. }
  38. /**
  39. * @param {shaka.extern.TimelineRegionInfo} region
  40. */
  41. addRegion(region) {
  42. const similarRegion = this.findSimilarRegion_(region);
  43. // Make sure we don't add duplicate regions. We keep track of this here
  44. // instead of making the parser track it.
  45. if (similarRegion == null) {
  46. this.regions_.add(region);
  47. this.onAddRegion_(region);
  48. }
  49. }
  50. /**
  51. * Find a region in the timeline that has the same scheme id uri, event id,
  52. * start time and end time. If these four parameters match, we assume it
  53. * to be the same region. If no similar region can be found, |null| will be
  54. * returned.
  55. *
  56. * @param {shaka.extern.TimelineRegionInfo} region
  57. * @return {?shaka.extern.TimelineRegionInfo}
  58. * @private
  59. */
  60. findSimilarRegion_(region) {
  61. for (const existing of this.regions_) {
  62. // The same scheme ID and time range means that it is similar-enough to
  63. // be the same region.
  64. const isSimilar = existing.schemeIdUri == region.schemeIdUri &&
  65. existing.id == region.id &&
  66. existing.startTime == region.startTime &&
  67. existing.endTime == region.endTime;
  68. if (isSimilar) {
  69. return existing;
  70. }
  71. }
  72. return null;
  73. }
  74. /**
  75. * Get an iterable for all the regions in the timeline. This will allow
  76. * others to see what regions are in the timeline while not being able to
  77. * change the collection.
  78. *
  79. * @return {!Iterable.<shaka.extern.TimelineRegionInfo>}
  80. */
  81. regions() {
  82. return this.regions_;
  83. }
  84. };