Question

How to write vorbis comments metadata, i.e. tags (for example "TITLE"), to the existing FLAC file using libFLAC++ (http://flac.sourceforge.net)?

For example:

const char* fileName = "/path/to/file.flac";

// read tags from the file
FLAC::Metadata::VorbisComment vorbisComment;
FLAC::Metadata::get_tags(fileName, vorbisComment);

// make some changes
vorbisComment.append_comment("TITLE", "This is title");

// write changes back to the file ...
// :-( there is no API for that, i.e. something like this:
// FLAC::Metadata::write_tags(fileName, vorbisComment);
Was it helpful?

Solution

I've analysed metaflac source code (as suggested) and here is a solution to the problem:

#include <FLAC++/metadata.h>

const char* fileName = "/path/to/file.flac";

// read a file using FLAC::Metadata::Chain class
FLAC::Metadata::Chain chain;
if (!chain.read(fileName)) {
    // error handling
    throw ...;
}

// now, find vorbis comment block and make changes in it
{
    FLAC::Metadata::Iterator iterator;
    iterator.init(chain);

    // find vorbis comment block
    FLAC::Metadata::VorbisComment* vcBlock = 0;
    do {
        FLAC::Metadata::Prototype* block = iterator.get_block();
        if (block->get_type() == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
            vcBlock = (FLAC::Metadata::VorbisComment*) block;
            break;
        }
    } while (iterator.next());

    // if not found, create a new one
    if (vcBlock == 0) {
        // create a new block
        vcBlock = new FLAC::Metadata::VorbisComment();

        // move iterator to the end
        while (iterator.next()) {
        }

        // insert a new block at the end
        if (!iterator.insert_block_after(vcBlock)) {
            delete vcBlock;
            // error handling
            throw ...;
        }
    }

    // now, you can make any number of changes to the vorbis comment block,
    // for example you can append TITLE comment:
    vcBlock->append_comment(
        FLAC::Metadata::VorbisComment::Entry("TITLE", "This is title"));
}

// write changes back to the file
if (!chain.write()) {
    // error handling
    throw ...;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top