Search in sources :

Example 11 with Mp4BoxHeader

use of org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader in project MusicDNA by harjot-oberai.

the class Mp4AtomTree method printAtomTree.

/**
 * Display atom tree
 */
@SuppressWarnings("unchecked")
public void printAtomTree() {
    Enumeration<DefaultMutableTreeNode> e = rootNode.preorderEnumeration();
    DefaultMutableTreeNode nextNode;
    while (e.hasMoreElements()) {
        nextNode = e.nextElement();
        Mp4BoxHeader header = (Mp4BoxHeader) nextNode.getUserObject();
        if (header != null) {
            String tabbing = "";
            for (int i = 1; i < nextNode.getLevel(); i++) {
                tabbing += "\t";
            }
            if (header instanceof NullPadding) {
                System.out.println(tabbing + "Null pad " + " @ " + header.getFilePos() + " of size:" + header.getLength() + " ,ends @ " + (header.getFilePos() + header.getLength()));
            } else {
                System.out.println(tabbing + "Atom " + header.getId() + " @ " + header.getFilePos() + " of size:" + header.getLength() + " ,ends @ " + (header.getFilePos() + header.getLength()));
            }
        }
    }
}
Also used : Mp4BoxHeader(org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader) DefaultMutableTreeNode(org.jaudiotagger.utils.tree.DefaultMutableTreeNode) NullPadding(org.jaudiotagger.audio.mp4.atom.NullPadding)

Example 12 with Mp4BoxHeader

use of org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader in project MusicDNA by harjot-oberai.

the class Mp4AtomTree method buildChildrenOfNode.

/**
 * @param moovBuffer
 * @param parentNode
 * @throws IOException
 * @throws CannotReadException
 */
