org.jaudiotagger.audio.mp4
Class Mp4TagWriter

java.lang.Object
  extended by org.jaudiotagger.audio.mp4.Mp4TagWriter

public class Mp4TagWriter
extends java.lang.Object

Writes metadata from mp4, the metadata tags are held under the ilst atom as shown below, (note all free atoms are optional).

When writing changes the size of all the atoms upto ilst has to be recalculated, then if the size of the metadata is increased the size of the free atom (below meta) should be reduced accordingly or vice versa. If the size of the metadata has increased by more than the size of the free atom then the size of meta, udta and moov should be recalculated and the top level free atom reduced accordingly If there is not enough space even if using both of the free atoms, then the mdat atom has to be shifted down accordingly to make space, and the stco atom has to have its offsets to mdat chunks table adjusted accordingly. Exceptions are that the meta/udta/ilst do not currently exist, in which udta/meta/ilst are created. Note it is valid to have meta/ilst without udta but this is less common so we always try to write files according to the Apple/iTunes specification. *

 |--- ftyp
 |--- free
 |--- moov
 |......|
 |......|----- mvdh
 |......|----- trak
 |......|----- udta
 |..............|
 |..............|-- meta
 |....................|
 |....................|-- hdlr
 |....................|-- ilst
 |....................|.. ..|
 |....................|.....|---- @nam (Optional for each metadatafield)
 |....................|.....|.......|-- data
 |....................|.....|....... ecetera
 |....................|.....|---- ---- (Optional for reverse dns field)
 |....................|.............|-- mean
 |....................|.............|-- name
 |....................|.............|-- data
 |....................|................ ecetere
 |....................|-- free
 |--- free
 |--- mdat
 


Field Summary
static java.util.logging.Logger logger
           
private  Mp4TagCreator tc
           
 
Constructor Summary
Mp4TagWriter()
           
 
Method Summary
private  void adjustSizeOfMoovHeader(Mp4BoxHeader moovHeader, java.nio.ByteBuffer moovBuffer, int sizeAdjustment, Mp4BoxHeader udtaHeader, Mp4BoxHeader metaHeader)
          When the size of the metadata has changed and it cant be compensated for by free atom we have to adjust the size of the size field upto the moovheader level for the udta atom and its child meta atom.
private  void checkFileWrittenCorrectly(java.io.RandomAccessFile rafTemp, Mp4BoxHeader mdatHeader, java.nio.channels.FileChannel fileWriteChannel, Mp4StcoBox stco)
          Check File Written Correctly
private  void convertandWriteTagsAtomToFreeAtom(java.nio.channels.FileChannel fileWriteChannel, Mp4BoxHeader tagsHeader)
          Replace tags atom (and children) by a free atom
private  void createMetadataAtoms(Mp4BoxHeader moovHeader, java.nio.ByteBuffer moovBuffer, int sizeAdjustment, Mp4BoxHeader udtaHeader, Mp4BoxHeader metaHeader)
           
 void delete(java.io.RandomAccessFile raf, java.io.RandomAccessFile rafTemp)
          Delete the tag

private  int getMetaLevelFreeAtomSize(Mp4AtomTree atomTree)
          Determine the size of the free atom immediately after ilst atom at the same level (if any), we can use this if ilst needs to grow or shrink because of more less metadata
 void write(Tag tag, java.io.RandomAccessFile raf, java.io.RandomAccessFile rafTemp)
          Write tag to rafTemp file
private  void writeDataAfterIlst(java.nio.channels.FileChannel fileReadChannel, java.nio.channels.FileChannel fileWriteChannel, Mp4BoxHeader tagsHeader)
          Write data after ilst upto the end of the file
private  void writeDataUptoIncludingIlst(java.nio.channels.FileChannel fileReadChannel, java.nio.channels.FileChannel fileWriteChannel, int oldIlstSize, int startIlstWithinFile, java.nio.ByteBuffer rawIlstData)
          Write the data including new ilst
private  void writeMetadataSameSize(java.nio.ByteBuffer rawIlstData, long oldIlstSize, long startIstWithinFile, java.nio.channels.FileChannel fileReadChannel, java.nio.channels.FileChannel fileWriteChannel, Mp4BoxHeader tagsHeader)
          Replace the ilst metadata

Because it is the same size as the original data nothing else has to be modified

private  void writeNeroData(java.nio.channels.FileChannel fileReadChannel, java.nio.channels.FileChannel fileWriteChannel, Mp4BoxHeader tagsHeader)
          If the existing files contains a tags atom and chp1 atom underneath the meta atom that means the file was encoded by Nero.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

logger

public static java.util.logging.Logger logger

tc

private Mp4TagCreator tc
Constructor Detail

Mp4TagWriter

public Mp4TagWriter()
Method Detail

writeMetadataSameSize

private void writeMetadataSameSize(java.nio.ByteBuffer rawIlstData,
                                   long oldIlstSize,
                                   long startIstWithinFile,
                                   java.nio.channels.FileChannel fileReadChannel,
                                   java.nio.channels.FileChannel fileWriteChannel,
                                   Mp4BoxHeader tagsHeader)
                            throws CannotWriteException,
                                   java.io.IOException
