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.

This commit is contained in:
Kevin Whitaker
2017-02-08 00:56:32 -05:00
parent 44df1cf607
commit 71a2cd6321
5 changed files with 58 additions and 2 deletions

View File

@@ -7,8 +7,9 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
find_package(Wt REQUIRED) find_package(Wt REQUIRED)
find_package(Groove 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) 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) install(TARGETS arbitrateor RUNTIME DESTINATION bin)

8
cmake/FindTagLib.cmake Normal file
View File

@@ -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)

View File

@@ -28,6 +28,10 @@
#include <Wt/Dbo/Transaction> #include <Wt/Dbo/Transaction>
#include <groovefingerprinter/fingerprinter.h> #include <groovefingerprinter/fingerprinter.h>
#include <grooveplayer/player.h> #include <grooveplayer/player.h>
#include <taglib/fileref.h>
#include <taglib/mpegfile.h>
#include <taglib/id3v2tag.h>
#include <taglib/attachedpictureframe.h>
GroovePlayerMgr::GroovePlayerMgr (std::string dbFile) 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) if(artist_tag == nullptr || album_tag == nullptr || name_tag == nullptr || genre_tag == nullptr)
{ {
//Only accept song with all metadata for DB. //Only accept song with all metadata for DB.
Wt::log("info") << "Audio track " << file << " did not have all required tags.";
groove_file_close(gfile); groove_file_close(gfile);
return false; return false;
} }
@@ -451,6 +456,16 @@ bool GroovePlayerMgr::addFileToTrackDBIfTagged(Wt::Dbo::Session* session, std::f
newTrack->trackLengthSeconds = trackLen; newTrack->trackLengthSeconds = trackLen;
newTrack->trackFingerprint = fingerprint; newTrack->trackFingerprint = fingerprint;
newTrack->trackPath = file.string(); 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); session->add(newTrack);
transaction.commit(); transaction.commit();
groove_file_close(gfile); groove_file_close(gfile);
@@ -473,6 +488,32 @@ void GroovePlayerMgr::removeOrphanedTracks(Wt::Dbo::Session* session)
transaction.commit(); 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<TagLib::ID3v2::AttachedPictureFrame*>(tag->frameListMap()["APIC"].front()) != nullptr)
{
TagLib::ID3v2::AttachedPictureFrame* pic = dynamic_cast<TagLib::ID3v2::AttachedPictureFrame*>(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<TagLib::Ogg::XiphComment*>(tagTrack.tag()) != nullptr && !dynamic_cast<TagLib::Ogg::XiphComment*>(tagTrack.tag())->isEmpty())
// {
// TagLib::Ogg::XiphComment* tag = dynamic_cast<TagLib::Ogg::XiphComment*>(tagTrack.tag());
// if(tag->fieldListMap()["METADATA_BLOCK_PICTURE"].isEmpty())
// {
// tag->fieldListMap()["METADATA_BLOCK_PICTURE"];//TODO?
// }
// }
}
}
void GroovePlayerMgr::grooveAudioScannerLoop() void GroovePlayerMgr::grooveAudioScannerLoop()
@@ -497,7 +538,7 @@ void GroovePlayerMgr::grooveAudioScannerLoop()
{ {
extensionLowered.push_back(std::tolower(elem)); 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())) if(addFileToTrackDBIfTagged(&sqlSession, p.path()))
{ {

View File

@@ -72,6 +72,7 @@ private:
void removeOrphanedTracks(Wt::Dbo::Session* session); void removeOrphanedTracks(Wt::Dbo::Session* session);
AudioTrack getCurrentTrack(Wt::Dbo::Session* session); AudioTrack getCurrentTrack(Wt::Dbo::Session* session);
void getPictureFromTrack(AudioTrack* trackToFill);
}; };

View File

@@ -21,6 +21,7 @@
#define AUDIOTRACK_H #define AUDIOTRACK_H
#include <Wt/Dbo/Dbo> #include <Wt/Dbo/Dbo>
#include <taglib/tbytevector.h>
class AudioTrack class AudioTrack
{ {
@@ -33,6 +34,10 @@ public:
std::string trackFingerprint; std::string trackFingerprint;
std::string trackPath; std::string trackPath;
//Non-persisted data
TagLib::ByteVector coverArt;
std::string coverMimeType;
template<class Action> template<class Action>
void persist(Action& a) void persist(Action& a)
{ {