From 238818850f897a8f4c92b0ec76ec13b07ee20d40 Mon Sep 17 00:00:00 2001 From: Hrvoje Senjan Date: Sun, 14 Sep 2014 23:35:53 +0200 Subject: [PATCH 1/1] Add an AudioThumnail --- thumbnail/CMakeLists.txt | 70 +++++++++++++++ thumbnail/audiocreator.cpp | 181 +++++++++++++++++++++++++++++++++++++++ thumbnail/audiocreator.h | 39 +++++++++ thumbnail/audiothumbnail.desktop | 11 +++ 4 files changed, 301 insertions(+) create mode 100644 thumbnail/audiocreator.cpp create mode 100644 thumbnail/audiocreator.h create mode 100644 thumbnail/audiothumbnail.desktop diff --git a/thumbnail/CMakeLists.txt b/thumbnail/CMakeLists.txt index 4c2d5e9..ccff1ad 100644 --- a/thumbnail/CMakeLists.txt +++ b/thumbnail/CMakeLists.txt @@ -22,6 +22,63 @@ set_package_properties(Exiv2 PROPERTIES DESCRIPTION "A library to access image m macro_bool_to_01(EXIV2_FOUND HAVE_EXIV2) +set(WITH_TAGLIB ON CACHE BOOL "build with TagLib") +set(WITH_FLAC ON CACHE BOOL "build with FLAC") + +### Check for taglib +set(TAGLIB_LIBRARIES) +set(TAGLIB_CFLAGS) +if(WITH_TAGLIB) + find_program(TAGLIBCONFIG_EXECUTABLE NAMES taglib-config PATHS /usr/bin /usr/local/bin ${BIN_INSTALL_DIR}) + if(TAGLIBCONFIG_EXECUTABLE) + exec_program(${TAGLIBCONFIG_EXECUTABLE} ARGS --libs RETURN_VALUE _return_VALUE OUTPUT_VARIABLE TAGLIB_LIBRARIES) + exec_program(${TAGLIBCONFIG_EXECUTABLE} ARGS --cflags RETURN_VALUE _return_VALUE OUTPUT_VARIABLE TAGLIB_CFLAGS) + exec_program(${TAGLIBCONFIG_EXECUTABLE} ARGS --version RETURN_VALUE _return_VALUE OUTPUT_VARIABLE TAGLIB_VERSION) + if(TAGLIB_LIBRARIES AND TAGLIB_CFLAGS AND TAGLIB_VERSION) + if( ${TAGLIB_VERSION} VERSION_LESS 1.4 ) + message(FATAL_ERROR "Needed at least taglib 1.4") + else() + set(TAGLIB_INSTALLED_VERSION_OK TRUE) + endif() + if(TAGLIB_INSTALLED_VERSION_OK) + set(HAVE_TAGLIB 1) + message(STATUS "TagLib found: ${TAGLIB_LIBRARIES}") + endif(TAGLIB_INSTALLED_VERSION_OK) + endif(TAGLIB_LIBRARIES AND TAGLIB_CFLAGS AND TAGLIB_VERSION) + endif(TAGLIBCONFIG_EXECUTABLE) + if (NOT HAVE_TAGLIB) + message(FATAL_ERROR "Could not find Taglib") + endif (NOT HAVE_TAGLIB) +endif(WITH_TAGLIB) + +### Check for FLAC++ +set(FLAC_LIBRARIES) +if(WITH_FLAC) + find_path(FLACPP_INCLUDE_DIR FLAC++/metadata.h) + find_library(FLAC_LIBRARY NAMES FLAC) + find_library(FLACPP_LIBRARY NAMES FLAC++) + if(FLACPP_INCLUDE_DIR AND FLAC_LIBRARY AND FLACPP_LIBRARY) + set(FLAC_LIBRARIES ${FLACPP_LIBRARY} ${FLAC_LIBRARY}) + message(STATUS "FLAC++ found: ${FLAC_LIBRARIES}") + set(HAVE_FLAC 1) + + set(_CMAKE_REQUIRED_LIBRARIES_TMP ${CMAKE_REQUIRED_LIBRARIES}) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${FLAC_LIBRARIES} ${FLACPP_LIBRARIES}) + CHECK_CXX_SOURCE_COMPILES("#include \nint main() {\n FLAC::Metadata::VorbisComment vc;\n const ::FLAC__StreamMetadata* fsmd = vc;\n return 0;\n}\n" FLAC_STREAMMETADATA_OPERATOR_FOUND) + CHECK_CXX_SOURCE_COMPILES("#include \nint main() {\n FLAC::Metadata::Picture pic;\n return 0;\n}\n" FLAC_METADATA_PICTURE_FOUND) + set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_TMP}) + + if(NOT FLAC_STREAMMETADATA_OPERATOR_FOUND) + set(HAVE_NO_FLAC_STREAMMETADATA_OPERATOR 1) + endif(NOT FLAC_STREAMMETADATA_OPERATOR_FOUND) + if(FLAC_METADATA_PICTURE_FOUND) + set(HAVE_FLAC_PICTURE 1) + endif(FLAC_METADATA_PICTURE_FOUND) + else(FLACPP_INCLUDE_DIR AND FLAC_LIBRARY AND FLACPP_LIBRARY) + message(FATAL_ERROR "Could not find FLAC++") + endif(FLACPP_INCLUDE_DIR AND FLAC_LIBRARY AND FLACPP_LIBRARY) +endif(WITH_FLAC) + include_directories(${JPEG_INCLUDE_DIR}) if(EXIV2_FOUND) include_directories(${EXIV2_INCLUDE_DIR}) @@ -219,6 +276,18 @@ install(TARGETS comicbookthumbnail DESTINATION ${PLUGIN_INSTALL_DIR}) ########### install files ############### +########### next target ############### + +set(audiothumbnail_SRCS audiocreator.cpp) + +add_library(audiothumbnail MODULE ${audiothumbnail_SRCS}) + +target_link_libraries(audiothumbnail KF5::KIOWidgets ${TAGLIB_LIBRARIES} ${FLAC_LIBRARIES}) + +install(TARGETS audiothumbnail DESTINATION ${PLUGIN_INSTALL_DIR}) + +########### install files ############### + install(FILES thumbcreator.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR}) install(FILES thumbnail.protocol @@ -226,6 +295,7 @@ install(FILES imagethumbnail.desktop jpegthumbnail.desktop textthumbnail.desktop + audiothumbnail.desktop # htmlthumbnail.desktop # desktopthumbnail.desktop comicbookthumbnail.desktop diff --git a/thumbnail/audiocreator.cpp b/thumbnail/audiocreator.cpp new file mode 100644 index 0000000..4bc69d6 --- /dev/null +++ b/thumbnail/audiocreator.cpp @@ -0,0 +1,181 @@ + +/*************************************************************************** + * This file is part of the AudioThumbs. * + * Copyright (C) 2009 Vytautas Mickus * + * Copyright (C) 2011 Raizner Evgeniy * + * * + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "audiocreator.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +extern "C" +{ + Q_DECL_EXPORT ThumbCreator *new_creator() + { + return new ATCreator; + } +} + + +ATCreator::ATCreator() +{ + +} + +ATCreator::~ATCreator() +{ + +} + +bool ATCreator::create ( const QString &path, int /*w*/, int /*h*/, QImage &img ) +{ + bool bRet = false; + + QMimeDatabase db; + QMimeType type = db.mimeTypeForFile(path, QMimeDatabase::MatchExtension); + + if (type.name() == "audio/mpeg") { + TagLib::MPEG::File mp3File(path.toUtf8()); + TagLib::ID3v2::Tag *mp3Tag = mp3File.ID3v2Tag(); + TagLib::ID3v2::FrameList fList = mp3Tag->frameList("APIC"); + TagLib::ID3v2::AttachedPictureFrame *pic; + pic = static_cast(fList.front()); + if (!pic->picture().isEmpty()) { + img.loadFromData((const uchar *) pic->picture().data(),pic->picture().size()); + bRet = true; + } + + } else if (type.name() == "audio/flac" || type.name() == "audio/x-flac") { + TagLib::FLAC::File ff(path.toUtf8()); + TagLib::List coverList; + + if (!ff.pictureList().isEmpty()) { + coverList.append(ff.pictureList().front()); + TagLib::ByteVector coverData = coverList.front()->data(); + QByteArray data; + data.setRawData(coverData.data(),coverData.size()); + img.loadFromData(data); + bRet = true; + return bRet; + } + + } else if (type.name() == "audio/mp4") { + TagLib::MP4::File mp4file(path.toUtf8()); + TagLib::MP4::Tag *tag = mp4file.tag(); + TagLib::MP4::ItemListMap map=tag->itemListMap(); + QByteArray data; + + if (!map.isEmpty()) { + for (TagLib::MP4::ItemListMap::ConstIterator it = map.begin(); it != map.end(); ++it) { + TagLib::MP4::CoverArtList coverList=(*it).second.toCoverArtList(); + if (!coverList.isEmpty()) { + TagLib::MP4::CoverArt cover=coverList[0]; + + TagLib::ByteVector coverData=cover.data(); + data.setRawData(coverData.data(),coverData.size()); + img.loadFromData(data); + + bRet = true; + return bRet; + } + } + } + } else if (type.name() == "audio/x-vorbis+ogg" || type.name() == "audio/ogg") { + // this part from Coquillo audio tag editor + TagLib::Ogg::Vorbis::File file(path.toUtf8()); + TagLib::Ogg::XiphComment *tag = file.tag(); + + if (tag->contains("METADATA_BLOCK_PICTURE")) { + TagLib::StringList blocks = tag->fieldListMap()["METADATA_BLOCK_PICTURE"]; + + for (uint i = 0; i < blocks.size(); i++) { + QByteArray data = QByteArray::fromBase64(blocks[i].toCString()); + QDataStream s(&data, QIODevice::ReadOnly); + + int type; + uint mimelen; + int descrlen; + int datalen; + + int w; + int h; + int c; + int ic; + + char * mime; + char * descr; + char * pic; + + s >> type; + s >> mimelen; + + mime = new char[mimelen+1]; + s.readRawData(mime, mimelen); + + mime[mimelen] = 0; + + s >> descrlen; + + descr = new char[descrlen+1]; + s.readRawData(descr, descrlen); + + descr[descrlen] = 0; + + s >> w >> h >> c >> ic >> datalen; + + if (!datalen) + return false; + + pic = new char[datalen]; + s.readRawData(pic, datalen); + img = QImage::fromData(QByteArray(pic, datalen)); + + bRet = true; + } + } + } + + return bRet; +} + +ThumbCreator::Flags ATCreator::flags() const +{ + return (Flags)(None); +} + diff --git a/thumbnail/audiocreator.h b/thumbnail/audiocreator.h new file mode 100644 index 0000000..f7badbd --- /dev/null +++ b/thumbnail/audiocreator.h @@ -0,0 +1,39 @@ + +/*************************************************************************** + * This file is part of the AudioThumbs. * + * Copyright (C) 2009 Vytautas Mickus * + * Copyright (C) 2011 Raizner Evgeniy * + * * + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef _AUDIO_THUMBS_H_ +#define _AUDIO_THUMBS_H_ + +#include +#include + +class ATCreator : public QObject, public ThumbCreator +{ + Q_OBJECT +public: + ATCreator(); + virtual ~ATCreator(); + virtual bool create(const QString &path, int w, int h, QImage &img); + virtual Flags flags() const; +private: +}; + +#endif // _AUDIO_THUMBS_H_ diff --git a/thumbnail/audiothumbnail.desktop b/thumbnail/audiothumbnail.desktop new file mode 100644 index 0000000..ddbb582 --- /dev/null +++ b/thumbnail/audiothumbnail.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Service +Name=Audio Files +Name[lt]=Audio failai +Name[ru]=Аудио файлы +Name[ua]=Аудiо файли +X-KDE-ServiceTypes=ThumbCreator +MimeType=audio/mpeg;audio/flac;audio/x-flac;audio/mp4;audio/x-vorbis+ogg;audio/ogg; +X-KDE-Library=audiothumbnail +CacheThumbnail=true +IgnoreMaximumSize=true -- 2.1.0