Replace the ilst metadata

Because it is the same size as the original data nothing else has to be modified

Parameters:
rawIlstData -
oldIlstSize -
startIstWithinFile -
fileReadChannel -
fileWriteChannel -
Throws:
CannotWriteException
java.io.IOException

writeNeroData

private void writeNeroData(java.nio.channels.FileChannel fileReadChannel,
                           java.nio.channels.FileChannel fileWriteChannel,
                           Mp4BoxHeader tagsHeader)
                    throws java.io.IOException
If the existing files contains a tags atom and chp1 atom underneath the meta atom that means the file was encoded by Nero. Applications such as foobar read this non-standard tag before the more usual data within ilst causing problems. So the solution is to convert the tags atom and its children into a free atom whilst leaving the chp1 atom alone.

Parameters:
fileReadChannel -
fileWriteChannel -
tagsHeader -
Throws:
java.io.IOException

adjustSizeOfMoovHeader

private void adjustSizeOfMoovHeader(Mp4BoxHeader moovHeader,
                                    java.nio.ByteBuffer moovBuffer,
                                    int sizeAdjustment,
                                    Mp4BoxHeader udtaHeader,
                                    Mp4BoxHeader metaHeader)
                             throws java.io.IOException
When the size of the metadata has changed and it cant be compensated for by free atom we have to adjust the size of the size field upto the moovheader level for the udta atom and its child meta atom.

Parameters:
moovHeader -
moovBuffer -
sizeAdjustment - can be negative or positive *
udtaHeader -
metaHeader -
Throws:
java.io.IOException

createMetadataAtoms

private void createMetadataAtoms(Mp4BoxHeader moovHeader,
                                 java.nio.ByteBuffer moovBuffer,
                                 int sizeAdjustment,
                                 Mp4BoxHeader udtaHeader,
                                 Mp4BoxHeader metaHeader)
                          throws java.io.IOException
Throws:
java.io.IOException

write

public void write(Tag tag,
                  java.io.RandomAccessFile raf,
                  java.io.RandomAccessFile rafTemp)
           throws CannotWriteException,
                  java.io.IOException
Write tag to rafTemp file

Parameters:
tag - tag data
raf - current file
rafTemp - temporary file for writing
Throws:
CannotWriteException
java.io.IOException

convertandWriteTagsAtomToFreeAtom

private void convertandWriteTagsAtomToFreeAtom(java.nio.channels.FileChannel fileWriteChannel,
                                               Mp4BoxHeader tagsHeader)
                                        throws java.io.IOException
Replace tags atom (and children) by a free atom

Parameters:
fileWriteChannel -
tagsHeader -
Throws:
java.io.IOException

writeDataUptoIncludingIlst

private void writeDataUptoIncludingIlst(java.nio.channels.FileChannel fileReadChannel,
                                        java.nio.channels.FileChannel fileWriteChannel,
                                        int oldIlstSize,
                                        int startIlstWithinFile,
                                        java.nio.ByteBuffer rawIlstData)
                                 throws java.io.IOException
Write the data including new ilst

can be used as long as we dont have to adjust the size of moov header

Parameters:
fileReadChannel -
fileWriteChannel -
oldIlstSize -
startIlstWithinFile -
rawIlstData -
Throws:
java.io.IOException

writeDataAfterIlst

private void writeDataAfterIlst(java.nio.channels.FileChannel fileReadChannel,
                                java.nio.channels.FileChannel fileWriteChannel,
                                Mp4BoxHeader tagsHeader)
                         throws java.io.IOException
Write data after ilst upto the end of the file

Can be used if dont need to adjust size of moov header of modify top level free atoms

Parameters:
fileReadChannel -
fileWriteChannel -
tagsHeader -
Throws:
java.io.IOException

getMetaLevelFreeAtomSize

private int getMetaLevelFreeAtomSize(Mp4AtomTree atomTree)
Determine the size of the free atom immediately after ilst atom at the same level (if any), we can use this if ilst needs to grow or shrink because of more less metadata

Parameters:
atomTree -
Returns:

checkFileWrittenCorrectly

private void checkFileWrittenCorrectly(java.io.RandomAccessFile rafTemp,
                                       Mp4BoxHeader mdatHeader,
                                       java.nio.channels.FileChannel fileWriteChannel,
                                       Mp4StcoBox stco)
                                throws CannotWriteException,
                                       java.io.IOException
Check File Written Correctly

Parameters:
rafTemp -
mdatHeader -
fileWriteChannel -
stco -
Throws:
CannotWriteException
java.io.IOException

delete

public void delete(java.io.RandomAccessFile raf,
                   java.io.RandomAccessFile rafTemp)
            throws java.io.IOException
Delete the tag

This is achieved by writing an empty ilst atom

Parameters:
raf -
rafTemp -
Throws:
java.io.IOException


Copyright © 2005-2010 java.net. All Rights Reserved.