Search in sources :

Example 1 with NullBoxIdException

use of org.jaudiotagger.audio.exceptions.NullBoxIdException 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)

Example 2 with NullBoxIdException

use of org.jaudiotagger.audio.exceptions.NullBoxIdException 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)

Aggregations

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