public void buildChildrenOfNode(ByteBuffer moovBuffer, DefaultMutableTreeNode parentNode) throws IOException, CannotReadException {
    Mp4BoxHeader boxHeader;
    // Preprocessing for nodes that contain data before their children atoms
    Mp4BoxHeader parentBoxHeader = (Mp4BoxHeader) parentNode.getUserObject();
    // We set the buffers position back to this after processing the children
    int justAfterHeaderPos = moovBuffer.position();
    // Preprocessing for meta that normally contains 4 data bytes, but doesn'timer where found under track or tags atom
    if (parentBoxHeader.getId().equals(Mp4AtomIdentifier.META.getFieldName())) {
        Mp4MetaBox meta = new Mp4MetaBox(parentBoxHeader, moovBuffer);
        meta.processData();
        try {
            boxHeader = new Mp4BoxHeader(moovBuffer);
        } catch (NullBoxIdException nbe) {
            // It might be that the meta box didn'timer actually have any additional data after it so we adjust the buffer
            // to be immediately after metabox and code can retry
            moovBuffer.position(moovBuffer.position() - Mp4MetaBox.FLAGS_LENGTH);
        } finally {
            // Skip back last header cos this was only a test
            moovBuffer.position(moovBuffer.position() - Mp4BoxHeader.HEADER_LENGTH);
        }
    }
    // Defines where to start looking for the first child node
    int startPos = moovBuffer.position();
    while (moovBuffer.position() < ((startPos + parentBoxHeader.getDataLength()) - Mp4BoxHeader.HEADER_LENGTH)) {
        boxHeader = new Mp4BoxHeader(moovBuffer);
        if (boxHeader != null) {
            boxHeader.setFilePos(moovHeader.getFilePos() + moovBuffer.position());
            logger.finest("Atom " + boxHeader.getId() + " @ " + boxHeader.getFilePos() + " of size:" + boxHeader.getLength() + " ,ends @ " + (boxHeader.getFilePos() + boxHeader.getLength()));
            DefaultMutableTreeNode newAtom = new DefaultMutableTreeNode(boxHeader);
            parentNode.add(newAtom);
            if (boxHeader.getId().equals(Mp4AtomIdentifier.UDTA.getFieldName())) {
                udtaNode = newAtom;
            } else // only interested in metaNode that is child of udta node
            if (boxHeader.getId().equals(Mp4AtomIdentifier.META.getFieldName()) && parentBoxHeader.getId().equals(Mp4AtomIdentifier.UDTA.getFieldName())) {
                metaNode = newAtom;
            } else if (boxHeader.getId().equals(Mp4AtomIdentifier.HDLR.getFieldName()) && parentBoxHeader.getId().equals(Mp4AtomIdentifier.META.getFieldName())) {
                hdlrWithinMetaNode = newAtom;
            } else if (boxHeader.getId().equals(Mp4AtomIdentifier.HDLR.getFieldName())) {
                hdlrWithinMdiaNode = newAtom;
            } else if (boxHeader.getId().equals(Mp4AtomIdentifier.TAGS.getFieldName())) {
                tagsNode = newAtom;
            } else if (boxHeader.getId().equals(Mp4AtomIdentifier.STCO.getFieldName())) {
                if (stco == null) {
                    stco = new Mp4StcoBox(boxHeader, moovBuffer);
                    stcoNode = newAtom;
                }
            } else if (boxHeader.getId().equals(Mp4AtomIdentifier.ILST.getFieldName())) {
                DefaultMutableTreeNode parent = (DefaultMutableTreeNode) parentNode.getParent();
                if (parent != null) {
                    Mp4BoxHeader parentsParent = (Mp4BoxHeader) (parent).getUserObject();
                    if (parentsParent != null) {
                        if (parentBoxHeader.getId().equals(Mp4AtomIdentifier.META.getFieldName()) && parentsParent.getId().equals(Mp4AtomIdentifier.UDTA.getFieldName())) {
                            ilstNode = newAtom;
                        }
                    }
                }
            } else if (boxHeader.getId().equals(Mp4AtomIdentifier.FREE.getFieldName())) {
                // Might be multiple in different locations
                freeNodes.add(newAtom);
            } else if (boxHeader.getId().equals(Mp4AtomIdentifier.TRAK.getFieldName())) {
                // Might be multiple in different locations, although only one should be audio track
                trakNodes.add(newAtom);
            }
            // For these atoms iterate down to build their children
            if ((boxHeader.getId().equals(Mp4AtomIdentifier.TRAK.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.MDIA.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.MINF.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.STBL.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.UDTA.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.META.getFieldName())) || (boxHeader.getId().equals(Mp4AtomIdentifier.ILST.getFieldName()))) {
                buildChildrenOfNode(moovBuffer, newAtom);
            }
            // Now  adjust buffer for the next atom header at this level
            moovBuffer.position(moovBuffer.position() + boxHeader.getDataLength());
        }
    }
    moovBuffer.position(justAfterHeaderPos);
}
Also used : Mp4BoxHeader(org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader) DefaultMutableTreeNode(org.jaudiotagger.utils.tree.DefaultMutableTreeNode) Mp4MetaBox(org.jaudiotagger.audio.mp4.atom.Mp4MetaBox) NullBoxIdException(org.jaudiotagger.audio.exceptions.NullBoxIdException) Mp4StcoBox(org.jaudiotagger.audio.mp4.atom.Mp4StcoBox)

Example 13 with Mp4BoxHeader

use of org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader in project MusicDNA by harjot-oberai.

the class Mp4TagReader method read.

/*
     * The metadata is stored in the box under the hierachy moov.udta.meta.ilst
     *
     * There are gaps between these boxes

     */
