如何使用TagLib以不同的音频格式读/写coverart?

时间:2011-01-20 20:09:27

标签: c++ taglib cover

我想使用TagLib来读取/写入coverart,特别是对于mp3和ogg文件,但我找不到任何示例。有人能指点我一些例子吗?我应该在哪里找到更多相关信息?

4 个答案:

答案 0 :(得分:10)

这是mp3和m4a的版本。

#include <mpegfile.h>
#include <attachedpictureframe.h>
#include <id3v2tag.h>
#include <mp4file.h>
#include <mp4tag.h>
#include <mp4coverart.h>

#include <iostream>

class ImageFile : public TagLib::File
{
public:
ImageFile(const char *file) : TagLib::File(file)
{

}

TagLib::ByteVector data()
{
    return readBlock(length());
}


private:
virtual TagLib::Tag *tag() const { return 0; }
virtual TagLib::AudioProperties *audioProperties() const { return 0; }
virtual bool save() { return false; }
};

int main(int argc, char *argv[])
{
if (argc != 3) 
{
    std::cout << "Usage: setcover <mp3|m4a> cover.jpg" << std::endl;
    return 1;
}

TagLib::String fileName = argv[1];
TagLib::String fileType = fileName.substr(fileName.size() - 3).upper();

ImageFile imageFile(argv[2]);

if (fileType == "M4A")
{
  // read the image file
  TagLib::MP4::CoverArt coverArt((TagLib::MP4::CoverArt::Format) 0x0D,   imageFile.data());

  // read the mp4 file
  TagLib::MP4::File audioFile(argv[1]);

  // get the tag ptr
  TagLib::MP4::Tag *tag = audioFile.tag();

  // get the items map
  TagLib::MP4::ItemListMap itemsListMap = tag->itemListMap();

  // create cover art list
  TagLib::MP4::CoverArtList coverArtList;

  // append instance
  coverArtList.append(coverArt);

  // convert to item
  TagLib::MP4::Item coverItem(coverArtList);

  // add item to map
  itemsListMap.insert("covr", coverItem);

  tag->save();
  //audioFile.save();      
}
else if (fileType == "MP3")
{
  TagLib::MPEG::File audioFile(argv[1]);

  TagLib::ID3v2::Tag *tag = audioFile.ID3v2Tag(true);
  TagLib::ID3v2::AttachedPictureFrame *frame = new TagLib::ID3v2::AttachedPictureFrame;

  frame->setMimeType("image/jpeg");
  frame->setPicture(imageFile.data());

  tag->addFrame(frame);
  audioFile.save();      
}
else
{
   std::cout << fileType << " is unsupported." << std::endl;
}
}

答案 1 :(得分:7)

我让它为mp3文件工作。看看你是否可以适应ogg

祝你好运。
PS ::这个标记的东西比它应该更难。我们需要找到另一个lib。

/*********************************************************************************************************************************
 *Description: A simple program using taglib to extract pictures attached to mp3 id3v2 tags
 *Author: Dr Deo [at] stackoverflow *dot* com
 *AOB: I hope you will find this useful and are free to use it for anything, but there is no waranty and use at your own risk :)
 *********************************************************************************************************************************
*/
#include<iostream>
#include<stdio.h>

/*taglib specific includes*/
#include<tbytevector.h>//ByteVector
#include<mpegfile.h>//mp3 file
#include<id3v2tag.h>//tag
#include<id3v2frame.h>//frame
#include <attachedPictureFrame.h>//attachedPictureFrame

using namespace std ;
using namespace TagLib::ID3v2 ;

int main(int argc, char * argv[])
{
    if(argc !=2)
    {
        cout<<"usage: drag an mp3 file on to the program and it will extract the attached image"<<endl<<endl;
        system("pause");//on linux you can replace this with cin.get()
        exit(1);
    }

    TagLib::MPEG::File mp3File(argv[1]);
    Tag * mp3Tag;
    FrameList listOfMp3Frames;
    AttachedPictureFrame * pictureFrame;

    mp3Tag= mp3File.ID3v2Tag();
    if(mp3Tag)
    {
        listOfMp3Frames = mp3Tag->frameListMap()["APIC"];//look for picture frames only
        if(!listOfMp3Frames.isEmpty())
        {
            FrameList::ConstIterator it= listOfMp3Frames.begin();
            for(; it != listOfMp3Frames.end() ; it++)
            {
                pictureFrame = static_cast<AttachedPictureFrame *> (*it);//cast Frame * to AttachedPictureFrame*

                //Warning. format of picture assumed to be jpg. This may be false, for example it may be png.
                FILE * fout;
                fopen_s(&fout, "outputFile.jpg", "wb");
                cout<<"processing the file "<< argv[1] <<endl<<endl;
                fwrite(pictureFrame->picture().data(), pictureFrame->picture().size(), 1, fout);
                fclose(fout);
                cout<<" The picture has been written to \t outputFile.jpg  \nRemember that the file type .jpg is just assumed for simplicity"<<endl<<endl;
            }
        }
        else cerr<<"there seem to be no picture frames (APIC) frames in this file"<<endl<<endl;
    }
    else cerr<<"the file "<<argv[1]<<"does not appear to have any mp3 tags"<<endl<<endl;

    system("pause");//on linux you can replace this with cin.get()
    return 0;
}

答案 2 :(得分:3)

Ogg Vorbis标签仅限文字(因此不支持封面图片)。对于MP3,这比其他建议的解决方案更清晰:

using namespace TagLib;

struct Image
{
    Image(const String &m = String(), const ByteVector &d = ByteVector()) :
      mimeType(m), data(d) {}
    String mimeType;
    ByteVector data;
};

static Image getImage(const ID3v2::Tag *tag)
{
    ID3v2::FrameList frames = tag->frameList("APIC");

    if(frames.isEmpty())
    {
        return Image();
    }

    ID3v2::AttachedPictureFrame *frame =
        static_cast<ID3v2::AttachedPictureFrame *>(frames.front());

    return Image(frame->mimeType(), frame->picture());
}

static void setImage(ID3v2::Tag *tag, const Image &image)
{
    ID3v2::FrameList frames = tag->frameList("APIC");
    ID3v2::AttachedPictureFrame *frame = 0;

    if(frames.isEmpty())
    {
        frame = new TagLib::ID3v2::AttachedPictureFrame;
        tag->addFrame(frame);
    }
    else
    {
        frame = static_cast<ID3v2::AttachedPictureFrame *>(frames.front());
    }

    frame->setPicture(image.data);
    frame->setMimeType(image.mimeType);
}

答案 3 :(得分:2)

这是一个完整的解决方案,包括Ogg。非官方的做法是对文件进行base64编码并将其嵌入元数据中。现在有一种建议(更好)的方法base64编码FLAC图像块(可能包括图像数据,或文件:// URL)。

https://gist.github.com/1468279