diff --git a/src/cds_resource_manager.cc b/src/cds_resource_manager.cc index abcc75f56..1ef01fb28 100644 --- a/src/cds_resource_manager.cc +++ b/src/cds_resource_manager.cc @@ -285,14 +285,15 @@ void CdsResourceManager::addResources(Ref item, Ref 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 res_attrs = item->getResource(i)->getAttributes(); - Ref res_params = item->getResource(i)->getParameters(); + Ref res = item->getResource(i); + Ref res_attrs = res->getAttributes(); + Ref res_params = res->getParameters(); String protocolInfo = res_attrs->get(MetadataHandler::getResAttrName(R_PROTOCOLINFO)); String mimeType = getMTFromProtocolInfo(protocolInfo); @@ -306,7 +307,7 @@ void CdsResourceManager::addResources(Ref item, Ref 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? @@ -357,52 +358,50 @@ void CdsResourceManager::addResources(Ref item, Ref 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 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 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 @@ -581,3 +580,15 @@ String CdsResourceManager::getFirstResource(Ref item) else return urlBase->urlBase; } + +String CdsResourceManager::getArtworkUrl(zmm::Ref item) { + // FIXME: This is temporary until we do artwork properly. + log_debug("Building Art url for %d\n", item->getID()); + + Ref urlBase = addResources_getUrlBase(item); + + if (urlBase->addResID) + return urlBase->urlBase + 1 + "/rct/aa"; + else + return urlBase->urlBase; +} \ No newline at end of file diff --git a/src/cds_resource_manager.h b/src/cds_resource_manager.h index e2f86cf16..315838fe9 100644 --- a/src/cds_resource_manager.h +++ b/src/cds_resource_manager.h @@ -60,7 +60,12 @@ class CdsResourceManager : public zmm::Object /// \param item Item for which the resources should be built. /// \return The URL static zmm::String getFirstResource(zmm::Ref 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 item); + protected: class UrlBase : public zmm::Object { @@ -68,7 +73,7 @@ class CdsResourceManager : public zmm::Object zmm::String urlBase; bool addResID; }; - + /// \brief Gets the baseUrl for a CdsItem. /// \param item Item for which the baseUrl should be built. /// diff --git a/src/file_request_handler.cc b/src/file_request_handler.cc index 917938171..3563eeb18 100644 --- a/src/file_request_handler.cc +++ b/src/file_request_handler.cc @@ -392,8 +392,7 @@ Ref FileRequestHandler::open(IN const char *filename, Ref 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) @@ -552,8 +551,10 @@ Ref 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)) diff --git a/src/upnp_xml.cc b/src/upnp_xml.cc index 8f95ac32b..6fb5dfc08 100644 --- a/src/upnp_xml.cc +++ b/src/upnp_xml.cc @@ -105,9 +105,7 @@ Ref UpnpXML_DIDLRenderObject(Ref 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) { @@ -156,13 +154,14 @@ Ref UpnpXML_DIDLRenderObject(Ref 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 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())); } @@ -172,6 +171,8 @@ Ref UpnpXML_DIDLRenderObject(Ref obj, bool renderActions, in Ref 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 dict(new Dictionary()); dict->put(_(URL_OBJECT_ID), aa_id); @@ -181,12 +182,48 @@ Ref UpnpXML_DIDLRenderObject(Ref 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 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 obj = storage->loadObject(id); + if (obj->getClass() != UPNP_DEFAULT_CLASS_MUSIC_TRACK) + continue; + + Ref 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; + } + } + } + } } } + } @@ -468,3 +505,9 @@ Ref UpnpXML_DIDLRenderCreator(String creator) { return out; } + +Ref UpnpXML_DIDLRenderAlbumArtURI(String uri) { + Ref out(new Element(_("upnp:albumArtURI"))); + out->setText(uri); + return out; +} diff --git a/src/upnp_xml.h b/src/upnp_xml.h index 3089672ab..621fac3ff 100644 --- a/src/upnp_xml.h +++ b/src/upnp_xml.h @@ -82,4 +82,6 @@ zmm::Ref UpnpXML_DIDLRenderResource(zmm::String URL, zmm::Ref UpnpXML_DIDLRenderCaptionInfo(zmm::String URL); zmm::Ref UpnpXML_DIDLRenderCreator(zmm::String creator); + +zmm::Ref UpnpXML_DIDLRenderAlbumArtURI(zmm::String uri); #endif // __UPNP_XML_H__