diff --git a/cover/CoverArt.hpp b/cover/CoverArt.hpp index 66afa4bb..e7de5303 100644 --- a/cover/CoverArt.hpp +++ b/cover/CoverArt.hpp @@ -4,7 +4,6 @@ #include #include -#include "database/AudioTypes.hpp" namespace CoverArt { diff --git a/cover/CoverArtGrabber.cpp b/cover/CoverArtGrabber.cpp index 3d59993b..cb664601 100644 --- a/cover/CoverArtGrabber.cpp +++ b/cover/CoverArtGrabber.cpp @@ -8,6 +8,32 @@ namespace CoverArt { + +std::vector +Grabber::getFromInputFormatContext(const Av::InputFormatContext& input) +{ + std::vector res; + + try + { + std::vector< std::vector > pictures; + input.getPictures(pictures); + + BOOST_FOREACH(const std::vector& picture, pictures) + res.push_back( CoverArt("application/octet-stream", picture) ); + + } + catch(std::exception& e) + { + std::cerr << "Cannot get pictures: " << e.what() << std::endl; + } + + return res; +} + + + + std::vector Grabber::getFromTrack(Track::pointer track) { @@ -17,12 +43,7 @@ Grabber::getFromTrack(Track::pointer track) { Av::InputFormatContext input(track->getPath()); - std::vector< std::vector > pictures; - input.getPictures(pictures); - - BOOST_FOREACH(const std::vector& picture, pictures) - res.push_back( CoverArt("application/octet-stream", picture) ); - + return getFromInputFormatContext(input); } catch(std::exception& e) { diff --git a/cover/CoverArtGrabber.hpp b/cover/CoverArtGrabber.hpp index 8e62fe09..d506f03d 100644 --- a/cover/CoverArtGrabber.hpp +++ b/cover/CoverArtGrabber.hpp @@ -1,6 +1,11 @@ #ifndef COVER_ART_GRABBER_HPP #define COVER_ART_GRABBER_HPP +#include + +#include "av/InputFormatContext.hpp" +#include "database/AudioTypes.hpp" + #include "CoverArt.hpp" @@ -10,6 +15,7 @@ class Grabber { public: + static std::vector getFromInputFormatContext(const Av::InputFormatContext& input); static std::vector getFromTrack(Track::pointer track); static std::vector getFromRelease(Release::pointer release); }; diff --git a/remote/messages/collection.pb.cc b/remote/messages/collection.pb.cc index 32cc73ce..8eb402fe 100644 --- a/remote/messages/collection.pb.cc +++ b/remote/messages/collection.pb.cc @@ -525,7 +525,7 @@ void protobuf_AddDesc_collection_2eproto() { "nre_id\030\004 \003(\004\032\276\001\n\013GetCoverArt\022=\n\004type\030\001 \002" "(\0162/.Remote.AudioCollectionRequest.GetCo" "verArt.Type\022\022\n\nrelease_id\030\002 \001(\004\022\020\n\010track" - "_id\030\003 \001(\004\022\014\n\004size\030\004 \001(\r\"<\n\004Type\022\032\n\026TypeG" + "_id\030\003 \001(\004\022\014\n\004size\030\004 \002(\r\"<\n\004Type\022\032\n\026TypeG" "etCoverArtRelease\020\001\022\030\n\024TypeGetCoverArtTr" "ack\020\002\"\213\001\n\004Type\022\023\n\017TypeGetRevision\020\001\022\024\n\020T" "ypeGetGenreList\020\002\022\025\n\021TypeGetArtistList\020\003" @@ -2200,7 +2200,7 @@ bool AudioCollectionRequest_GetCoverArt::MergePartialFromCodedStream( break; } - // optional uint32 size = 4; + // required uint32 size = 4; case 4: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { @@ -2250,7 +2250,7 @@ void AudioCollectionRequest_GetCoverArt::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->track_id(), output); } - // optional uint32 size = 4; + // required uint32 size = 4; if (has_size()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->size(), output); } @@ -2279,7 +2279,7 @@ void AudioCollectionRequest_GetCoverArt::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->track_id(), target); } - // optional uint32 size = 4; + // required uint32 size = 4; if (has_size()) { target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->size(), target); } @@ -2315,7 +2315,7 @@ int AudioCollectionRequest_GetCoverArt::ByteSize() const { this->track_id()); } - // optional uint32 size = 4; + // required uint32 size = 4; if (has_size()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( @@ -2378,7 +2378,7 @@ void AudioCollectionRequest_GetCoverArt::CopyFrom(const AudioCollectionRequest_G } bool AudioCollectionRequest_GetCoverArt::IsInitialized() const { - if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; + if ((_has_bits_[0] & 0x00000009) != 0x00000009) return false; return true; } diff --git a/remote/messages/collection.pb.h b/remote/messages/collection.pb.h index 4088e074..85cf0f0d 100644 --- a/remote/messages/collection.pb.h +++ b/remote/messages/collection.pb.h @@ -727,7 +727,7 @@ class AudioCollectionRequest_GetCoverArt : public ::google::protobuf::Message { inline ::google::protobuf::uint64 track_id() const; inline void set_track_id(::google::protobuf::uint64 value); - // optional uint32 size = 4; + // required uint32 size = 4; inline bool has_size() const; inline void clear_size(); static const int kSizeFieldNumber = 4; @@ -2636,7 +2636,7 @@ inline void AudioCollectionRequest_GetCoverArt::set_track_id(::google::protobuf: track_id_ = value; } -// optional uint32 size = 4; +// required uint32 size = 4; inline bool AudioCollectionRequest_GetCoverArt::has_size() const { return (_has_bits_[0] & 0x00000008u) != 0; } diff --git a/remote/proto/collection.proto b/remote/proto/collection.proto index c2dcb3f7..ec45a0d2 100644 --- a/remote/proto/collection.proto +++ b/remote/proto/collection.proto @@ -53,7 +53,7 @@ message AudioCollectionRequest optional uint64 release_id = 2; // Release that owns the cover art optional uint64 track_id = 3; // Track that owns the cover art - optional uint32 size = 4; // Scale image to this size + required uint32 size = 4; // Scale image to size*size pixels. Set 0 to get the biggest image } enum Type diff --git a/test/RemoteClientServer.cpp b/test/RemoteClientServer.cpp index 8de92039..2828e76a 100644 --- a/test/RemoteClientServer.cpp +++ b/test/RemoteClientServer.cpp @@ -75,7 +75,7 @@ std::ostream& operator<<(std::ostream& os, const TrackInfo& info) return os; } -struct CoverArt +struct Cover { std::string mimeType; std::vector data; @@ -364,7 +364,7 @@ class TestClient mediaTerminate(); } - void getCoverTrack(std::vector& coverArt, uint64_t trackId) + void getCoverTrack(std::vector& coverArt, uint64_t trackId) { // Send request Remote::ClientMessage request; @@ -374,7 +374,7 @@ class TestClient request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest::TypeGetCoverArt); request.mutable_audio_collection_request()->mutable_get_cover_art()->set_type( Remote::AudioCollectionRequest::GetCoverArt::TypeGetCoverArtTrack); request.mutable_audio_collection_request()->mutable_get_cover_art()->set_track_id( trackId ); - request.mutable_audio_collection_request()->mutable_get_cover_art()->set_size( 100 ); + request.mutable_audio_collection_request()->mutable_get_cover_art()->set_size( 256 ); sendMsg(request); // Receive responses @@ -387,7 +387,7 @@ class TestClient for (int i = 0; i < response.audio_collection_response().cover_art_size(); ++i) { - CoverArt cover; + Cover cover; cover.mimeType = response.audio_collection_response().cover_art(i).mime_type(); cover.data.assign(response.audio_collection_response().cover_art(i).data().begin(), response.audio_collection_response().cover_art(i).data().end());; @@ -395,7 +395,7 @@ class TestClient } } - void getCoverRelease(std::vector& coverArt, uint64_t releaseId) + void getCoverRelease(std::vector& coverArt, uint64_t releaseId) { // Send request Remote::ClientMessage request; @@ -405,7 +405,7 @@ class TestClient request.mutable_audio_collection_request()->set_type( Remote::AudioCollectionRequest::TypeGetCoverArt); request.mutable_audio_collection_request()->mutable_get_cover_art()->set_type( Remote::AudioCollectionRequest::GetCoverArt::TypeGetCoverArtRelease); request.mutable_audio_collection_request()->mutable_get_cover_art()->set_release_id( releaseId ); - request.mutable_audio_collection_request()->mutable_get_cover_art()->set_size( 100 ); + request.mutable_audio_collection_request()->mutable_get_cover_art()->set_size( 256 ); sendMsg(request); @@ -419,7 +419,7 @@ class TestClient for (int i = 0; i < response.audio_collection_response().cover_art_size(); ++i) { - CoverArt cover; + Cover cover; cover.mimeType = response.audio_collection_response().cover_art(i).mime_type(); cover.data.assign(response.audio_collection_response().cover_art(i).data().begin(), response.audio_collection_response().cover_art(i).data().end());; @@ -718,12 +718,13 @@ int main() { BOOST_FOREACH(const ReleaseInfo& release, releases) { - std::vector coverArts; + std::vector coverArts; client.getCoverRelease(coverArts, release.id); - BOOST_FOREACH(const CoverArt coverArt, coverArts) + boost::filesystem::create_directory("cover"); + BOOST_FOREACH(const Cover coverArt, coverArts) { - std::ostringstream oss; oss << release.name << ".jpeg"; + std::ostringstream oss; oss << "cover/" << release.id << "." << release.name << ".jpeg"; std::ofstream out(oss.str().c_str()); BOOST_FOREACH(unsigned char c, coverArt.data) out.put(c); @@ -734,7 +735,7 @@ int main() BOOST_FOREACH(const TrackInfo& track, tracks) { - std::vector coverArt; + std::vector coverArt; client.getCoverTrack(coverArt, track.id); std::cout << "Track '" << track << "', spotted " << coverArt.size() << " covers!" << std::endl; diff --git a/transcode/InputMediaFile.cpp b/transcode/InputMediaFile.cpp index 6e65d58a..4de5f030 100644 --- a/transcode/InputMediaFile.cpp +++ b/transcode/InputMediaFile.cpp @@ -6,6 +6,7 @@ #include "InputMediaFile.hpp" #include "av/InputFormatContext.hpp" +#include "cover/CoverArtGrabber.hpp" namespace Transcode { @@ -77,7 +78,7 @@ InputMediaFile::InputMediaFile(const boost::filesystem::path& p) std::cerr << "Cannot find best stream for type " << type << std::endl; } - input.getPictures( _coverPictures ); + _covers = CoverArt::Grabber::getFromInputFormatContext(input); } std::vector diff --git a/transcode/InputMediaFile.hpp b/transcode/InputMediaFile.hpp index 874235d8..1bca1316 100644 --- a/transcode/InputMediaFile.hpp +++ b/transcode/InputMediaFile.hpp @@ -7,6 +7,8 @@ #include #include +#include "cover/CoverArt.hpp" + #include "Stream.hpp" @@ -33,7 +35,7 @@ class InputMediaFile boost::posix_time::time_duration getDuration(void) const {return _duration;} // Pictures - const std::vector< std::vector >& getCoverPictures(void) const { return _coverPictures; } + const std::vector< CoverArt::CoverArt >& getCovers(void) const { return _covers; } // Stream handling std::vector getStreams(Stream::Type type) const; @@ -47,7 +49,7 @@ class InputMediaFile std::vector _streams; std::map _bestStreams; - std::vector< std::vector > _coverPictures; + std::vector< CoverArt::CoverArt > _covers; }; diff --git a/ui/audio/AudioWidget.cpp b/ui/audio/AudioWidget.cpp index e50e18e5..e717b91b 100644 --- a/ui/audio/AudioWidget.cpp +++ b/ui/audio/AudioWidget.cpp @@ -2,8 +2,6 @@ #include "AudioWidget.hpp" -#include "metadata/Extractor.hpp" - namespace UserInterface { AudioWidget::AudioWidget(SessionData& sessionData, Wt::WContainerWidget* parent) @@ -51,13 +49,16 @@ AudioWidget::playTrack(boost::filesystem::path p) // Refresh cover { - const std::vector< std::vector >& pictures = inputFile.getCoverPictures(); + std::vector covers = inputFile.getCovers(); - if (!pictures.empty()) + if (!covers.empty()) { std::cout << "Cover found!" << std::endl; -// _imgResource->setMimeType(cover.mimeType); - _imgResource->setData(pictures.front()); + if (!covers.front().scale(256)) + std::cerr << "Cannot resize!" << std::endl; + + //_imgResource->setMimeType(covers.front().getMimeType()); + _imgResource->setData(covers.front().getData()); } else { std::cout << "No cover found!" << std::endl;