All files / src/helper buffer-helper.js

92.86% Statements 39/42
77.27% Branches 17/22
100% Functions 4/4
92.68% Lines 38/41

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101        1x               10x 10x 10x 9x 15x 5x               5x       9x 9x 8x 8x 16x   8x             1x       8x       8x 8x 8x 8x             8x 16x 16x 8x   8x                 8x       8x     8x 16x 16x   16x   5x 5x 5x 11x 3x 3x     8x          
/**
 * Buffer Helper utils, providing methods dealing buffer length retrieval
*/
 
const BufferHelper = {
  /**
   * Return true if `media`'s buffered include `position`
   * @param {HTMLMediaElement|SourceBuffer} media
   * @param {number} position
   * @returns {boolean}
   */
  isBuffered: function (media, position) {
    try {
      Eif (media) {
        let buffered = media.buffered;
        for (let i = 0; i < buffered.length; i++) {
          if (position >= buffered.start(i) && position <= buffered.end(i))
            return true;
        }
      }
    } catch (error) {
      // this is to catch
      // InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer':
      // This SourceBuffer has been removed from the parent media source
    }
    return false;
  },
 
  bufferInfo: function (media, pos, maxHoleDuration) {
    try {
      if (media) {
        let vbuffered = media.buffered, buffered = [], i;
        for (i = 0; i < vbuffered.length; i++)
          buffered.push({ start: vbuffered.start(i), end: vbuffered.end(i) });
 
        return this.bufferedInfo(buffered, pos, maxHoleDuration);
      }
    } catch (error) {
      // this is to catch
      // InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer':
      // This SourceBuffer has been removed from the parent media source
    }
    return { len: 0, start: pos, end: pos, nextStart: undefined };
  },
 
  bufferedInfo: function (buffered, pos, maxHoleDuration) {
    let buffered2 = [],
      // bufferStart and bufferEnd are buffer boundaries around current video position
      bufferLen, bufferStart, bufferEnd, bufferStartNext, i;
    // sort on buffer.start/smaller end (IE does not always return sorted buffered range)
    buffered.sort(function (a, b) {
      let diff = a.start - b.start;
      Eif (diff)
        return diff;
      else
        return b.end - a.end;
    });
    // there might be some small holes between buffer time range
    // consider that holes smaller than maxHoleDuration are irrelevant and build another
    // buffer time range representations that discards those holes
    for (i = 0; i < buffered.length; i++) {
      let buf2len = buffered2.length;
      if (buf2len) {
        let buf2end = buffered2[buf2len - 1].end;
        // if small hole (value between 0 or maxHoleDuration ) or overlapping (negative)
        Iif ((buffered[i].start - buf2end) < maxHoleDuration) {
          // merge overlapping time ranges
          // update lastRange.end only if smaller than item.end
          // e.g.  [ 1, 15] with  [ 2,8] => [ 1,15] (no need to modify lastRange.end)
          // whereas [ 1, 8] with  [ 2,15] => [ 1,15] ( lastRange should switch from [1,8] to [1,15])
          if (buffered[i].end > buf2end)
            buffered2[buf2len - 1].end = buffered[i].end;
        } else {
          // big hole
          buffered2.push(buffered[i]);
        }
      } else {
        // first value
        buffered2.push(buffered[i]);
      }
    }
    for (i = 0, bufferLen = 0, bufferStart = bufferEnd = pos; i < buffered2.length; i++) {
      let start = buffered2[i].start,
        end = buffered2[i].end;
      // logger.log('buf start/end:' + buffered.start(i) + '/' + buffered.end(i));
      if ((pos + maxHoleDuration) >= start && pos < end) {
        // play position is inside this buffer TimeRange, retrieve end of buffer position and buffer length
        bufferStart = start;
        bufferEnd = end;
        bufferLen = bufferEnd - pos;
      } else if ((pos + maxHoleDuration) < start) {
        bufferStartNext = start;
        break;
      }
    }
    return { len: bufferLen, start: bufferStart, end: bufferEnd, nextStart: bufferStartNext };
  }
};
 
export default BufferHelper;