svvitch
digital signage player
|
00001 #include <Poco/DateTime.h> 00002 #include <Poco/Timezone.h> 00003 #include <Poco/Mutex.h> 00004 #include <Poco/Thread.h> 00005 #include <Poco/Runnable.h> 00006 #include <Poco/Util/XMLConfiguration.h> 00007 #include <Poco/UnicodeConverter.h> 00008 00009 #include "MixContent.h" 00010 #include "ImageContent.h" 00011 #ifdef USE_FFMPEG 00012 #include "FFMovieContent.h" 00013 #endif 00014 #include "DSContent.h" 00015 #include "TextContent.h" 00016 #include "FlashContent.h" 00017 #include "Utils.h" 00018 00019 00020 MixContent::MixContent(Renderer& renderer, int splitType): Content(renderer, splitType), 00021 _playing(false) 00022 { 00023 initialize(); 00024 } 00025 00026 MixContent::‾MixContent() { 00027 initialize(); 00028 for (vector<ContentPtr>::const_iterator it = _contents.begin(); it != _contents.end(); it++) delete (*it); 00029 } 00030 00031 void MixContent::initialize() { 00032 close(); 00033 } 00034 00036 bool MixContent::open(const MediaItemPtr media, const int offset) { 00037 initialize(); 00038 00039 vector<string> blocks; // 0-0-1080-600|0-600-1080-720|0-1320-1080-600 00040 svvitch::split(Poco::trim(media->getProperty("blocks")), '|', blocks); 00041 00042 int i = 0; 00043 for (vector<MediaItemFile>::const_iterator it = media->files().begin(); it != media->files().end(); it++) { 00044 MediaItemFile mif = *it; 00045 double x = 0; 00046 double y = 0; 00047 double w = _w; 00048 double h = _h; 00049 if (blocks.size() > i) { 00050 vector<string> nums; // 0-0-1080-600|0-600-1080-720|0-1320-1080-600 00051 svvitch::split(blocks.at(i), '-', nums); 00052 if (nums.size() == 4) { 00053 Poco::NumberParser::tryParseFloat(Poco::trim(nums[0]), x); 00054 Poco::NumberParser::tryParseFloat(Poco::trim(nums[1]), y); 00055 Poco::NumberParser::tryParseFloat(Poco::trim(nums[2]), w); 00056 Poco::NumberParser::tryParseFloat(Poco::trim(nums[3]), h); 00057 } else { 00058 _log.warning(Poco::format("failed blocks setting: %s", media->getProperty("blocks"))); 00059 } 00060 } else { 00061 _log.warning(Poco::format("failed blocks setting: %d > %s", i, media->getProperty("blocks"))); 00062 } 00063 ContentPtr c = NULL; 00064 switch (mif.type()) { 00065 case MediaTypeImage: 00066 c = new ImageContent(_renderer, config().splitType); 00067 c->set("aspect-mode", "lefttop"); 00068 break; 00069 case MediaTypeMovie: 00070 for (vector<string>::iterator it = config().movieEngines.begin(); it < config().movieEngines.end(); it++) { 00071 string engine = Poco::toLower(*it); 00072 #ifdef USE_FFMPEG 00073 if (engine == "ffmpeg") { 00074 c = new FFMovieContent(_renderer, config().splitType); 00075 if (c->open(media, i)) break; 00076 } else if (engine == "directshow") { 00077 #else 00078 if (engine == "directshow") { 00079 #endif 00080 c = new DSContent(_renderer, config().splitType); 00081 if (c->open(media, i)) break; 00082 } else { 00083 _log.warning(Poco::format("failed not found movie engine: %s", engine)); 00084 } 00085 } 00086 break; 00087 case MediaTypeFlash: 00088 c = new FlashContent(_renderer, config().splitType, x, y, w, h); 00089 break; 00090 } 00091 if (c) { 00092 if (!c->opened().empty() || c->open(media, i)) { 00093 c->setPosition(x, y); 00094 c->setBounds(w, h); 00095 c->set("alpha", 1.0f); 00096 _contents.push_back(c); 00097 } else { 00098 SAFE_DELETE(c); 00099 } 00100 } 00101 i++; 00102 } 00103 00104 _duration = media->duration() * 60 / 1000; 00105 _current = 0; 00106 _mediaID = media->id(); 00107 return true; 00108 } 00109 00110 00114 void MixContent::play() { 00115 for (vector<ContentPtr>::const_iterator it = _contents.begin(); it != _contents.end(); it++) (*it)->play(); 00116 } 00117 00121 void MixContent::stop() { 00122 for (vector<ContentPtr>::const_iterator it = _contents.begin(); it != _contents.end(); it++) (*it)->stop(); 00123 } 00124 00125 bool MixContent::useFastStop() { 00126 bool useFastStop = false; 00127 for (vector<ContentPtr>::const_iterator it = _contents.begin(); it != _contents.end(); it++) useFastStop |= (*it)->useFastStop(); 00128 return useFastStop; 00129 } 00130 00134 const bool MixContent::playing() const { 00135 bool playing = false; 00136 for (vector<ContentPtr>::const_iterator it = _contents.begin(); it != _contents.end(); it++) { 00137 playing |= (*it)->playing(); 00138 } 00139 return playing; 00140 } 00141 00142 const bool MixContent::finished() { 00143 if (!_mediaID.empty()) { 00144 bool finished = true; 00145 for (vector<ContentPtr>::const_iterator it = _contents.begin(); it != _contents.end(); it++) { 00146 finished &= (*it)->finished(); 00147 } 00148 return finished; 00149 } 00150 return true; 00151 } 00152 00154 void MixContent::close() { 00155 for (vector<ContentPtr>::const_iterator it = _contents.begin(); it != _contents.end(); it++) (*it)->close(); 00156 _mediaID.clear(); 00157 } 00158 00159 void MixContent::process(const DWORD& frame) { 00160 string time, current, remain, fps, status; 00161 for (vector<ContentPtr>::const_iterator it = _contents.begin(); it != _contents.end(); it++) { 00162 ContentPtr c = *it; 00163 c->process(frame); 00164 if (!c->finished()) { 00165 string s = c->get("time"); if (!s.empty()) time = s; 00166 s = c->get("time_current"); if (!s.empty()) current = s; 00167 s = c->get("time_remain"); if (!s.empty()) remain = s; 00168 s = c->get("time_fps"); if (!s.empty()) fps = s; 00169 s = c->get("status"); if (!s.empty()) status = s; 00170 set("time", time); 00171 set("time_current", current); 00172 set("time_remain", remain); 00173 set("time_fps", fps); 00174 set("status", status); 00175 } 00176 } 00177 } 00178 00179 void MixContent::draw(const DWORD& frame) { 00180 for (vector<ContentPtr>::const_iterator it = _contents.begin(); it != _contents.end(); it++) (*it)->draw(frame); 00181 }