Search in sources :

Example 1 with DefaultTreeModel

use of org.jaudiotagger.utils.tree.DefaultTreeModel in project MusicDNA by harjot-oberai.

the class Mp4AtomTree method buildTree.

/**
 * Build a tree of the atoms in the file
 *
 * @param raf
 * @param closeExit false to keep randomfileacces open, only used when randomaccessfile already being used
 * @return
 * @throws java.io.IOException
 * @throws org.jaudiotagger.audio.exceptions.CannotReadException
 */
public DefaultTreeModel buildTree(RandomAccessFile raf, boolean closeExit) throws IOException, CannotReadException {
    FileChannel fc = null;
    try {
        fc = raf.getChannel();
        // make sure at start of file
        fc.position(0);
        // Build up map of nodes
        rootNode = new DefaultMutableTreeNode();
        dataTree = new DefaultTreeModel(rootNode);
        // Iterate though all the top level Nodes
        ByteBuffer headerBuffer = ByteBuffer.allocate(Mp4BoxHeader.HEADER_LENGTH);
        while (fc.position() < fc.size()) {
            Mp4BoxHeader boxHeader = new Mp4BoxHeader();
            headerBuffer.clear();
            fc.read(headerBuffer);
            headerBuffer.rewind();
            try {
                boxHeader.update(headerBuffer);
            } catch (NullBoxIdException ne) {
                // If we only get this error after all the expected data has been found we allow it
                if (moovNode != null & mdatNode != null) {
                    NullPadding np = new NullPadding(fc.position() - Mp4BoxHeader.HEADER_LENGTH, fc.size());
                    DefaultMutableTreeNode trailingPaddingNode = new DefaultMutableTreeNode(np);
                    rootNode.add(trailingPaddingNode);
                    logger.warning(ErrorMessage.NULL_PADDING_FOUND_AT_END_OF_MP4.getMsg(np.getFilePos()));
                    break;
                } else {
                    // File appears invalid
                    throw ne;
                }
            }
            boxHeader.setFilePos(fc.position() - Mp4BoxHeader.HEADER_LENGTH);
            DefaultMutableTreeNode newAtom = new DefaultMutableTreeNode(boxHeader);
            // Go down moov
            if (boxHeader.getId().equals(Mp4AtomIdentifier.MOOV.getFieldName())) {
                // and finish
                if (moovNode != null & mdatNode != null) {
                    logger.warning(ErrorMessage.ADDITIONAL_MOOV_ATOM_AT_END_OF_MP4.getMsg(fc.position() - Mp4BoxHeader.HEADER_LENGTH));
                    break;
                }
                moovNode = newAtom;
                moovHeader = boxHeader;
                long filePosStart = fc.position();
                moovBuffer = ByteBuffer.allocate(boxHeader.getDataLength());
                int bytesRead = fc.read(moovBuffer);
                // If Moov atom is incomplete we are not going to be able to read this file properly
                if (bytesRead < boxHeader.getDataLength()) {
                    String msg = ErrorMessage.ATOM_LENGTH_LARGER_THAN_DATA.getMsg(boxHeader.getId(), boxHeader.getDataLength(), bytesRead);
                    throw new CannotReadException(msg);
                }
                moovBuffer.rewind();
                buildChildrenOfNode(moovBuffer, newAtom);
                fc.position(filePosStart);
            } else if (boxHeader.getId().equals(Mp4AtomIdentifier.FREE.getFieldName())) {
                // Might be multiple in different locations
                freeNodes.add(newAtom);
            } else if (boxHeader.getId().equals(Mp4AtomIdentifier.MDAT.getFieldName())) {
                // mdatNode always points to the last mDatNode, normally there is just one mdatnode but do have
                // a valid example of multiple mdatnode
                // if(mdatNode!=null)
                // {
                // throw new CannotReadException(ErrorMessage.MP4_FILE_CONTAINS_MULTIPLE_DATA_ATOMS.getMsg());
                // }
                mdatNode = newAtom;
                mdatNodes.add(newAtom);
            }
            rootNode.add(newAtom);
            fc.position(fc.position() + boxHeader.getDataLength());
        }
        return dataTree;
    } finally {
        // now rather than later when try and write to it.
        if (mdatNode == null) {
            throw new CannotReadException(ErrorMessage.MP4_CANNOT_FIND_AUDIO.getMsg());
        }
        if (closeExit) {
            fc.close();
        }
    }
}
Also used : Mp4BoxHeader(org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader) DefaultMutableTreeNode(org.jaudiotagger.utils.tree.DefaultMutableTreeNode) CannotReadException(org.jaudiotagger.audio.exceptions.CannotReadException) FileChannel(java.nio.channels.FileChannel) DefaultTreeModel(org.jaudiotagger.utils.tree.DefaultTreeModel) NullBoxIdException(org.jaudiotagger.audio.exceptions.NullBoxIdException) ByteBuffer(java.nio.ByteBuffer) NullPadding(org.jaudiotagger.audio.mp4.atom.NullPadding)

Aggregations

ByteBuffer (java.nio.ByteBuffer)1 FileChannel (java.nio.channels.FileChannel)1 CannotReadException (org.jaudiotagger.audio.exceptions.CannotReadException)1 NullBoxIdException (org.jaudiotagger.audio.exceptions.NullBoxIdException)1 Mp4BoxHeader (org.jaudiotagger.audio.mp4.atom.Mp4BoxHeader)1 NullPadding (org.jaudiotagger.audio.mp4.atom.NullPadding)1 DefaultMutableTreeNode (org.jaudiotagger.utils.tree.DefaultMutableTreeNode)1 DefaultTreeModel (org.jaudiotagger.utils.tree.DefaultTreeModel)1