parseNext(absStart, reader, partialOkay, stopOnPartial) {
    const start = reader.getPosition();

    // size(4 bytes) + type(4 bytes) = 8 bytes
    if (stopOnPartial && start + 8 > reader.getLength()) {
      this.done_ = true;
      return;
    }

    let size = reader.readUint32();
    const type = reader.readUint32();
    const name = shaka.util.Mp4Parser.typeToString(type);
    let has64BitSize = false;
    shaka.log.v2('Parsing MP4 box', name);

    switch (size) {
      case 0:
        size = reader.getLength() - start;
        break;
      case 1:
        if (stopOnPartial && reader.getPosition() + 8 > reader.getLength()) {
          this.done_ = true;
          return;
        }
        size = reader.readUint64();
        has64BitSize = true;
        break;
    }

    const boxDefinition = this.boxDefinitions_.get(type);

    if (boxDefinition) {
      let version = null;
      let flags = null;

      if (this.headers_.get(type) == shaka.util.Mp4Parser.BoxType_.FULL_BOX) {
        if (stopOnPartial && reader.getPosition() + 4 > reader.getLength()) {
          this.done_ = true;
          return;
        }
        const versionAndFlags = reader.readUint32();
        version = versionAndFlags >>> 24;
        flags = versionAndFlags & 0xFFFFFF;
      }

      // Read the whole payload so that the current level can be safely read
      // regardless of how the payload is parsed.
      let end = start + size;
      if (partialOkay && end > reader.getLength()) {
        // For partial reads, truncate the payload if we must.
        end = reader.getLength();
      }

      if (stopOnPartial && end > reader.getLength()) {
        this.done_ = true;
        return;
      }
      const payloadSize = end - reader.getPosition();
      const payload =
      (payloadSize > 0) ? reader.readBytes(payloadSize) : new Uint8Array(0);

      const payloadReader = new shaka.util.DataViewReader(
          payload, shaka.util.DataViewReader.Endianness.BIG_ENDIAN);

      /** @type {shaka.extern.ParsedBox} */
      const box = {
        name,
        parser: this,
        partialOkay: partialOkay || false,
        version,
        flags,
        reader: payloadReader,
        size,
        start: start + absStart,
        has64BitSize,
      };

      boxDefinition(box);
    } else {
      // Move the read head to be at the end of the box.
      // If the box is longer than the remaining parts of the file, e.g. the
      // mp4 is improperly formatted, or this was a partial range request that
      // ended in the middle of a box, just skip to the end.
      const skipLength = Math.min(
          start + size - reader.getPosition(),
          reader.getLength() - reader.getPosition());
      reader.skip(skipLength);
    }
  }
Parse the next box on the current level.

@param {number} absStart The absolute start position in the original
  byte array.
@param {!shaka.util.DataViewReader} reader
@param {boolean=} partialOkay If true, allow reading partial payloads
  from some boxes. If the goal is a child box, we can sometimes find it
  without enough data to find all child boxes.
@param {boolean=} stopOnPartial If true, stop reading if an incomplete
  box is detected.
@export