2011-01-20 6 views
8

Me gustaría utilizar TagLib para leer/escribir Coverart especialmente para archivos mp3 y ogg, pero no pude encontrar ningún ejemplo. ¿Podría alguien señalarme algunos ejemplos? ¿Dónde debo buscar para encontrar más información sobre esto?¿Cómo uso TagLib para leer/escribir Coverart en diferentes formatos de audio?

+0

Wikipedia dice que MP3 y OGG tienen diferentes formatos de etiquetado por lo que su probable que el código de abajo sólo funcionará para mp3. ver este artículo http://en.wikipedia.org/wiki/ID3 –

Respuesta

6

Lo tengo para trabajar con archivos mp3. Vea si puede adaptarlo para ogg

Buena suerte.
PS :: Este material de etiquetado es mucho más difícil de lo que debería ser. Necesitamos encontrar otra 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; 
} 
3

Las etiquetas de Ogg Vorbis son solo de texto (y, como tales, no son compatibles con la carátula). Para MP3, esto es algo más limpio que la otra solución sugerida:

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

No sabía que no hay soporte oficial para la portada en los archivos Ogg. Esto explicaría los problemas con muchos reproductores multimedia :-( – Bernd

+0

Ogg es compatible con las artes del álbum, incluso si es solo texto. –

+1

Es un tanto divertido que me hayan votado negativamente un par de veces sobre esto: ** Soy el autor de TagLib **. En el momento en que escribí este comentario, las etiquetas Xiph en realidad no admitían imágenes (y la especificación recomendaba específicamente usar una secuencia de metadatos separada). Desde entonces, han agregado la opción de texto base64 – scotchi

9

Aquí hay una versión para mp3 y 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; 
} 
} 
2

Aquí hay una solución completa, que incluye Ogg. La forma no oficial de hacerlo ha sido codificar64 base64 el archivo e incrustarlo en los metadatos. Ahora hay una forma propuesta (mejor) de que base64 codifique un bloque de imagen FLAC (que puede incluir los datos de imagen, o un archivo: // URL).

https://gist.github.com/1468279

Cuestiones relacionadas