public Mp4Tag read(RandomAccessFile raf) throws CannotReadException, IOException {
    Mp4Tag tag = new Mp4Tag();
    // Get to the facts everything we are interested in is within the moov box, so just load data from file
    // once so no more file I/O needed
    Mp4BoxHeader moovHeader = Mp4BoxHeader.seekWithinLevel(raf, Mp4AtomIdentifier.MOOV.getFieldName());
    if (moovHeader == null) {
        throw new CannotReadException(ErrorMessage.MP4_FILE_NOT_CONTAINER.getMsg());
    }
    ByteBuffer moovBuffer = ByteBuffer.allocate(moovHeader.getLength() - Mp4BoxHeader.HEADER_LENGTH);
    raf.getChannel().read(moovBuffer);
    moovBuffer.rewind();
    // Level 2-Searching for "udta" within "moov"
    Mp4BoxHeader boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.UDTA.getFieldName());
    if (boxHeader != null) {
        // Level 3-Searching for "meta" within udta
        boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.META.getFieldName());
        if (boxHeader == null) {
            logger.warning(ErrorMessage.MP4_FILE_HAS_NO_METADATA.getMsg());
            return tag;
        }
        Mp4MetaBox meta = new Mp4MetaBox(boxHeader, moovBuffer);
        meta.processData();
        // Level 4- Search for "ilst" within meta
        boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.ILST.getFieldName());
        // This file does not actually contain a tag
        if (boxHeader == null) {
            logger.warning(ErrorMessage.MP4_FILE_HAS_NO_METADATA.getMsg());
            return tag;
        }
    } else {
        // Level 2-Searching for "meta" not within udta
        boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.META.getFieldName());
        if (boxHeader == null) {
            logger.warning(ErrorMessage.MP4_FILE_HAS_NO_METADATA.getMsg());
            return tag;
        }
        Mp4MetaBox meta = new Mp4MetaBox(boxHeader, moovBuffer);
        meta.processData();
        // Level 3- Search for "ilst" within meta
        boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4AtomIdentifier.ILST.getFieldName());
        // This file does not actually contain a tag
        if (boxHeader == null) {
            logger.warning(ErrorMessage.MP4_FILE_HAS_NO_METADATA.getMsg());
            return tag;
        }
    }
    // Size of metadata (exclude the size of the ilst parentHeader), take a slice starting at
    // metadata children to make things safer
    int length = boxHeader.getLength() - Mp4BoxHeader.HEADER_LENGTH;
    ByteBuffer metadataBuffer = moovBuffer.slice();
    // Datalength is longer are there boxes after ilst at this level?
    logger.config("headerlengthsays:" + length + "datalength:" + metadataBuffer.limit());
    int read = 0;
    logger.config("Started to read metadata fields at position is in metadata buffer:" + metadataBuffer.position());
    while (read < length) {
        // Read the boxHeader
        boxHeader.update(metadataBuffer);
        // Create the corresponding datafield from the id, and slice the buffer so position of main buffer
        // wont get affected
        logger.config("Next position is at:" + metadataBuffer.position());
        createMp4Field(tag, boxHeader, metadataBuffer.slice());
        // Move position in buffer to the start of the next parentHeader
        metadataBuffer.position(metadataBuffer.position() + boxHeader.getDataLength());
        read += boxHeader.getLength();
    }
    return tag;
}
Also used : Mp4Tag(org.jaudiotagger.tag.mp4.Mp4Tag) Mp4BoxHeader(org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader) CannotReadException(org.jaudiotagger.audio.exceptions.CannotReadException) Mp4MetaBox(org.jaudiotagger.audio.mp4.atom.Mp4MetaBox) ByteBuffer(java.nio.ByteBuffer)

Aggregations

Mp4BoxHeader (org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader)13 Mp4DataBox (org.jaudiotagger.tag.mp4.atom.Mp4DataBox)7 DefaultMutableTreeNode (org.jaudiotagger.utils.tree.DefaultMutableTreeNode)3 ByteBuffer (java.nio.ByteBuffer)2 CannotReadException (org.jaudiotagger.audio.exceptions.CannotReadException)2 NullBoxIdException (org.jaudiotagger.audio.exceptions.NullBoxIdException)2 Mp4MetaBox (org.jaudiotagger.audio.mp4.atom.Mp4MetaBox)2 NullPadding (org.jaudiotagger.audio.mp4.atom.NullPadding)2 FileChannel (java.nio.channels.FileChannel)1 Mp4StcoBox (org.jaudiotagger.audio.mp4.atom.Mp4StcoBox)1 Mp4Tag (org.jaudiotagger.tag.mp4.Mp4Tag)1 Mp4MeanBox (org.jaudiotagger.tag.mp4.atom.Mp4MeanBox)1 Mp4NameBox (org.jaudiotagger.tag.mp4.atom.Mp4NameBox)1 DefaultTreeModel (org.jaudiotagger.utils.tree.DefaultTreeModel)1