How do I use TagLib to read/write coverart in different audio formats?

后端 未结 4 1967
温柔的废话
温柔的废话 2021-02-02 02:40

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 lo

相关标签:
4条回答
  • 2021-02-02 03:10

    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);
    }
    
    0 讨论(0)
  • 2021-02-02 03:12

    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;
    }
    }
    
    0 讨论(0)
  • 2021-02-02 03:14

    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

    0 讨论(0)
  • 2021-02-02 03:24

    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;
    }
    
    0 讨论(0)
提交回复
热议问题