Skip to content

Commit

Permalink
Album art, use image from first track if folder art not found
Browse files Browse the repository at this point in the history
  • Loading branch information
whyman committed Jan 1, 2017
1 parent 76bbe0b commit fd1fb25
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 53 deletions.
89 changes: 50 additions & 39 deletions src/cds_resource_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -285,14 +285,15 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
#endif // EXTERNAL_TRANSCODING

int resCount = item->getResourceCount();
for (int i = 0; i < resCount; i++)
{
for (int i = 0; i < resCount; i++) {

/// \todo what if the resource has a different mimetype than the item??
/* String mimeType = item->getMimeType();
if (!string_ok(mimeType)) mimeType = DEFAULT_MIMETYPE; */

Ref<Dictionary> res_attrs = item->getResource(i)->getAttributes();
Ref<Dictionary> res_params = item->getResource(i)->getParameters();
Ref<CdsResource> res = item->getResource(i);
Ref<Dictionary> res_attrs = res->getAttributes();
Ref<Dictionary> res_params = res->getParameters();
String protocolInfo = res_attrs->get(MetadataHandler::getResAttrName(R_PROTOCOLINFO));
String mimeType = getMTFromProtocolInfo(protocolInfo);

Expand All @@ -306,7 +307,7 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)
String contentType = mappings->get(mimeType);
String url;

/// \todo who will sync mimetype that is part of the protocl info and
/// \todo who will sync mimetype that is part of the protocol info and
/// that is lying in the resources with the information that is in the
/// resource tags?

Expand Down Expand Up @@ -357,52 +358,50 @@ void CdsResourceManager::addResources(Ref<CdsItem> item, Ref<Element> element)

// ok this really sucks, I guess another rewrite of the resource manager
// is necessary
if ((i > 0) && (item->getResource(i)->getHandlerType() == CH_EXTURL) &&
((item->getResource(i)->getOption(_(RESOURCE_CONTENT_TYPE)) ==
THUMBNAIL) ||
(item->getResource(i)->getOption(_(RESOURCE_CONTENT_TYPE)) ==
ID3_ALBUM_ART)))
if ((i > 0) && (res->getHandlerType() == CH_EXTURL) &&
((res->getOption(_(RESOURCE_CONTENT_TYPE)) == THUMBNAIL) ||
(res->getOption(_(RESOURCE_CONTENT_TYPE)) == ID3_ALBUM_ART)))
{
url = item->getResource(i)->getOption(_(RESOURCE_OPTION_URL));
url = res->getOption(_(RESOURCE_OPTION_URL));
if (!string_ok(url))
throw _Exception(_("missing thumbnail URL!"));

isExtThumbnail = true;
}

/// \todo currently resource is misused for album art
#ifdef HAVE_ID3_ALBUMART
/// FIXME: currently resource is misused for album art

// only add upnp:AlbumArtURI if we have an AA, skip the resource
if ((i > 0) && ((item->getResource(i)->getHandlerType() == CH_ID3) ||
(item->getResource(i)->getHandlerType() == CH_MP4) ||
(item->getResource(i)->getHandlerType() == CH_FLAC) ||
(item->getResource(i)->getHandlerType() == CH_FANART) ||
(item->getResource(i)->getHandlerType() == CH_EXTURL)))
{
String rct;
if (item->getResource(i)->getHandlerType() == CH_EXTURL)
rct = item->getResource(i)->getOption(_(RESOURCE_CONTENT_TYPE));
else
rct = item->getResource(i)->getParameter(_(RESOURCE_CONTENT_TYPE));
if (rct == ID3_ALBUM_ART)
{
Ref<Element> aa(new Element(MetadataHandler::getMetaFieldName(M_ALBUMARTURI)));
aa->setText(url);
if (i > 0) {
int handlerType = res->getHandlerType();

if (handlerType == CH_ID3 || (handlerType == CH_MP4) ||
handlerType == CH_FLAC || handlerType == CH_FANART ||
handlerType == CH_EXTURL) {

String rct;
if (res->getHandlerType() == CH_EXTURL)
rct = res->getOption(_(RESOURCE_CONTENT_TYPE));
else
rct = res->getParameter(_(RESOURCE_CONTENT_TYPE));
if (rct == ID3_ALBUM_ART) {
Ref<Element> aa(new Element(MetadataHandler::getMetaFieldName(M_ALBUMARTURI)));
aa->setText(url);
#ifdef EXTEND_PROTOCOLINFO
if (config->getBoolOption(CFG_SERVER_EXTEND_PROTOCOLINFO))
{
/// \todo clean this up, make sure to check the mimetype and
/// provide the profile correctly
aa->setAttribute(_("xmlns:dlna"),
_("urn:schemas-dlna-org:metadata-1-0"));
aa->setAttribute(_("dlna:profileID"), _("JPEG_TN"));
}
if (config->getBoolOption(CFG_SERVER_EXTEND_PROTOCOLINFO)) {
/// \todo clean this up, make sure to check the mimetype and
/// provide the profile correctly
aa->setAttribute(_("xmlns:dlna"),
_("urn:schemas-dlna-org:metadata-1-0"));
aa->setAttribute(_("dlna:profileID"), _("JPEG_TN"));
}
#endif
element->appendElementChild(aa);
continue;
element->appendElementChild(aa);
continue;
}
}
}
#endif

if (!isExtThumbnail)
{
#ifdef EXTERNAL_TRANSCODING
Expand Down Expand Up @@ -581,3 +580,15 @@ String CdsResourceManager::getFirstResource(Ref<CdsItem> item)
else
return urlBase->urlBase;
}

String CdsResourceManager::getArtworkUrl(zmm::Ref<CdsItem> item) {
// FIXME: This is temporary until we do artwork properly.
log_debug("Building Art url for %d\n", item->getID());

Ref<UrlBase> urlBase = addResources_getUrlBase(item);

if (urlBase->addResID)
return urlBase->urlBase + 1 + "/rct/aa";
else
return urlBase->urlBase;
}
9 changes: 7 additions & 2 deletions src/cds_resource_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,20 @@ class CdsResourceManager : public zmm::Object
/// \param item Item for which the resources should be built.
/// \return The URL
static zmm::String getFirstResource(zmm::Ref<CdsItem> item);


/// \brief Gets the URL of the artwork.
/// \param item Item for which the resources should be built.
/// \return The URL
static zmm::String getArtworkUrl(zmm::Ref<CdsItem> item);

protected:
class UrlBase : public zmm::Object
{
public:
zmm::String urlBase;
bool addResID;
};

/// \brief Gets the baseUrl for a CdsItem.
/// \param item Item for which the baseUrl should be built.
///
Expand Down
7 changes: 4 additions & 3 deletions src/file_request_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,7 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,

Ref<Dictionary> dict(new Dictionary());
dict->decodeSimple(parameters);
log_debug("full url (filename): %s, parameters: %s\n",
filename, parameters.c_str());
log_debug("full url (filename): %s, parameters: %s\n", filename, parameters.c_str());

String objID = dict->get(_("object_id"));
if (objID == nil)
Expand Down Expand Up @@ -552,8 +551,10 @@ Ref<IOHandler> FileRequestHandler::open(IN const char *filename,
path.substring(slash_pos) + _("\"");
}
}
log_debug("fetching resource id %d\n", res_id);
*/

log_debug("fetching resource id %d\n", res_id);

#ifdef EXTERNAL_TRANSCODING
tr_profile = dict->get(_(URL_PARAM_TRANSCODE_PROFILE_NAME));
if (string_ok(tr_profile))
Expand Down
61 changes: 52 additions & 9 deletions src/upnp_xml.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,7 @@ Ref<Element> UpnpXML_DIDLRenderObject(Ref<CdsObject> obj, bool renderActions, in
(upnp_class == UPNP_DEFAULT_CLASS_MUSIC_TRACK)))
result->appendTextChild(key, el->getValue());
}

