FileDocCategorySizeDatePackage
AsfFileWriter.javaAPI DocJaudiotagger 2.0.46171Wed Mar 30 16:11:52 BST 2011org.jaudiotagger.audio.asf

AsfFileWriter

public class AsfFileWriter extends org.jaudiotagger.audio.generic.AudioFileWriter
This class writes given tags to ASF files containing WMA content.

author
Christian Laireiter

Fields Summary
Constructors Summary
Methods Summary
protected voiddeleteTag(java.io.RandomAccessFile raf, java.io.RandomAccessFile tempRaf)
{@inheritDoc}

        writeTag(new AsfTag(true), raf, tempRaf);
    
private boolean[]searchExistence(org.jaudiotagger.audio.asf.data.ChunkContainer container, org.jaudiotagger.audio.asf.data.MetadataContainer[] metaContainers)

        assert container != null;
        assert metaContainers != null;
        final boolean[] result = new boolean[metaContainers.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = container.hasChunkByGUID(metaContainers[i]
                    .getContainerType().getContainerGUID());
        }
        return result;
    
protected voidwriteTag(org.jaudiotagger.tag.Tag tag, java.io.RandomAccessFile raf, java.io.RandomAccessFile rafTemp)
{@inheritDoc}

        /*
         * Since this implementation should not change the structure of the ASF
         * file (locations of content description chunks), we need to read the
         * content description chunk and the extended content description chunk
         * from the source file. In the second step we need to determine which
         * modifier (asf header or asf extended header) gets the appropriate
         * modifiers. The following policies are applied: if the source does not
         * contain any descriptor, the necessary descriptors are appended to the
         * header object.
         * 
         * if the source contains only one descriptor in the header extension
         * object, and the other type is needed as well, the other one will be
         * put into the header extension object.
         * 
         * for each descriptor type, if an object is found, an updater will be
         * configured.
         */
        final AsfHeader sourceHeader = AsfHeaderReader.readTagHeader(raf);
        raf.seek(0); // Reset for the streamer
        /*
         * Now createField modifiers for metadata descriptor and extended content
         * descriptor as implied by the given Tag.
         */
        // TODO not convinced that we need to copy fields here
        final AsfTag copy = new AsfTag(tag, true);
        final MetadataContainer[] distribution = TagConverter
                .distributeMetadata(copy);
        final boolean[] existHeader = searchExistence(sourceHeader,
                distribution);
        final boolean[] existExtHeader = searchExistence(sourceHeader
                .getExtendedHeader(), distribution);
        // Modifiers for the asf header object
        final List<ChunkModifier> headerModifier = new ArrayList<ChunkModifier>();
        // Modifiers for the asf header extension object
        final List<ChunkModifier> extHeaderModifier = new ArrayList<ChunkModifier>();
        for (int i = 0; i < distribution.length; i++) {
            final WriteableChunkModifer modifier = new WriteableChunkModifer(
                    distribution[i]);
            if (existHeader[i]) {
                // Will remove or modify chunks in ASF header
                headerModifier.add(modifier);
            } else if (existExtHeader[i]) {
                // Will remove or modify chunks in extended header
                extHeaderModifier.add(modifier);
            } else {
                // Objects (chunks) will be added here.
                if (i == 0 || i == 2 || i == 1) {
                    // Add content description and extended content description
                    // at header for maximum compatibility
                    headerModifier.add(modifier);
                } else {
                    // For now, the rest should be created at extended header
                    // since other positions aren't known.
                    extHeaderModifier.add(modifier);
                }
            }
        }
        // only addField an AsfExtHeaderModifier, if there is actually something to
        // change (performance)
        if (!extHeaderModifier.isEmpty()) {
            headerModifier.add(new AsfExtHeaderModifier(extHeaderModifier));
        }
        new AsfStreamer()
                .createModifiedCopy(new RandomAccessFileInputstream(raf),
                        new RandomAccessFileOutputStream(rafTemp),
                        headerModifier);