Search in sources :

Example 1 with Mp4MetaBox

use of org.jaudiotagger.audio.mp4.atom.Mp4MetaBox 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 2 with Mp4MetaBox

use of org.jaudiotagger.audio.mp4.atom.Mp4MetaBox 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)2 Mp4MetaBox (org.jaudiotagger.audio.mp4.atom.Mp4MetaBox)2 ByteBuffer (java.nio.ByteBuffer)1 CannotReadException (org.jaudiotagger.audio.exceptions.CannotReadException)1 NullBoxIdException (org.jaudiotagger.audio.exceptions.NullBoxIdException)1 Mp4StcoBox (org.jaudiotagger.audio.mp4.atom.Mp4StcoBox)1 Mp4Tag (org.jaudiotagger.tag.mp4.Mp4Tag)1 DefaultMutableTreeNode (org.jaudiotagger.utils.tree.DefaultMutableTreeNode)1