log_debug("ITEM HAS FOLLOWING METADATA: %s\n", item->getMetadata()->encode().c_str());


CdsResourceManager::addResources(item, result);

if (upnp_class == UPNP_DEFAULT_CLASS_MUSIC_TRACK) {
Expand Down Expand Up @@ -156,13 +154,14 @@ Ref<Element> UpnpXML_DIDLRenderObject(Ref<CdsObject> obj, bool renderActions, in
int len = elements->size();
String key;

log_debug("Album as %d metadata\n", len);
log_debug("Album has %d metadata(s)\n", len);

for (int i = 0; i < len; i++)
{
Ref<DictionaryElement> el = elements->get(i);
key = el->getKey();
log_debug("Container %s\n", key.c_str());
//log_debug("Container %s\n", key.c_str());

if (key == MetadataHandler::getMetaFieldName(M_ARTIST)) {
result->appendElementChild(UpnpXML_DIDLRenderCreator(el->getValue()));
}
Expand All @@ -172,6 +171,8 @@ Ref<Element> UpnpXML_DIDLRenderObject(Ref<CdsObject> obj, bool renderActions, in
Ref<Storage> storage = Storage::getInstance();
String aa_id = storage->findFolderImage(cont->getID(), String());
if (aa_id != nil) {
log_debug("Using folder image as artwork for container\n");

String url;
Ref<Dictionary> dict(new Dictionary());
dict->put(_(URL_OBJECT_ID), aa_id);
Expand All @@ -181,12 +182,48 @@ Ref<Element> UpnpXML_DIDLRenderObject(Ref<CdsObject> obj, bool renderActions, in
CONTENT_MEDIA_HANDLER + _(_URL_PARAM_SEPARATOR) +
dict->encodeSimple() + _(_URL_PARAM_SEPARATOR) +
_(URL_RESOURCE_ID) + _(_URL_PARAM_SEPARATOR) + "0";
log_debug("UpnpXML_DIDLRenderObject: url: %s\n", url.c_str());
Ref<Element> aa(new Element(MetadataHandler::getMetaFieldName(M_ALBUMARTURI)));
aa->setText(url);
result->appendElementChild(aa);

result->appendElementChild(UpnpXML_DIDLRenderAlbumArtURI(url));

} else if (upnp_class == UPNP_DEFAULT_CLASS_MUSIC_ALBUM) {
// try to find the first track and use its artwork
auto items = storage->getObjects(cont->getID(), true);
if (items != nullptr) {

bool artAdded = false;
for (const auto &id : *items) {
if (artAdded)
break;

Ref<CdsObject> obj = storage->loadObject(id);
if (obj->getClass() != UPNP_DEFAULT_CLASS_MUSIC_TRACK)
continue;

Ref<CdsItem> item = RefCast(obj, CdsItem);

auto resources = item->getResources();

for (int i = 1; i < resources->size(); i++) {
auto res = resources->get(i);
// only add upnp:AlbumArtURI if we have an AA, skip the resource
if ((res->getHandlerType() == CH_ID3) ||
(res->getHandlerType() == CH_MP4) ||
(res->getHandlerType() == CH_FLAC) ||
(res->getHandlerType() == CH_FANART) ||
(res->getHandlerType() == CH_EXTURL)) {

String url = CdsResourceManager::getArtworkUrl(item);
result->appendElementChild(UpnpXML_DIDLRenderAlbumArtURI(url));

artAdded = true;
break;
}
}
}
}
}
}


}

Expand Down Expand Up @@ -468,3 +505,9 @@ Ref<Element> UpnpXML_DIDLRenderCreator(String creator) {

return out;
}

Ref<Element> UpnpXML_DIDLRenderAlbumArtURI(String uri) {
Ref<Element> out(new Element(_("upnp:albumArtURI")));
out->setText(uri);
return out;
}
2 changes: 2 additions & 0 deletions src/upnp_xml.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,6 @@ zmm::Ref<mxml::Element> UpnpXML_DIDLRenderResource(zmm::String URL, zmm::Ref<Dic
zmm::Ref<mxml::Element> UpnpXML_DIDLRenderCaptionInfo(zmm::String URL);

zmm::Ref<mxml::Element> UpnpXML_DIDLRenderCreator(zmm::String creator);

zmm::Ref<mxml::Element> UpnpXML_DIDLRenderAlbumArtURI(zmm::String uri);
#endif // __UPNP_XML_H__

0 comments on commit fd1fb25

Please sign in to comment.