Package org.jaudiotagger.audio.mp4

Examples of org.jaudiotagger.audio.mp4.Mp4FileReader


    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, Mp4NotMetaFieldKey.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, Mp4NotMetaFieldKey.UDTA.getFieldName());
        if (boxHeader != null) {
            //Level 3-Searching for "meta" within udta
            boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4NotMetaFieldKey.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, Mp4NotMetaFieldKey.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, Mp4NotMetaFieldKey.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, Mp4NotMetaFieldKey.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.info("headerlengthsays:" + length + "datalength:" + metadataBuffer.limit());
        int read = 0;
        //logger.info("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.info("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;
    }
View Full Code Here


            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(Mp4NotMetaFieldKey.MOOV.getFieldName())) {
                    moovNode = newAtom;
                    moovHeader = boxHeader;

                    long filePosStart = fc.position();
                    moovBuffer = ByteBuffer.allocate(boxHeader.getDataLength());
                    fc.read(moovBuffer);
                    moovBuffer.rewind();

                    /*Maybe needed but dont have test case yet
                    if(filePosStart + boxHeader.getDataLength() > fc.size())
                    {
                        throw new CannotReadException("The atom states its datalength to be "+boxHeader.getDataLength()
                                + "but there are only "+fc.size()+"bytes in the file and already at position "+filePosStart);   
                    }
                    */
                    buildChildrenOfNode(moovBuffer, newAtom);
                    fc.position(filePosStart);
                } else if (boxHeader.getId().equals(Mp4NotMetaFieldKey.FREE.getFieldName())) {
                    //Might be multiple in different locations
                    freeNodes.add(newAtom);
                } else if (boxHeader.getId().equals(Mp4NotMetaFieldKey.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 {
            //If we cant find the audio then we cannot modify this file so better to throw exception
            //now rather than later when try and write to it.
View Full Code Here

    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()));
                }
            }
        }
    }
