getTimestampAndDispatchMetadata(contentType, data, reference, stream,
      mimeType) {
    let timestamp = null;
    let metadata = [];

    const uint8ArrayData = shaka.util.BufferUtils.toUint8(data);
    if (shaka.util.MimeUtils.RAW_FORMATS.includes(mimeType)) {
      const frames = shaka.util.Id3Utils.getID3Frames(uint8ArrayData);
      if (frames.length && reference) {
        const metadataTimestamp = frames.find((frame) => {
          return frame.description ===
              'com.apple.streaming.transportStreamTimestamp';
        });
        if (metadataTimestamp && typeof metadataTimestamp.data == 'number') {
          timestamp = Math.round(metadataTimestamp.data) / 1000;
        }
        /** @private {shaka.extern.ID3Metadata} */
        const id3Metadata = {
          cueTime: reference.startTime,
          data: uint8ArrayData,
          frames: frames,
          dts: reference.startTime,
          pts: reference.startTime,
        };
        this.playerInterface_.onMetadata(
            [id3Metadata], /* offset= */ 0, reference.endTime);
      }
    } else if (mimeType.includes('/mp4') &&
        reference &&
        reference.initSegmentReference &&
        reference.initSegmentReference.timescale) {
      const timescale = reference.initSegmentReference.timescale;
      if (!isNaN(timescale)) {
        const hasEmsg = ((stream.emsgSchemeIdUris != null &&
            stream.emsgSchemeIdUris.length > 0) ||
            this.config_.dispatchAllEmsgBoxes);
        const Mp4Parser = shaka.util.Mp4Parser;
        let startTime = 0;
        let parsedMedia = false;
        const parser = new Mp4Parser();
        if (hasEmsg) {
          parser.fullBox('emsg', (box) =>
            this.parseEMSG_(reference, stream.emsgSchemeIdUris, box));
        }
        parser.fullBox('prft', (box) => this.parsePrft_(timescale, box))
            .box('moof', Mp4Parser.children)
            .box('traf', Mp4Parser.children)
            .fullBox('tfdt', (box) => {
              if (!parsedMedia) {
                goog.asserts.assert(
                    box.version == 0 || box.version == 1,
                    'TFDT version can only be 0 or 1');
                const parsed = shaka.util.Mp4BoxParsers.parseTFDTInaccurate(
                    box.reader, box.version);
                startTime = parsed.baseMediaDecodeTime / timescale;
                parsedMedia = true;
                if (!hasEmsg) {
                  box.parser.stop();
                }
              }
            }).parse(data, /* partialOkay= */ true);
        if (parsedMedia && reference.timestampOffset == 0) {
          timestamp = startTime;
        }
      }
    } else if (!mimeType.includes('/mp4') && !mimeType.includes('/webm') &&
        shaka.util.TsParser.probe(uint8ArrayData)) {
      if (!this.tsParsers_.has(contentType)) {
        this.tsParsers_.set(contentType, new shaka.util.TsParser());
      } else {
        this.tsParsers_.get(contentType).clearData();
      }
      const tsParser = this.tsParsers_.get(contentType).parse(uint8ArrayData);
      const startTime = tsParser.getStartTime(contentType);
      if (startTime != null) {
        timestamp = startTime;
      }
      metadata = tsParser.getMetadata();
    }
    return {timestamp, metadata};
  }
This method is only public for testing.

@param {shaka.util.ManifestParserUtils.ContentType} contentType
@param {!BufferSource} data
@param {!shaka.media.SegmentReference} reference The segment reference
  we are appending
@param {shaka.extern.Stream} stream
@param {!string} mimeType
@return {{timestamp: ?number, metadata: !Array<shaka.extern.ID3Metadata>}}