WIP. Scale cover art option now mandatory!

This commit is contained in:
emeric
2014-06-15 23:40:04 +02:00
parent 9bada5ee2a
commit b739f4ef56
10 changed files with 67 additions and 36 deletions
-1
View File
@@ -4,7 +4,6 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include "database/AudioTypes.hpp"
namespace CoverArt namespace CoverArt
{ {
+27 -6
View File
@@ -8,6 +8,32 @@
namespace CoverArt { namespace CoverArt {
std::vector<CoverArt>
Grabber::getFromInputFormatContext(const Av::InputFormatContext& input)
{
std::vector<CoverArt> res;
try
{
std::vector< std::vector<unsigned char> > pictures;
input.getPictures(pictures);
BOOST_FOREACH(const std::vector<unsigned char>& 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<CoverArt> std::vector<CoverArt>
Grabber::getFromTrack(Track::pointer track) Grabber::getFromTrack(Track::pointer track)
{ {
@@ -17,12 +43,7 @@ Grabber::getFromTrack(Track::pointer track)
{ {
Av::InputFormatContext input(track->getPath()); Av::InputFormatContext input(track->getPath());
std::vector< std::vector<unsigned char> > pictures; return getFromInputFormatContext(input);
input.getPictures(pictures);
BOOST_FOREACH(const std::vector<unsigned char>& picture, pictures)
res.push_back( CoverArt("application/octet-stream", picture) );
} }
catch(std::exception& e) catch(std::exception& e)
{ {
+6
View File
@@ -1,6 +1,11 @@
#ifndef COVER_ART_GRABBER_HPP #ifndef COVER_ART_GRABBER_HPP
#define COVER_ART_GRABBER_HPP #define COVER_ART_GRABBER_HPP
#include <vector>
#include "av/InputFormatContext.hpp"
#include "database/AudioTypes.hpp"
#include "CoverArt.hpp" #include "CoverArt.hpp"
@@ -10,6 +15,7 @@ class Grabber
{ {
public: public:
static std::vector<CoverArt> getFromInputFormatContext(const Av::InputFormatContext& input);
static std::vector<CoverArt> getFromTrack(Track::pointer track); static std::vector<CoverArt> getFromTrack(Track::pointer track);
static std::vector<CoverArt> getFromRelease(Release::pointer release); static std::vector<CoverArt> getFromRelease(Release::pointer release);
}; };
+6 -6
View File
@@ -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" "nre_id\030\004 \003(\004\032\276\001\n\013GetCoverArt\022=\n\004type\030\001 \002"
"(\0162/.Remote.AudioCollectionRequest.GetCo" "(\0162/.Remote.AudioCollectionRequest.GetCo"
"verArt.Type\022\022\n\nrelease_id\030\002 \001(\004\022\020\n\010track" "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" "etCoverArtRelease\020\001\022\030\n\024TypeGetCoverArtTr"
"ack\020\002\"\213\001\n\004Type\022\023\n\017TypeGetRevision\020\001\022\024\n\020T" "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" "ypeGetGenreList\020\002\022\025\n\021TypeGetArtistList\020\003"
@@ -2200,7 +2200,7 @@ bool AudioCollectionRequest_GetCoverArt::MergePartialFromCodedStream(
break; break;
} }
// optional uint32 size = 4; // required uint32 size = 4;
case 4: { case 4: {
if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
@@ -2250,7 +2250,7 @@ void AudioCollectionRequest_GetCoverArt::SerializeWithCachedSizes(
::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->track_id(), output); ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->track_id(), output);
} }
// optional uint32 size = 4; // required uint32 size = 4;
if (has_size()) { if (has_size()) {
::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->size(), output); ::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); target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->track_id(), target);
} }
// optional uint32 size = 4; // required uint32 size = 4;
if (has_size()) { if (has_size()) {
target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->size(), target); target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->size(), target);
} }
@@ -2315,7 +2315,7 @@ int AudioCollectionRequest_GetCoverArt::ByteSize() const {
this->track_id()); this->track_id());
} }
// optional uint32 size = 4; // required uint32 size = 4;
if (has_size()) { if (has_size()) {
total_size += 1 + total_size += 1 +
::google::protobuf::internal::WireFormatLite::UInt32Size( ::google::protobuf::internal::WireFormatLite::UInt32Size(
@@ -2378,7 +2378,7 @@ void AudioCollectionRequest_GetCoverArt::CopyFrom(const AudioCollectionRequest_G
} }
bool AudioCollectionRequest_GetCoverArt::IsInitialized() const { bool AudioCollectionRequest_GetCoverArt::IsInitialized() const {
if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; if ((_has_bits_[0] & 0x00000009) != 0x00000009) return false;
return true; return true;
} }
+2 -2
View File
@@ -727,7 +727,7 @@ class AudioCollectionRequest_GetCoverArt : public ::google::protobuf::Message {
inline ::google::protobuf::uint64 track_id() const; inline ::google::protobuf::uint64 track_id() const;
inline void set_track_id(::google::protobuf::uint64 value); inline void set_track_id(::google::protobuf::uint64 value);
// optional uint32 size = 4; // required uint32 size = 4;
inline bool has_size() const; inline bool has_size() const;
inline void clear_size(); inline void clear_size();
static const int kSizeFieldNumber = 4; static const int kSizeFieldNumber = 4;
@@ -2636,7 +2636,7 @@ inline void AudioCollectionRequest_GetCoverArt::set_track_id(::google::protobuf:
track_id_ = value; track_id_ = value;
} }
// optional uint32 size = 4; // required uint32 size = 4;
inline bool AudioCollectionRequest_GetCoverArt::has_size() const { inline bool AudioCollectionRequest_GetCoverArt::has_size() const {
return (_has_bits_[0] & 0x00000008u) != 0; return (_has_bits_[0] & 0x00000008u) != 0;
} }
+1 -1
View File
@@ -53,7 +53,7 @@ message AudioCollectionRequest
optional uint64 release_id = 2; // Release that owns the cover art optional uint64 release_id = 2; // Release that owns the cover art
optional uint64 track_id = 3; // Track 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 enum Type
+12 -11
View File
@@ -75,7 +75,7 @@ std::ostream& operator<<(std::ostream& os, const TrackInfo& info)
return os; return os;
} }
struct CoverArt struct Cover
{ {
std::string mimeType; std::string mimeType;
std::vector<unsigned char> data; std::vector<unsigned char> data;
@@ -364,7 +364,7 @@ class TestClient
mediaTerminate(); mediaTerminate();
} }
void getCoverTrack(std::vector<CoverArt>& coverArt, uint64_t trackId) void getCoverTrack(std::vector<Cover>& coverArt, uint64_t trackId)
{ {
// Send request // Send request
Remote::ClientMessage 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()->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_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_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); sendMsg(request);
// Receive responses // Receive responses
@@ -387,7 +387,7 @@ class TestClient
for (int i = 0; i < response.audio_collection_response().cover_art_size(); ++i) 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.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());; 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>& coverArt, uint64_t releaseId) void getCoverRelease(std::vector<Cover>& coverArt, uint64_t releaseId)
{ {
// Send request // Send request
Remote::ClientMessage 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()->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_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_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); sendMsg(request);
@@ -419,7 +419,7 @@ class TestClient
for (int i = 0; i < response.audio_collection_response().cover_art_size(); ++i) 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.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());; 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) BOOST_FOREACH(const ReleaseInfo& release, releases)
{ {
std::vector<CoverArt> coverArts; std::vector<Cover> coverArts;
client.getCoverRelease(coverArts, release.id); 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()); std::ofstream out(oss.str().c_str());
BOOST_FOREACH(unsigned char c, coverArt.data) BOOST_FOREACH(unsigned char c, coverArt.data)
out.put(c); out.put(c);
@@ -734,7 +735,7 @@ int main()
BOOST_FOREACH(const TrackInfo& track, tracks) BOOST_FOREACH(const TrackInfo& track, tracks)
{ {
std::vector<CoverArt> coverArt; std::vector<Cover> coverArt;
client.getCoverTrack(coverArt, track.id); client.getCoverTrack(coverArt, track.id);
std::cout << "Track '" << track << "', spotted " << coverArt.size() << " covers!" << std::endl; std::cout << "Track '" << track << "', spotted " << coverArt.size() << " covers!" << std::endl;
+2 -1
View File
@@ -6,6 +6,7 @@
#include "InputMediaFile.hpp" #include "InputMediaFile.hpp"
#include "av/InputFormatContext.hpp" #include "av/InputFormatContext.hpp"
#include "cover/CoverArtGrabber.hpp"
namespace Transcode namespace Transcode
{ {
@@ -77,7 +78,7 @@ InputMediaFile::InputMediaFile(const boost::filesystem::path& p)
std::cerr << "Cannot find best stream for type " << type << std::endl; std::cerr << "Cannot find best stream for type " << type << std::endl;
} }
input.getPictures( _coverPictures ); _covers = CoverArt::Grabber::getFromInputFormatContext(input);
} }
std::vector<Stream> std::vector<Stream>
+4 -2
View File
@@ -7,6 +7,8 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time.hpp>
#include "cover/CoverArt.hpp"
#include "Stream.hpp" #include "Stream.hpp"
@@ -33,7 +35,7 @@ class InputMediaFile
boost::posix_time::time_duration getDuration(void) const {return _duration;} boost::posix_time::time_duration getDuration(void) const {return _duration;}
// Pictures // Pictures
const std::vector< std::vector<unsigned char> >& getCoverPictures(void) const { return _coverPictures; } const std::vector< CoverArt::CoverArt >& getCovers(void) const { return _covers; }
// Stream handling // Stream handling
std::vector<Stream> getStreams(Stream::Type type) const; std::vector<Stream> getStreams(Stream::Type type) const;
@@ -47,7 +49,7 @@ class InputMediaFile
std::vector<Stream> _streams; std::vector<Stream> _streams;
std::map<Stream::Type, Stream::Id> _bestStreams; std::map<Stream::Type, Stream::Id> _bestStreams;
std::vector< std::vector<unsigned char> > _coverPictures; std::vector< CoverArt::CoverArt > _covers;
}; };
+7 -6
View File
@@ -2,8 +2,6 @@
#include "AudioWidget.hpp" #include "AudioWidget.hpp"
#include "metadata/Extractor.hpp"
namespace UserInterface { namespace UserInterface {
AudioWidget::AudioWidget(SessionData& sessionData, Wt::WContainerWidget* parent) AudioWidget::AudioWidget(SessionData& sessionData, Wt::WContainerWidget* parent)
@@ -51,13 +49,16 @@ AudioWidget::playTrack(boost::filesystem::path p)
// Refresh cover // Refresh cover
{ {
const std::vector< std::vector<unsigned char> >& pictures = inputFile.getCoverPictures(); std::vector<CoverArt::CoverArt> covers = inputFile.getCovers();
if (!pictures.empty()) if (!covers.empty())
{ {
std::cout << "Cover found!" << std::endl; std::cout << "Cover found!" << std::endl;
// _imgResource->setMimeType(cover.mimeType); if (!covers.front().scale(256))
_imgResource->setData(pictures.front()); std::cerr << "Cannot resize!" << std::endl;
//_imgResource->setMimeType(covers.front().getMimeType());
_imgResource->setData(covers.front().getData());
} }
else { else {
std::cout << "No cover found!" << std::endl; std::cout << "No cover found!" << std::endl;