From 71a2cd632177a7e21d79cdd1a6157eca9e5a1460 Mon Sep 17 00:00:00 2001 From: Kevin Whitaker Date: Wed, 8 Feb 2017 00:56:32 -0500 Subject: [PATCH] Add taglib to project to get extra cover data(and possibly replace libgroove for this function). Remove oggs from accepted files until I can figure out cover data for them better. Add non-persisted field for this to audiotrack object and method to add this data to it in memory. --- CMakeLists.txt | 3 ++- cmake/FindTagLib.cmake | 8 ++++++++ src/GroovePlayer.cpp | 43 +++++++++++++++++++++++++++++++++++++++++- src/GroovePlayer.h | 1 + src/db/AudioTrack.h | 5 +++++ 5 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 cmake/FindTagLib.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fada86a..d170192 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,9 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") find_package(Wt REQUIRED) find_package(Groove REQUIRED) +find_package(TagLib REQUIRED) add_executable(arbitrateor src/main.cpp src/WebInterface.cpp src/GroovePlayer.cpp src/ui/LoginInterface.cpp src/ui/PlayerInterface.cpp) -target_link_libraries(arbitrateor ${Wt_LIBRARIES} ${GROOVE_LIBRARY} ${GROOVE_FINGERPRINT_LIBRARY} ${GROOVE_PLAYER_LIBRARY} pthread stdc++fs) #TODO get threading links based on platform. Remove gcc experimental fs when official c++17 exists. +target_link_libraries(arbitrateor ${Wt_LIBRARIES} ${GROOVE_LIBRARY} ${GROOVE_FINGERPRINT_LIBRARY} ${GROOVE_PLAYER_LIBRARY} ${TAGLIB_LIBRARY} pthread stdc++fs) #TODO get threading links based on platform. Remove gcc experimental fs when official c++17 exists. install(TARGETS arbitrateor RUNTIME DESTINATION bin) diff --git a/cmake/FindTagLib.cmake b/cmake/FindTagLib.cmake new file mode 100644 index 0000000..d0fa28b --- /dev/null +++ b/cmake/FindTagLib.cmake @@ -0,0 +1,8 @@ +find_path(TAGLIB_INCLUDE_DIR NAMES taglib/id3v2tag.h) + +find_library(TAGLIB_LIBRARY NAMES tag) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(TAGLIB DEFAULT_MSG TAGLIB_LIBRARY TAGLIB_INCLUDE_DIR) + +mark_as_advanced(TAGLIB_INCLUDE_DIR TAGLIB_LIBRARY) diff --git a/src/GroovePlayer.cpp b/src/GroovePlayer.cpp index 7b548ad..bddb0b1 100644 --- a/src/GroovePlayer.cpp +++ b/src/GroovePlayer.cpp @@ -28,6 +28,10 @@ #include #include #include +#include +#include +#include +#include GroovePlayerMgr::GroovePlayerMgr (std::string dbFile) { @@ -412,6 +416,7 @@ bool GroovePlayerMgr::addFileToTrackDBIfTagged(Wt::Dbo::Session* session, std::f if(artist_tag == nullptr || album_tag == nullptr || name_tag == nullptr || genre_tag == nullptr) { //Only accept song with all metadata for DB. + Wt::log("info") << "Audio track " << file << " did not have all required tags."; groove_file_close(gfile); return false; } @@ -451,6 +456,16 @@ bool GroovePlayerMgr::addFileToTrackDBIfTagged(Wt::Dbo::Session* session, std::f newTrack->trackLengthSeconds = trackLen; newTrack->trackFingerprint = fingerprint; newTrack->trackPath = file.string(); + + //Quickly see if there is cover artist + getPictureFromTrack(newTrack); + if(newTrack->coverArt.size() == 0) + { + Wt::log("info") << "Audio track " << newTrack->trackPath << " did not have cover art in the file."; + groove_file_close(gfile); + return false; + } + session->add(newTrack); transaction.commit(); groove_file_close(gfile); @@ -473,6 +488,32 @@ void GroovePlayerMgr::removeOrphanedTracks(Wt::Dbo::Session* session) transaction.commit(); } +void GroovePlayerMgr::getPictureFromTrack(AudioTrack* trackToFill) +{ + if(trackToFill->trackPath != "") + { + TagLib::String file = TagLib::String(trackToFill->trackPath); + if(file.substr(file.size()-3).upper() == "MP3" && TagLib::MPEG::File(trackToFill->trackPath.c_str()).hasID3v2Tag()) + { + TagLib::MPEG::File file(trackToFill->trackPath.c_str()); + TagLib::ID3v2::Tag* tag = file.ID3v2Tag(); + if(!tag->frameListMap()["APIC"].isEmpty() && dynamic_cast(tag->frameListMap()["APIC"].front()) != nullptr) + { + TagLib::ID3v2::AttachedPictureFrame* pic = dynamic_cast(tag->frameListMap()["APIC"].front()); + trackToFill->coverArt = TagLib::ByteVector(pic->picture().data(),pic->picture().size()); + trackToFill->coverMimeType = std::string(pic->mimeType().toCString(true)); + } + } +// else if(dynamic_cast(tagTrack.tag()) != nullptr && !dynamic_cast(tagTrack.tag())->isEmpty()) +// { +// TagLib::Ogg::XiphComment* tag = dynamic_cast(tagTrack.tag()); +// if(tag->fieldListMap()["METADATA_BLOCK_PICTURE"].isEmpty()) +// { +// tag->fieldListMap()["METADATA_BLOCK_PICTURE"];//TODO? +// } +// } + } +} void GroovePlayerMgr::grooveAudioScannerLoop() @@ -497,7 +538,7 @@ void GroovePlayerMgr::grooveAudioScannerLoop() { extensionLowered.push_back(std::tolower(elem)); } - if(extensionLowered == ".mp3" || extensionLowered == ".ogg") //TODO:think about supporting more than mp3s and oggs. + if(extensionLowered == ".mp3") //TODO:think about supporting more than mp3s. { if(addFileToTrackDBIfTagged(&sqlSession, p.path())) { diff --git a/src/GroovePlayer.h b/src/GroovePlayer.h index ce05c21..f9eaef9 100644 --- a/src/GroovePlayer.h +++ b/src/GroovePlayer.h @@ -72,6 +72,7 @@ private: void removeOrphanedTracks(Wt::Dbo::Session* session); AudioTrack getCurrentTrack(Wt::Dbo::Session* session); + void getPictureFromTrack(AudioTrack* trackToFill); }; diff --git a/src/db/AudioTrack.h b/src/db/AudioTrack.h index 4a10aad..1e7384d 100644 --- a/src/db/AudioTrack.h +++ b/src/db/AudioTrack.h @@ -21,6 +21,7 @@ #define AUDIOTRACK_H #include +#include class AudioTrack { @@ -33,6 +34,10 @@ public: std::string trackFingerprint; std::string trackPath; + //Non-persisted data + TagLib::ByteVector coverArt; + std::string coverMimeType; + template void persist(Action& a) { -- GitLab