如何使用 TagLib 读取/写入不同音频格式的封面图?

发布于 2024-10-13 05:53:14 字数 165 浏览 10 评论 0原文

我想使用 TagLib 来读取/写入封面,特别是对于 mp3 和 ogg 文件,但我找不到任何例子。有人能给我举一些例子吗?我应该在哪里寻找有关此内容的更多信息?

I would like to use TagLib to read/write coverart especially for mp3 AND ogg files, but I couldn't find any examples. Could someone point me to some examples? Where should I look to find more information about this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

惟欲睡 2024-10-20 05:53:14

这是 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;
}
}

Here is a version for mp3 and 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;
}
}
美胚控场 2024-10-20 05:53:14

我让它适用于 mp3 文件。看看你是否可以适应 ogg 祝你

好运。
PS::这个标记的东西比应有的要困难得多。我们需要找到另一个库。

/*********************************************************************************************************************************
 *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;
}

I got it to work for mp3 files. See if you can adapt it for ogg

Good luck.
PS::This tagging stuff is way harder than it should be. We need to find another 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;
}
你的背包 2024-10-20 05:53:14

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);
}

Ogg Vorbis tags are text-only (and as such don't support cover art). For MP3s, this is somewhat cleaner than the other solution suggested:

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);
}
长梦不多时 2024-10-20 05:53:14

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

https://gist.github.com/1468279

Here is a complete solution, including Ogg. The unofficial way of doing it has been to base64 encode the file and embed it in the metadata. There is now a proposed (better) way of base64 encoding a FLAC Picture block (which may include the image data, or a file:// URL).

https://gist.github.com/1468279

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文