Search in sources :

Example 11 with OggPageHeader

use of org.jaudiotagger.audio.ogg.util.OggPageHeader in project MusicDNA by harjot-oberai.

the class OggVorbisTagWriter method write.

public void write(Tag tag, RandomAccessFile raf, RandomAccessFile rafTemp) throws CannotReadException, CannotWriteException, IOException {
    logger.config("Starting to write file:");
    //1st Page:Identification Header
    logger.fine("Read 1st Page:identificationHeader:");
    OggPageHeader pageHeader = OggPageHeader.read(raf);
    raf.seek(pageHeader.getStartByte());
    //Write 1st page (unchanged) and place writer pointer at end of data
    rafTemp.getChannel().transferFrom(raf.getChannel(), 0, pageHeader.getPageLength() + OggPageHeader.OGG_PAGE_HEADER_FIXED_LENGTH + pageHeader.getSegmentTable().length);
    rafTemp.skipBytes(pageHeader.getPageLength() + OggPageHeader.OGG_PAGE_HEADER_FIXED_LENGTH + pageHeader.getSegmentTable().length);
    logger.fine("Written identificationHeader:");
    //2nd page:Comment and Setup if there is enough room, may also (although not normally) contain audio frames
    OggPageHeader secondPageHeader = OggPageHeader.read(raf);
    //2nd Page:Store the end of Header
    long secondPageHeaderEndPos = raf.getFilePointer();
    logger.fine("Read 2nd Page:comment and setup and possibly audio:Header finishes at file position:" + secondPageHeaderEndPos);
    //Get header sizes
    raf.seek(0);
    OggVorbisTagReader.OggVorbisHeaderSizes vorbisHeaderSizes = reader.readOggVorbisHeaderSizes(raf);
    //Convert the OggVorbisComment header to raw packet data
    ByteBuffer newComment = tc.convert(tag);
    //Compute new comment length(this may need to be spread over multiple pages)
    int newCommentLength = newComment.capacity();
    //Calculate new size of new 2nd page
    int newSecondPageDataLength = vorbisHeaderSizes.getSetupHeaderSize() + newCommentLength + vorbisHeaderSizes.getExtraPacketDataSize();
    logger.fine("Old 2nd Page no of packets: " + secondPageHeader.getPacketList().size());
    logger.fine("Old 2nd Page size: " + secondPageHeader.getPageLength());
    logger.fine("Old last packet incomplete: " + secondPageHeader.isLastPacketIncomplete());
    logger.fine("Setup Header Size: " + vorbisHeaderSizes.getSetupHeaderSize());
    logger.fine("Extra Packets: " + vorbisHeaderSizes.getExtraPacketList().size());
    logger.fine("Extra Packet Data Size: " + vorbisHeaderSizes.getExtraPacketDataSize());
    logger.fine("Old comment: " + vorbisHeaderSizes.getCommentHeaderSize());
    logger.fine("New comment: " + newCommentLength);
    logger.fine("New Page Data Size: " + newSecondPageDataLength);
    //Second Page containing new vorbis, setup and possibly some extra packets can fit on one page
    if (isCommentAndSetupHeaderFitsOnASinglePage(newCommentLength, vorbisHeaderSizes.getSetupHeaderSize(), vorbisHeaderSizes.getExtraPacketList())) {
        //we dont care if the last audio packet is split on next page as long as we preserve it
        if ((secondPageHeader.getPageLength() < OggPageHeader.MAXIMUM_PAGE_DATA_SIZE) && (((secondPageHeader.getPacketList().size() == 2) && (!secondPageHeader.isLastPacketIncomplete())) || (secondPageHeader.getPacketList().size() > 2))) {
            logger.fine("Header and Setup remain on single page:");
            replaceSecondPageOnly(vorbisHeaderSizes, newCommentLength, newSecondPageDataLength, secondPageHeader, newComment, secondPageHeaderEndPos, raf, rafTemp);
        } else //Original 2nd page spanned multiple pages so more work to do
        {
            logger.fine("Header and Setup now on single page:");
            replaceSecondPageAndRenumberPageSeqs(vorbisHeaderSizes, newCommentLength, newSecondPageDataLength, secondPageHeader, newComment, raf, rafTemp);
        }
    } else //Bit more complicated, have to create more than one new page and renumber subsequent audio
    {
        logger.fine("Header and Setup with shift audio:");
        replacePagesAndRenumberPageSeqs(vorbisHeaderSizes, newCommentLength, secondPageHeader, newComment, raf, rafTemp);
    }
}
Also used : OggPageHeader(org.jaudiotagger.audio.ogg.util.OggPageHeader) ByteBuffer(java.nio.ByteBuffer)

Aggregations

OggPageHeader (org.jaudiotagger.audio.ogg.util.OggPageHeader)11 CannotReadException (org.jaudiotagger.audio.exceptions.CannotReadException)4 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 ByteBuffer (java.nio.ByteBuffer)3 RandomAccessFile (java.io.RandomAccessFile)2 CannotWriteException (org.jaudiotagger.audio.exceptions.CannotWriteException)2 ArrayList (java.util.ArrayList)1