⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 id3v22frame.java

📁 java+eclipse做的TTPlayer
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
     * Creates a new ID3v22Frame datatype by reading from byteBuffer.
     *
     * @param byteBuffer to read from
     */
    public ID3v22Frame(ByteBuffer byteBuffer, String loggingFilename) throws InvalidFrameException
    {
        setLoggingFilename(loggingFilename);
        read(byteBuffer);
    }

    /**
     * Creates a new ID3v23Frame datatype by reading from byteBuffer.
     *
     * @param byteBuffer to read from
     * @deprecated use {@link #ID3v22Frame(ByteBuffer,String)} instead
     */
    public ID3v22Frame(ByteBuffer byteBuffer) throws InvalidFrameException
    {
        this(byteBuffer, "");
    }

    /**
     * Return size of frame
     *
     * @return int size of frame
     */
    public int getSize()
    {
        return frameBody.getSize() + FRAME_HEADER_SIZE;
    }

    /**
     * Read frame from file.
     * Read the frame header then delegate reading of data to frame body.
     *
     * @param byteBuffer
     */
    public void read(ByteBuffer byteBuffer) throws InvalidFrameException
    {
        byte[] buffer = new byte[FRAME_ID_SIZE];

        if (byteBuffer.position() + FRAME_HEADER_SIZE >= byteBuffer.limit())
        {
            logger.warning("No space to find another frame:");
            throw new InvalidFrameException(" No space to find another frame");
        }

        // Read the FrameID Identifier
        byteBuffer.get(buffer, 0, FRAME_ID_SIZE);
        identifier = new String(buffer);
        logger.info("Read Frame from file identifier is:" + identifier);

        // Is this a valid identifier?
        if (isValidID3v2FrameIdentifier(identifier) == false)
        {
            logger.info("Invalid identifier:" + identifier);
            byteBuffer.position(byteBuffer.position() - (FRAME_ID_SIZE - 1));
            throw new InvalidFrameIdentifierException(identifier + " is not a valid ID3v2.20 frame");
        }
        //Read Frame Size (same size as Frame Id so reuse buffer)
        byteBuffer.get(buffer, 0, FRAME_SIZE_SIZE);
        frameSize = decodeSize(buffer);
        if (frameSize < 0)
        {
            throw new InvalidFrameException(identifier + " has invalid size of:" + frameSize);
        }
        else if (frameSize == 0)
        {
            logger.warning("Empty Frame:" + identifier);
            throw new EmptyFrameException(identifier + " is empty frame");
        }
        else if (frameSize > byteBuffer.remaining())
        {
            logger.warning("Invalid Frame size larger than size before mp3 audio:" + identifier);
            throw new InvalidFrameException(identifier + " is invalid frame");
        }
        else
        {
            logger.fine("Frame Size Is:" + frameSize);
            //Convert v2.2 to v2.4 id just for reading the data
            String id = (String) ID3Tags.convertFrameID22To24(identifier);
            if (id == null)
            {
                //OK,it may be convertable to a v.3 id even though not valid v.4
                id = (String) ID3Tags.convertFrameID22To23(identifier);
                if (id == null)
                {
                    // Is it a valid v22 identifier so should be able to find a
                    // frame body for it.
                    if (ID3Tags.isID3v22FrameIdentifier(identifier) == true)
                    {
                        id = identifier;
                    }
                    // Unknown so will be created as FrameBodyUnsupported
                    else
                    {
                        id = UNSUPPORTED_ID;
                    }
                }
            }
            logger.fine("Identifier was:" + identifier + " reading using:" + id);

            //Create Buffer that only contains the body of this frame rather than the remainder of tag
            ByteBuffer frameBodyBuffer = byteBuffer.slice();
            frameBodyBuffer.limit(frameSize);

            try
            {
                frameBody = readBody(id, frameBodyBuffer, frameSize);
            }
            finally
            {
                //Update position of main buffer, so no attempt is made to reread these bytes
                byteBuffer.position(byteBuffer.position() + frameSize);
            }
        }
    }

    /**
     * Read Frame Size, which has to be decoded
     */
    private int decodeSize(byte[] buffer)
    {
        BigInteger bi = new BigInteger(buffer);
        int tmpSize = bi.intValue();
        if (tmpSize < 0)
        {
            logger.warning("Invalid Frame Size of:" + tmpSize + "Decoded from bin:" + Integer.toBinaryString(tmpSize) + "Decoded from hex:" + Integer.toHexString(tmpSize));
        }
        return tmpSize;
    }


    /**
     * Write Frame raw data
     *
     * @throws IOException
     */
    public void write(ByteArrayOutputStream tagBuffer)
    {
        logger.info("Write Frame to Buffer" + getIdentifier());
        //This is where we will write header, move position to where we can
        //write body
        ByteBuffer headerBuffer = ByteBuffer.allocate(FRAME_HEADER_SIZE);

        //Write Frame Body Data
        ByteArrayOutputStream bodyOutputStream = new ByteArrayOutputStream();
        ((AbstractID3v2FrameBody) frameBody).write(bodyOutputStream);

        //Write Frame Header
        //Write Frame ID must adjust can only be 3 bytes long
        headerBuffer.put(Utils.getDefaultBytes(getIdentifier(),"ISO-8859-1"), 0, FRAME_ID_SIZE);
        encodeSize(headerBuffer, frameBody.getSize());

        //Add header to the Byte Array Output Stream
        try
        {
            tagBuffer.write(headerBuffer.array());

            //Add body to the Byte Array Output Stream
            tagBuffer.write(bodyOutputStream.toByteArray());
        }
        catch(IOException ioe)
        {
             //This could never happen coz not writing to file, so convert to RuntimeException
             throw new RuntimeException(ioe);
        }
    }

    /**
     * Write Frame Size (can now be accurately calculated, have to convert 4 byte int
     * to 3 byte format.
     */
    private void encodeSize(ByteBuffer headerBuffer, int size)
    {
        headerBuffer.put((byte) ((size & 0x00FF0000) >> 16));
        headerBuffer.put((byte) ((size & 0x0000FF00) >> 8));
        headerBuffer.put((byte) (size & 0x000000FF));
        logger.fine("Frame Size Is Actual:" + size + ":Encoded bin:" + Integer.toBinaryString(size) + ":Encoded Hex" + Integer.toHexString(size));
    }

    /**
     * Does the frame identifier meet the syntax for a idv3v2 frame identifier.
     * must start with a capital letter and only contain capital letters and numbers
     *
     * @param identifier
     * @return
     */
    public boolean isValidID3v2FrameIdentifier(String identifier)
    {
        Matcher m = validFrameIdentifier.matcher(identifier);
        return m.matches();
    }

    /**
     * Return String Representation of body
     */
    public void createStructure()
    {
        MP3File.getStructureFormatter().openHeadingElement(TYPE_FRAME, getIdentifier());
        MP3File.getStructureFormatter().addElement(TYPE_FRAME_SIZE, frameSize);
        frameBody.createStructure();
        MP3File.getStructureFormatter().closeHeadingElement(TYPE_FRAME);
    }

     /**
     *
     * @return true if considered a common frame
     */
    public boolean isCommon()
    {
        return ID3v22Frames.getInstanceOf().isCommon(getId());
    }

     /**
     *
     * @return true if considered a common frame
     */
    public boolean isBinary()
    {
        return ID3v22Frames.getInstanceOf().isBinary(getId());
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -