00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00032
00033 #ifdef HAVE_CONFIG_H
00034 #include "autoconfig.h"
00035 #endif
00036
00037 #include "metadata_handler.h"
00038 #include "string_converter.h"
00039 #include "tools.h"
00040 #include "config_manager.h"
00041
00042 #ifdef HAVE_EXIV2
00043 #include "metadata/exiv2_handler.h"
00044 #endif
00045
00046 #ifdef HAVE_TAGLIB
00047 #include "metadata/taglib_handler.h"
00048 #else
00049 #ifdef HAVE_ID3LIB // we only want ID3 if taglib was not found
00050 #include "metadata/id3_handler.h"
00051 #endif // HAVE_ID3LIB
00052 #endif // HAVE_TAGLIB
00053
00054 #ifdef HAVE_LIBMP4V2
00055 #include "metadata/libmp4v2_handler.h"
00056 #endif
00057
00058 #ifdef HAVE_FFMPEG
00059 #include "metadata/ffmpeg_handler.h"
00060 #endif
00061
00062 #ifdef HAVE_LIBEXTRACTOR
00063 #include "metadata/extractor_handler.h"
00064 #endif
00065
00066 #ifdef HAVE_LIBEXIF
00067 #include "metadata/libexif_handler.h"
00068 #endif
00069
00070 #ifdef HAVE_LIBDVDNAV
00071 #include "metadata/dvd_handler.h"
00072 #endif
00073
00074 using namespace zmm;
00075
00076 mt_key MT_KEYS[] = {
00077 { "M_TITLE", "dc:title" },
00078 { "M_ARTIST", "upnp:artist" },
00079 { "M_ALBUM", "upnp:album" },
00080 { "M_DATE", "dc:date" },
00081 { "M_GENRE", "upnp:genre" },
00082 { "M_DESCRIPTION", "dc:description" },
00083 { "M_LONGDESCRIPTION", "upnp:longDescription" },
00084 { "M_TRACKNUMBER", "upnp:originalTrackNumber"},
00085 { "M_ALBUMARTURI", "upnp:albumArtURI"},
00086 { "M_REGION", "upnp:region"},
00087 { "M_AUTHOR", "upnp:author"},
00088 { "M_DIRECTOR", "upnp:director"},
00089 { "M_PUBLISHER", "dc:publisher"},
00090 { "M_RATING", "upnp:rating"},
00091 { "M_ACTOR", "upnp:actor"},
00092 { "M_PRODUCER", "upnp:producer"},
00093 };
00094
00095 res_key RES_KEYS[] = {
00096 { "R_SIZE", "size" },
00097 { "R_DURATION", "duration" },
00098 { "R_BITRATE", "bitrate" },
00099 { "R_SAMPLEFREQUENCY", "sampleFrequency" },
00100 { "R_NRAUDIOCHANNELS", "nrAudioChannels" },
00101 { "R_RESOLUTION", "resolution" },
00102 { "R_COLORDEPTH", "colorDepth" },
00103 { "R_PROTOCOLINFO", "protocolInfo" }
00104 };
00105
00106
00107 MetadataHandler::MetadataHandler() : Object()
00108 {
00109 }
00110
00111 void MetadataHandler::setMetadata(Ref<CdsItem> item)
00112 {
00113 String location = item->getLocation();
00114 off_t filesize;
00115
00116 string_ok_ex(location);
00117 check_path_ex(location, false, false, &filesize);
00118
00119 String mimetype = item->getMimeType();
00120
00121 Ref<CdsResource> resource(new CdsResource(CH_DEFAULT));
00122 resource->addAttribute(getResAttrName(R_PROTOCOLINFO),
00123 renderProtocolInfo(mimetype));
00124 resource->addAttribute(getResAttrName(R_SIZE),
00125 String::from(filesize));
00126
00127 item->addResource(resource);
00128
00129 Ref<MetadataHandler> handler;
00130 Ref<Dictionary> mappings = ConfigManager::getInstance()->getDictionaryOption(CFG_IMPORT_MAPPINGS_MIMETYPE_TO_CONTENTTYPE_LIST);
00131
00132 String content_type = mappings->get(mimetype);
00133
00134 if ((content_type == CONTENT_TYPE_OGG) && (isTheora(item->getLocation())))
00135 item->setFlag(OBJECT_FLAG_OGG_THEORA);
00136
00137 do
00138 {
00139 #ifdef HAVE_TAGLIB
00140 if ((content_type == CONTENT_TYPE_MP3) ||
00141 ((content_type == CONTENT_TYPE_OGG) &&
00142 (!item->getFlag(OBJECT_FLAG_OGG_THEORA))) ||
00143 (content_type == CONTENT_TYPE_FLAC))
00144 {
00145 handler = Ref<MetadataHandler>(new TagHandler());
00146 break;
00147 }
00148 #else
00149 #ifdef HAVE_ID3LIB
00150 if (content_type == CONTENT_TYPE_MP3)
00151 {
00152 handler = Ref<MetadataHandler>(new Id3Handler());
00153 break;
00154 }
00155 #endif // HAVE_ID3LIB
00156 #endif // HAVE_TAGLIB
00157
00158
00159
00160 #ifdef HAVE_EXIV2
00161
00162
00163
00164
00165
00166
00167
00168 #endif
00169
00170 #ifdef HAVE_LIBEXIF
00171 if (content_type == CONTENT_TYPE_JPG)
00172 {
00173 handler = Ref<MetadataHandler>(new LibExifHandler());
00174 break;
00175 }
00176 #else
00177
00178 #ifndef HAVE_LIBEXTRACTOR
00179 if (content_type == CONTENT_TYPE_JPG)
00180 {
00181 set_jpeg_resolution_resource(item, 0);
00182 }
00183 #endif // LIBEXTRACTOR
00184
00185 #endif // HAVE_LIBEXIF
00186
00187 #if defined(HAVE_LIBMP4V2)
00188 #if !defined(HAVE_FFMPEG)
00189 if (content_type == CONTENT_TYPE_MP4)
00190 #else // FFMPEG available
00191 if ((content_type == CONTENT_TYPE_MP4) &&
00192 (!item->getMimeType().startsWith(_("video"))))
00193 #endif // !defined(HAVE_FFMPEG)
00194 {
00195 handler = Ref<MetadataHandler>(new LibMP4V2Handler());
00196 break;
00197 }
00198 #endif // defined(HAVE_LIBMP4V2)
00199
00200 #ifdef HAVE_FFMPEG
00201 if (content_type != CONTENT_TYPE_PLAYLIST &&
00202 ((content_type == CONTENT_TYPE_OGG &&
00203 item->getFlag(OBJECT_FLAG_OGG_THEORA)) ||
00204 item->getMimeType().startsWith(_("video")) ||
00205 item->getMimeType().startsWith(_("audio"))))
00206 {
00207 handler = Ref<MetadataHandler>(new FfmpegHandler());
00208 break;
00209 }
00210 #else
00211 if (content_type == CONTENT_TYPE_AVI)
00212 {
00213 String fourcc = getAVIFourCC(item->getLocation());
00214 if (string_ok(fourcc))
00215 {
00216 item->getResource(0)->addOption(_(RESOURCE_OPTION_FOURCC),
00217 fourcc);
00218 }
00219 }
00220
00221 #endif // HAVE_FFMPEG
00222
00223 #ifdef HAVE_LIBDVDNAV
00224 if (content_type == CONTENT_TYPE_DVD)
00225 {
00226 handler = Ref<MetadataHandler>(new DVDHandler());
00227 break;
00228 }
00229 #endif
00230
00231 #ifdef HAVE_LIBEXTRACTOR
00232 {
00233 handler = Ref<MetadataHandler>(new ExtractorHandler());
00234 break;
00235 }
00236 #endif // HAVE_LIBEXTRACTOR
00237
00238
00239 }
00240 while (false);
00241
00242 if (handler == nil)
00243 return;
00244 handler->fillMetadata(item);
00245 }
00246
00247 String MetadataHandler::getMetaFieldName(metadata_fields_t field)
00248 {
00249 return MT_KEYS[field].upnp;
00250 }
00251
00252 String MetadataHandler::getResAttrName(resource_attributes_t attr)
00253 {
00254 return RES_KEYS[attr].upnp;
00255 }
00256
00257 Ref<MetadataHandler> MetadataHandler::createHandler(int handlerType)
00258 {
00259 switch(handlerType)
00260 {
00261 #ifdef HAVE_LIBEXIF
00262 case CH_LIBEXIF:
00263 return Ref<MetadataHandler>(new LibExifHandler());
00264 #endif
00265 #ifdef HAVE_ID3LIB
00266 case CH_ID3:
00267 return Ref<MetadataHandler>(new Id3Handler());
00268 #elif HAVE_TAGLIB
00269 case CH_ID3:
00270 return Ref<MetadataHandler>(new TagHandler());
00271 #endif
00272 #ifdef HAVE_LIBMP4V2
00273 case CH_MP4:
00274 return Ref<MetadataHandler>(new LibMP4V2Handler());
00275 #endif
00276 #if defined(HAVE_FFMPEG) && defined(HAVE_FFMPEGTHUMBNAILER)
00277 case CH_FFTH:
00278 return Ref<MetadataHandler>(new FfmpegHandler());
00279 #endif
00280 default:
00281 throw _Exception(_("unknown content handler ID: ") + handlerType);
00282 }
00283 }
00284
00285 String MetadataHandler::getMimeType()
00286 {
00287 return _(MIMETYPE_DEFAULT);
00288 }