notifyTimeRange(timeline, startOffset) {
    if (timeline.length == 0) {
      return;
    }

    // Date.now() is in milliseconds, from which we compute "now" in seconds.
    const now = (Date.now() + this.clockOffset_) / 1000.0;
    // Exclude time ranges that are in the "future".
    const timelineForStart = timeline.filter((timeRange) =>
      timeRange.start + startOffset < now);
    if (timelineForStart.length == 0) {
      return;
    }

    const firstStartTime = timelineForStart[0].start + startOffset;
    const lastEndTime = timelineForStart[timelineForStart.length - 1].end +
      startOffset;

    this.notifyMinSegmentStartTime(firstStartTime);

    this.maxSegmentDuration_ = timelineForStart.reduce(
        (max, r) => { return Math.max(max, r.end - r.start); },
        this.maxSegmentDuration_);

    this.maxSegmentEndTime_ =
          Math.max(this.maxSegmentEndTime_, lastEndTime);

    if (this.presentationStartTime_ != null && this.autoCorrectDrift_ &&
            !this.startTimeLocked_) {
      // Since we have explicit segment end times, calculate a presentation
      // start based on them.  This start time accounts for drift.
      this.presentationStartTime_ =
            now - this.maxSegmentEndTime_ - this.maxSegmentDuration_;
    }

    shaka.log.v1('notifySegments:',
        'maxSegmentDuration=' + this.maxSegmentDuration_);
  }
Gives PresentationTimeline a Stream's timeline so it can size and position
the segment availability window, and account for missing segment
information.

@param {!Array<shaka.media.PresentationTimeline.TimeRange>} timeline
@param {number} startOffset
@export