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 #if defined(SOPCAST)
00038
00039 #include "sopcast_content_handler.h"
00040 #include "online_service.h"
00041 #include "tools.h"
00042 #include "metadata_handler.h"
00043 #include "cds_objects.h"
00044 #include "config_manager.h"
00045
00046 using namespace zmm;
00047 using namespace mxml;
00048
00049 bool SopCastContentHandler::setServiceContent(zmm::Ref<mxml::Element> service)
00050 {
00051 String temp;
00052
00053 if (service->getName() != "channels")
00054 throw _Exception(_("Invalid XML for SopCast service received"));
00055
00056 channels = service;
00057
00058 group_count = channels->childCount();
00059 if (group_count < 1)
00060 return false;
00061
00062 current_group_node_index = 0;
00063 current_channel_index = 0;
00064 channel_count = 0;
00065 current_group = nil;
00066
00067 extension_mimetype_map =
00068 ConfigManager::getInstance()->getDictionaryOption(CFG_IMPORT_MAPPINGS_EXTENSION_TO_MIMETYPE_LIST);
00069
00070 return true;
00071 }
00072
00073 Ref<CdsObject> SopCastContentHandler::getNextObject()
00074 {
00075 #define DATE_BUF_LEN 12
00076 String temp;
00077 struct timespec ts;
00078
00079 while (current_group_node_index < group_count)
00080 {
00081 if (current_group == nil)
00082 {
00083 Ref<Node> n = channels->getChild(current_group_node_index);
00084 current_group_node_index++;
00085
00086 if (n == nil)
00087 continue;
00088
00089 if (n->getType() != mxml_node_element)
00090 continue;
00091
00092 current_group = RefCast(n, Element);
00093 channel_count = current_group->childCount();
00094
00095 if ((current_group->getName() != "group") ||
00096 (channel_count < 1))
00097 {
00098 current_group = nil;
00099 current_group_name = nil;
00100 continue;
00101 }
00102 else
00103 {
00104 current_group_name = current_group->getText();
00105 if (!string_ok(current_group_name))
00106 {
00107 current_group_name = current_group->getAttribute(_("en"));
00108 if (!string_ok(current_group_name))
00109 current_group_name = _("Unknown");
00110 }
00111 }
00112
00113 current_channel_index = 0;
00114 }
00115
00116 if (current_channel_index >= channel_count)
00117 {
00118 current_group = nil;
00119 continue;
00120 }
00121
00122 while (current_channel_index < channel_count)
00123 {
00124 Ref<Node> n = current_group->getChild(current_channel_index);
00125 current_channel_index++;
00126
00127 if ((n == nil) || (n->getType() != mxml_node_element))
00128 continue;
00129
00130 Ref<Element> channel = RefCast(n, Element);
00131
00132 if (channel->getName() != "channel")
00133 continue;
00134
00135 Ref<CdsItemExternalURL> item(new CdsItemExternalURL());
00136 Ref<CdsResource> resource(new CdsResource(CH_DEFAULT));
00137 item->addResource(resource);
00138
00139 item->setAuxData(_(ONLINE_SERVICE_AUX_ID),
00140 String::from(OS_SopCast));
00141
00142 item->setAuxData(_(SOPCAST_AUXDATA_GROUP), current_group_name);
00143
00144 temp = channel->getAttribute(_("id"));
00145 if (!string_ok(temp))
00146 {
00147 log_warning("Failed to retrieve SopCast channel ID\n");
00148 continue;
00149 }
00150
00151 temp = String(OnlineService::getStoragePrefix(OS_SopCast)) + temp;
00152 item->setServiceID(temp);
00153
00154 temp = channel->getChildText(_("stream_type"));
00155 if (!string_ok(temp))
00156 {
00157 log_warning("Failed to retrieve SopCast channel mimetype\n");
00158 continue;
00159 }
00160
00161
00162
00163 String mt;
00164
00165 if (!string_ok(mt))
00166 {
00167 if (temp == "wmv")
00168 mt = _("video/sopcast-x-ms-wmv");
00169 else if (temp == "mp3")
00170 mt = _("audio/sopcast-mpeg");
00171 else if (temp == "wma")
00172 mt = _("audio/sopcast-x-ms-wma");
00173 else
00174 {
00175 log_warning("Could not determine mimetype for SopCast channel (stream_type: %s)\n", temp.c_str());
00176 mt = _("application/sopcast-stream");
00177 }
00178 }
00179 resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO),
00180 renderProtocolInfo(mt, _(SOPCAST_PROTOCOL)));
00181 item->setMimeType(mt);
00182
00183 Ref<Element> tmp_el = channel->getChildByName(_("sop_address"));
00184 if (tmp_el == nil)
00185 {
00186 log_warning("Failed to retrieve SopCast channel URL\n");
00187 continue;
00188 }
00189
00190 temp = tmp_el->getChildText(_("item"));
00191 if (!string_ok(temp))
00192 {
00193 log_warning("Failed to retrieve SopCast channel URL\n");
00194 continue;
00195 }
00196 item->setURL(temp);
00197
00198 tmp_el = channel->getChildByName(_("name"));
00199 if (tmp_el == nil)
00200 {
00201 log_warning("Failed to retrieve SopCast channel name\n");
00202 continue;
00203 }
00204
00205 temp = tmp_el->getAttribute(_("en"));
00206 if (string_ok(temp))
00207 item->setTitle(temp);
00208 else
00209 item->setTitle(_("Unknown"));
00210
00211 tmp_el = channel->getChildByName(_("region"));
00212 if (tmp_el != nil)
00213 {
00214 temp = tmp_el->getAttribute(_("en"));
00215 if (string_ok(temp))
00216 item->setMetadata(MetadataHandler::getMetaFieldName(M_REGION), temp);
00217 }
00218
00219 temp = channel->getChildText(_("description"));
00220 if (string_ok(temp))
00221 item->setMetadata(MetadataHandler::getMetaFieldName(M_DESCRIPTION), temp);
00222
00223 temp = channel->getAttribute(_("language"));
00224 if (string_ok(temp))
00225 item->setAuxData(_(SOPCAST_AUXDATA_LANGUAGE), temp);
00226
00227 item->setClass(_(UPNP_DEFAULT_CLASS_VIDEO_BROADCAST));
00228
00229 getTimespecNow(&ts);
00230 item->setAuxData(_(ONLINE_SERVICE_LAST_UPDATE), String::from(ts.tv_sec));
00231 item->setFlag(OBJECT_FLAG_PROXY_URL);
00232 item->setFlag(OBJECT_FLAG_ONLINE_SERVICE);
00233
00234 try
00235 {
00236 item->validate();
00237 return RefCast(item, CdsObject);
00238 }
00239 catch (Exception ex)
00240 {
00241 log_warning("Failed to validate newly created SopCast item: %s\n",
00242 ex.getMessage().c_str());
00243 continue;
00244 }
00245 }
00246 }
00247
00248 return nil;
00249 }
00250
00251 #endif//SOPCAST