-
-
Save guymac/1468279 to your computer and use it in GitHub Desktop.
/* | |
Command-line application for embedding JPEG cover art in MP3, MP4 and OGG audio files. | |
Based on taglib-1.7 (debian libtag1-dev) | |
and libb64 (http://libb64.sourceforge.net/) needed for OGG Vorbis embedded cover art | |
g++ -I/usr/local/include/taglib -L/usr/local/lib -ltag -lb64 setcover.cpp -o setcover | |
g++ -I/opt/homebrew/include/taglib -L/opt/homebrew/include/b64 -ltag -lb64 setcover.cpp -o setcover | |
*/ | |
/* Copyright (C) 2004 Scott Wheeler <[email protected]> ImageFile and MP3 example | |
* Copyright (C) 2011,2021 Guy McArthur <[email protected]> MP4 and OGG examples | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions | |
* are met: | |
* | |
* 1. Redistributions of source code must retain the above copyright | |
* notice, this list of conditions and the following disclaimer. | |
* 2. Redistributions in binary form must reproduce the above copyright | |
* notice, this list of conditions and the following disclaimer in the | |
* documentation and/or other materials provided with the distribution. | |
* | |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
*/ | |
#include <mpegfile.h> | |
#include <attachedpictureframe.h> | |
#include <id3v2tag.h> | |
#include <mp4file.h> | |
#include <mp4tag.h> | |
#include <mp4coverart.h> | |
#include <vorbisfile.h> | |
#include <xiphcomment.h> | |
#include <flacpicture.h> | |
#ifndef BUFFERSIZE | |
#define BUFFERSIZE 8192 | |
#endif | |
#include <encode.h> | |
#include <iostream> | |
#include <sstream> | |
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|ogg> cover.jpg" << std::endl; | |
return 1; | |
} | |
TagLib::String fileName = argv[1]; | |
TagLib::String fileType = fileName.substr(fileName.size() - 3).upper(); | |
ImageFile imageFile(argv[2]); | |
TagLib::ByteVector imageData = imageFile.data(); | |
if (fileType == "M4A") | |
{ | |
// read the image file | |
TagLib::MP4::CoverArt coverArt((TagLib::MP4::CoverArt::Format) 0x0D, imageData); | |
// 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(); | |
} | |
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(imageData); | |
tag->addFrame(frame); | |
audioFile.save(); | |
} | |
else if (fileType == "OGG") | |
{ | |
TagLib::Ogg::Vorbis::File audioFile(argv[1]); | |
TagLib::Ogg::XiphComment *tag = audioFile.tag(); | |
/* | |
PROPOSED http://wiki.xiph.org/VorbisComment#METADATA_BLOCK_PICTURE | |
*/ | |
TagLib::FLAC::Picture* picture = new TagLib::FLAC::Picture(); | |
picture->setData(imageData); | |
picture->setType((TagLib::FLAC::Picture::Type) 0x03); // FrontCover | |
picture->setMimeType("image/jpeg"); | |
picture->setDescription("Front Cover"); | |
TagLib::ByteVector block = picture->render(); | |
base64::encoder b64enc; | |
std::stringstream in, out; | |
in.read(block.data(), block.size()); | |
b64enc.encode(in, out); | |
out.write(block.data(), out.tellp()); | |
tag->addField("METADATA_BLOCK_PICTURE", block, true); | |
/* | |
UNOFFICIAL DEPRECATED http://wiki.xiph.org/VorbisComment#Unofficial_COVERART_field_.28deprecated.29 | |
*/ | |
tag->addField("COVERART", block, true); | |
audioFile.save(); | |
} | |
else | |
{ | |
std::cout << fileType << " is unsupported." << std::endl; | |
} | |
} |
To ermstp, the error tells you exactly what to do: add -lcrypto to the command line.
I have compilation error telling me:
g++: error: base64.o: No such file or directory
Where should it be?
Okay, got it. I had to install base64encoding from http://code.google.com/p/base64encoding/. But now i have all undefined references for TagLib, which I installed
g++ -g -I. -I/usr/local/include/taglib -L/usr/local/lib -lz -ltag -lssl -lcrypto setcover.cpp -o setcover base64.o
/tmp/cc1UOJCy.o: In function
main':
/home/ivan/Applications/cover_art/setcover.cpp:80: undefined reference to TagLib::String::String(char const*, TagLib::String::Type)' /home/ivan/Applications/cover_art/setcover.cpp:81: undefined reference to
TagLib::String::size() const'
/home/ivan/Applications/cover_art/setcover.cpp:81: undefined reference to TagLib::String::substr(unsigned int, unsigned int) const' /home/ivan/Applications/cover_art/setcover.cpp:81: undefined reference to
TagLib::String::upper() const'
/home/ivan/Applications/cover_art/setcover.cpp:81: undefined reference to TagLib::String::~String()' /home/ivan/Applications/cover_art/setcover.cpp:86: undefined reference to
TagLib::String::operator==(char const*) const'
/home/ivan/Applications/cover_art/setcover.cpp:89: undefined reference to TagLib::MP4::CoverArt::CoverArt(TagLib::MP4::CoverArt::Format, TagLib::ByteVector const&)' /home/ivan/Applications/cover_art/setcover.cpp:92: undefined reference to
TagLib::MP4::File::File(char const*, bool, TagLib::AudioProperties::ReadStyle)'
`
I've updated it, changed from openssl and Google's base64 to the (public domain) b64 library. Tested compiling and running on Mac with home-brew (which has the taglib and libb64 packages).
I'm getting a compile error when g++'ing
$ g++ -g -I. -I/usr/local/include/taglib -L/usr/local/lib -ltag -lssl setcover.cpp -o setcover base64.o
/usr/bin/ld: base64.o: undefined reference to symbol 'BIO_ctrl@@libcrypto.so.10'
/usr/bin/ld: note: 'BIO_ctrl@@libcrypto.so.10' is defined in DSO /lib64/libcrypto.so.10 so try adding it to the linker command line
/lib64/libcrypto.so.10: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status
Running Fedora18 x86_64. Any idea what this could be?