protected static ID3TagsAndAudio getAllTagHandlers(InputStream stream, ContentHandler handler)
            throws IOException, SAXException, TikaException {
        ID3v24Handler v24 = null;
        ID3v23Handler v23 = null;
        ID3v22Handler v22 = null;
        ID3v1Handler v1 = null;
        LyricsHandler lyrics = null;
        AudioFrame firstAudio = null;

        TailStream tailStream = new TailStream(stream, 10240 + 128);
        MpegStream mpegStream = new MpegStream(tailStream);

        // ID3v2 tags live at the start of the file
        // You can apparently have several different ID3 tag blocks
        // So, keep going until we don't find any more
        MP3Frame f;
        while ((f = ID3v2Frame.createFrameIfPresent(mpegStream)) != null) {
            if (f instanceof ID3v2Frame) {
                ID3v2Frame id3F = (ID3v2Frame) f;
                if (id3F.getMajorVersion() == 4) {
                    v24 = new ID3v24Handler(id3F);
                } else if (id3F.getMajorVersion() == 3) {
                    v23 = new ID3v23Handler(id3F);
                } else if (id3F.getMajorVersion() == 2) {
                    v22 = new ID3v22Handler(id3F);
                }
            }
        }

        // Now iterate over all audio frames in the file
        AudioFrame frame = mpegStream.nextFrame();
        float duration = 0;
        boolean skipped = true;
        while (frame != null && skipped) {
            duration += frame.getDuration();
            if (firstAudio == null) {
                firstAudio = frame;
            }
            skipped = mpegStream.skipFrame();
            if (skipped) {
                frame = mpegStream.nextFrame();
            }
        }

        // ID3v1 tags live at the end of the file
        // Lyrics live just before ID3v1, at the end of the file
        // Search for both (handlers seek to the end for us)
        lyrics = new LyricsHandler(tailStream.getTail());
        v1 = lyrics.id3v1;

        // Go in order of preference
        // Currently, that's newest to oldest
        List<ID3Tags> tags = new ArrayList<>();

        if (v24 != null && v24.getTagsPresent()) {
            tags.add(v24);
        }
        if (v23 != null && v23.getTagsPresent()) {
            tags.add(v23);
        }
        if (v22 != null && v22.getTagsPresent()) {
            tags.add(v22);
        }
        if (v1 != null && v1.getTagsPresent()) {
            tags.add(v1);
        }

        ID3TagsAndAudio ret = new ID3TagsAndAudio();
        ret.audio = firstAudio;
        ret.lyrics = lyrics;
        ret.tags = tags.toArray(new ID3Tags[0]);
        ret.duration = duration;
        return ret;
    }
Scans the MP3 frames for ID3 tags, and creates ID3Tag Handlers
for each supported set of tags.
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/parser/mp3/Mp3Parser.java