View Full Code Here

     * @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't where found under track or tags atom
        if (parentBoxHeader.getId().equals(Mp4NotMetaFieldKey.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't 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(Mp4NotMetaFieldKey.UDTA.getFieldName())) {
                    udtaNode = newAtom;
                }
                //only interested in metaNode that is child of udta node
                else if (boxHeader.getId().equals(Mp4NotMetaFieldKey.META.getFieldName()) && parentBoxHeader.getId().equals(Mp4NotMetaFieldKey.UDTA.getFieldName())) {
                    metaNode = newAtom;
                } else if (boxHeader.getId().equals(Mp4NotMetaFieldKey.HDLR.getFieldName()) && parentBoxHeader.getId().equals(Mp4NotMetaFieldKey.META.getFieldName())) {
                    hdlrWithinMetaNode = newAtom;
                } else if (boxHeader.getId().equals(Mp4NotMetaFieldKey.HDLR.getFieldName())) {
                    hdlrWithinMdiaNode = newAtom;
                } else if (boxHeader.getId().equals(Mp4NotMetaFieldKey.TAGS.getFieldName())) {
                    tagsNode = newAtom;
                } else if (boxHeader.getId().equals(Mp4NotMetaFieldKey.STCO.getFieldName())) {
                    if (stco == null) {
                        stco = new Mp4StcoBox(boxHeader, moovBuffer);
                        stcoNode = newAtom;
                    }
                } else if (boxHeader.getId().equals(Mp4NotMetaFieldKey.ILST.getFieldName())) {
                    DefaultMutableTreeNode parent = (DefaultMutableTreeNode) parentNode.getParent();
                    if (parent != null) {
                        Mp4BoxHeader parentsParent = (Mp4BoxHeader) (parent).getUserObject();
                        if (parentsParent != null) {
                            if (parentBoxHeader.getId().equals(Mp4NotMetaFieldKey.META.getFieldName()) && parentsParent.getId().equals(Mp4NotMetaFieldKey.UDTA.getFieldName())) {
                                ilstNode = newAtom;
                            }
                        }
                    }
                } else if (boxHeader.getId().equals(Mp4NotMetaFieldKey.FREE.getFieldName())) {
View Full Code Here

    }

    protected void build(ByteBuffer data) throws UnsupportedEncodingException {
        //Data actually contains a 'Data' Box so process data using this
        Mp4BoxHeader header = new Mp4BoxHeader(data);
        Mp4DataBox databox = new Mp4DataBox(header, data);
        dataSize = header.getDataLength();
        //Needed for subsequent write
        realDataLength = dataSize - Mp4DataBox.PRE_DATA_LENGTH;
        bytedata = databox.getByteData();
        content = databox.getContent();
View Full Code Here

        super(id, data);
    }

    protected void build(ByteBuffer data) throws UnsupportedEncodingException {
        //Data actually contains a 'Data' Box so process data using this
        Mp4BoxHeader header = new Mp4BoxHeader(data);
        Mp4DataBox databox = new Mp4DataBox(header, data);
        dataSize = header.getDataLength();
        numbers = databox.getNumbers();

        //Disc number always hold four values, we can discard the first one and last one, the second one is the disc no
        //and the third is the total no of discs so only use if not zero
        StringBuffer sb = new StringBuffer();
View Full Code Here

    public String toString() {
        return imageType + ":" + dataBytes.length + "bytes";
    }

    protected void build(ByteBuffer raw) {
        Mp4BoxHeader header = new Mp4BoxHeader(raw);
        dataSize = header.getDataLength();
        dataAndHeaderSize = header.getLength();

        //Skip the version and length fields
        raw.position(raw.position() + Mp4DataBox.PRE_DATA_LENGTH);

        //Read the raw data into byte array
        this.dataBytes = new byte[dataSize - Mp4DataBox.PRE_DATA_LENGTH];
        raw.get(dataBytes, 0, dataBytes.length);

        //Is there room for another atom (remember actually passed all the data so unless Covr is last atom
        //there will be room even though more likely to be for the text top level atom)
        int positionAfterDataAtom = raw.position();
        if (raw.position() + Mp4BoxHeader.HEADER_LENGTH <= raw.limit()) {
            //Is there a following name field (not the norm)
            Mp4BoxHeader nameHeader = new Mp4BoxHeader(raw);
            if (nameHeader.getId().equals(Mp4NameBox.IDENTIFIER)) {
                dataSize += nameHeader.getDataLength();
                dataAndHeaderSize += nameHeader.getLength();
            } else {
                raw.position(positionAfterDataAtom);
            }
        }
View Full Code Here

        return Mp4FieldType.TEXT;
    }

    protected void build(ByteBuffer data) throws UnsupportedEncodingException {
        //Read mean box, set the issuer and skip over data
        Mp4BoxHeader meanBoxHeader = new Mp4BoxHeader(data);
        Mp4MeanBox meanBox = new Mp4MeanBox(meanBoxHeader, data);
        setIssuer(meanBox.getIssuer());
        data.position(data.position() + meanBoxHeader.getDataLength());

        //Read name box, identify what type of field it is
        Mp4BoxHeader nameBoxHeader = new Mp4BoxHeader(data);
        Mp4NameBox nameBox = new Mp4NameBox(nameBoxHeader, data);
        setDescriptor(nameBox.getName());
        data.position(data.position() + nameBoxHeader.getDataLength());

        //Issue 198:There is not actually a data atom there cannot cant be because no room for one
        if (parentHeader.getDataLength() == meanBoxHeader.getLength() + nameBoxHeader.getLength()) {
            id = IDENTIFIER + ":" + issuer + ":" + descriptor;
            setContent("");
            //logger.warning(ErrorMessage.MP4_REVERSE_DNS_FIELD_HAS_NO_DATA.getMsg(id));
        }
        //Usual Case
        else {
            //Read data box, identify the data
            Mp4BoxHeader dataBoxHeader = new Mp4BoxHeader(data);
            Mp4DataBox dataBox = new Mp4DataBox(dataBoxHeader, data);
            setContent(dataBox.getContent());
            data.position(data.position() + dataBoxHeader.getDataLength());

            //Now calculate the id which in order to be unique needs to use all htree values
            id = IDENTIFIER + ":" + issuer + ":" + descriptor;
        }
    }
View Full Code Here

            boxHeader = Mp4BoxHeader.seekWithinLevel(moovBuffer, Mp4NotMetaFieldKey.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, Mp4NotMetaFieldKey.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, Mp4NotMetaFieldKey.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, Mp4NotMetaFieldKey.ILST.getFieldName());
            //This file does not actually contain a tag
View Full Code Here

        //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't where found under track or tags atom
        if (parentBoxHeader.getId().equals(Mp4NotMetaFieldKey.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't actually have any additional data after it so we adjust the buffer
View Full Code Here

TOP

Related Classes of org.jaudiotagger.audio.mp4.Mp4FileReader

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.