WIP. Scale cover art option now mandatory!
This commit is contained in:
@@ -4,7 +4,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "database/AudioTypes.hpp"
|
|
||||||
|
|
||||||
namespace CoverArt
|
namespace CoverArt
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user